<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
    Card,
    Typography,
    Button,
    List,
    Space,
    Spin,
    Input,
    message,
    Tag,
    Modal,
    Tabs,
    InputNumber,
} from 'ant-design-vue'
import { apiClient, isAxiosError, API } from '../router/api'
import { useUserStore } from '../stores/userStore'
import type { Organization } from '../types/organization'
import type { User } from '../types/user'
import type { InviteToken } from '../types/organization'
import type { Role } from '../types/organization'

const route = useRoute()
const router = useRouter()
const auth = useUserStore()

const organizationUuid = route.params.organizationUuid as string
const organization = ref<Organization | null>(null)
const members = ref<User[]>([])
const invites = ref<InviteToken[]>([])
const newInviteMaxUses = ref<number>(1)
const Roles = ref<Role[]>([])
const memberSearch = ref('')
const roleSearch = ref('')
const loading = ref(false)
const creatingRole = ref(false)
const deletingRoleUuid = ref<string | null>(null)
const roleModalVisible = ref(false)
const roleMembersModalVisible = ref(false)
const selectedRoleForMembers = ref<Role | null>(null)
const selectedRoleMembers = ref<User[]>([])
const createRoleForm = ref({
    name: '',
    description: '',
})
const inviteModalVisible = ref(false)
const newInviteUrl = ref('')
const editingDescription = ref(false)
const newDescription = ref('')

const filteredMembers = computed(() => {
    const query = memberSearch.value.trim().toLowerCase()
    if (!query) return members.value
    return members.value.filter((member) => {
        const fullName = `${member.first_name} ${member.last_name}`.toLowerCase()
        return fullName.includes(query)
    })
})

const filteredRoles = computed(() => {
    const query = roleSearch.value.trim().toLowerCase()
    if (!query) return Roles.value
    return Roles.value.filter((role) => {
        const name = role.name?.toLowerCase() || ''
        const description = role.description?.toLowerCase() || ''
        return name.includes(query) || description.includes(query)
    })
})

const memberEmptyMessage = computed(() => {
    if (members.value.length === 0) return 'No members in this organization yet.'
    if (memberSearch.value.trim()) return 'No members match your search.'
    return 'No members in this organization yet.'
})

const roleEmptyMessage = computed(() => {
    if (Roles.value.length === 0) return 'No Roles in this organization yet.'
    if (roleSearch.value.trim()) return 'No roles match your search.'
    return 'No Roles in this organization yet.'
})

const fetchOrganization = async () => {
    loading.value = true
    try {
        const response = await apiClient.get<Organization>(API.organization.byId(organizationUuid))
        organization.value = response.data
        newDescription.value = response.data.description
    } catch (error) {
        console.error('Failed to fetch organization:', error)
        message.error('Failed to load organization details')
    } finally {
        loading.value = false
    }
}

const fetchMembers = async () => {
    try {
        const response = await apiClient.get<User[]>(API.organization.members.list(organizationUuid))
        members.value = response.data
    } catch (error) {
        console.error('Failed to fetch members:', error)
    }
}

const fetchInvites = async () => {
    try {
        const response = await apiClient.get<InviteToken[]>(API.invites.list(organizationUuid))
        invites.value = response.data
    } catch (error) {
        console.error('Failed to fetch invites:', error)
    }
}

const fetchRoles = async () => {
    try {
        const response = await apiClient.get<Role[]>(API.roles.list(organizationUuid))
        Roles.value = response.data as unknown as Role[]
    } catch (error) {
        console.error('Failed to fetch Roles:', error)
    }
}

const resetRoleForm = () => {
    createRoleForm.value = { name: '', description: '' }
}

const hasDuplicateRoleName = (name: string) =>
    Roles.value.some((role) => role.name.trim().toLowerCase() === name.trim().toLowerCase())

const createRole = async () => {
    const name = createRoleForm.value.name.trim()
    const description = createRoleForm.value.description.trim()

    if (!name) {
        message.error('Role name is required')
        return
    }

    if (hasDuplicateRoleName(name)) {
        message.error('A role with this name already exists')
        return
    }

    creatingRole.value = true
    try {
        await apiClient.post(API.roles.list(organizationUuid), { name, description })
        message.success('Role created successfully')
        roleModalVisible.value = false
        resetRoleForm()
        await fetchRoles()
    } catch (error) {
        console.error('Failed to create role:', error)
        if (isAxiosError(error)) {
            message.error(error.response?.data?.error || 'Failed to create role')
        } else {
            message.error('Failed to create role')
        }
    } finally {
        creatingRole.value = false
    }
}

const deleteRole = async (role: Role) => {
    Modal.confirm({
        title: 'Delete role',
        content: `Are you sure you want to delete "${role.name}"?`,
        okText: 'Delete',
        okType: 'danger',
        cancelText: 'Cancel',
        onOk: async () => {
            deletingRoleUuid.value = role.uuid
            try {
                await apiClient.delete(API.roles.remove(organizationUuid, role.uuid))
                message.success('Role deleted successfully')
                await fetchRoles()
            } catch (error) {
                console.error('Failed to delete role:', error)
                if (isAxiosError(error)) {
                    message.error(error.response?.data?.error || 'Failed to delete role')
                } else {
                    message.error('Failed to delete role')
                }
            } finally {
                deletingRoleUuid.value = null
            }
        },
    })
}

const openRoleMembersModal = (role: Role) => {
    selectedRoleForMembers.value = role
    selectedRoleMembers.value = Array.isArray(role.members) ? role.members : []
    roleMembersModalVisible.value = true
}

const createInvite = async () => {
    try {
        const response = await apiClient.post<InviteToken>(
            API.invites.create(organizationUuid, newInviteMaxUses.value),
        )
        newInviteUrl.value = response.data.invite_url
        inviteModalVisible.value = true
        fetchInvites()
    } catch (error) {
        console.error('Failed to create invite:', error)
        message.error('Failed to create invite')
    }
}

const fallbackCopyText = (text: string): boolean => {
    const textarea = document.createElement('textarea')
    textarea.value = text
    textarea.setAttribute('readonly', 'true')
    textarea.style.position = 'fixed'
    textarea.style.opacity = '0'
    textarea.style.pointerEvents = 'none'
    document.body.appendChild(textarea)
    textarea.focus()
    textarea.select()

    const copied = document.execCommand('copy')
    document.body.removeChild(textarea)
    return copied
}

const copyToClipboard = async (text: string): Promise<boolean> => {
    const safeText = String(text || '').trim()
    if (!safeText) return false

    if (window.isSecureContext && window.navigator.clipboard?.writeText) {
        try {
            await window.navigator.clipboard.writeText(safeText)
            return true
        } catch {
            // Fall through to legacy copy for restricted browser contexts.
        }
    }

    return fallbackCopyText(safeText)
}

const copyInviteUrl = async () => {
    const copied = await copyToClipboard(newInviteUrl.value)
    if (copied) {
        message.success('Invite URL copied to clipboard')
        return
    }
    message.error('Could not copy invite URL. Please copy it manually.')
}

const copyUrl = async (url: string) => {
    const copied = await copyToClipboard(url)
    if (copied) {
        message.success('Copied to clipboard')
        return
    }
    message.error('Could not copy URL. Please copy it manually.')
}

const revokeInvite = async (inviteUuid: string) => {
    try {
        await apiClient.delete(API.invites.revoke(organizationUuid, inviteUuid))
        message.success('Invite revoked')
        fetchInvites()
    } catch (error) {
        console.error('Failed to revoke invite:', error)
        message.error('Failed to revoke invite')
    }
}

const removeMember = async (userUuid: string) => {
    try {
        await apiClient.post(API.organization.members.remove(organizationUuid, userUuid))
        message.success('Member removed')
        fetchMembers()
    } catch (error) {
        console.error('Failed to remove member:', error)
        if (isAxiosError(error)) {
            message.error(error.response?.data?.error || 'Failed to remove member')
        }
    }
}

const saveDescription = async () => {
    try {
        await apiClient.patch(API.organization.byId(organizationUuid), {
            description: newDescription.value,
        })
        message.success('Description updated')
        editingDescription.value = false
        fetchOrganization()
    } catch (error) {
        console.error('Failed to update description:', error)
        message.error('Failed to update description')
    }
}

onMounted(async () => {
    await fetchOrganization()
    await fetchMembers()
    await fetchInvites()
    await fetchRoles()

    const currentUserUuid = auth.user?.uuid
    const isOwner = organization.value?.owner?.uuid === currentUserUuid
    const myMembership = members.value.find((member) => member.uuid === currentUserUuid)
    const isEmployer = myMembership?.is_manager

    if (!isOwner && !isEmployer) {
        message.error('You do not have permission to manage this organization')
        router.replace(`/organization/${organizationUuid}`)
    }
})
</script>

<template>
    <div class="page">
        <Spin :spinning="loading" tip="Loading organization...">
            <Card v-if="organization" class="panel" :bordered="false">
                <div class="header">
                    <Typography.Title :level="2">Manage {{ organization.name }}</Typography.Title>
                    <Button type="default" @click="router.push(`/organization/${organizationUuid}`)">
                        Back to Organization
                    </Button>
                </div>

                <Tabs>
                    <Tabs.TabPane key="details" tab="Details">
                        <div class="section">
                            <Typography.Title :level="4" style="color: #1f2937 !important">
                                Description
                            </Typography.Title>
                            <div v-if="!editingDescription">
                                <Typography.Paragraph>
                                    {{ organization.description || 'No description provided' }}
                                </Typography.Paragraph>
                                <Button @click="editingDescription = true" size="small">
                                    Edit Description
                                </Button>
                            </div>
                            <div v-else>
                                <Input.TextArea
                                    v-model:value="newDescription"
                                    :rows="4"
                                    placeholder="Enter organization description"
                                />
                                <Space style="margin-top: 0.5rem">
                                    <Button type="primary" @click="saveDescription">Save</Button>
                                    <Button @click="editingDescription = false">Cancel</Button>
                                </Space>
                            </div>
                        </div>
                    </Tabs.TabPane>

                    <Tabs.TabPane key="members" tab="Members">
                        <div class="section">
                            <div class="section-header">
                                <Typography.Title :level="4" style="color: #1f2937 !important">
                                    Members ({{ filteredMembers.length }})
                                </Typography.Title>
                                <Input
                                    v-model:value="memberSearch"
                                    allow-clear
                                    class="search-input"
                                    placeholder="Search members by name"
                                    style="max-width: 280px"
                                />
                            </div>

                            <List
                                v-if="filteredMembers.length > 0"
                                :data-source="filteredMembers"
                                :bordered="false"
                            >
                                <template #renderItem="{ item }">
                                    <List.Item class="member-item">
                                        <List.Item.Meta
                                            :title="`${item.first_name} ${item.last_name}`"
                                            :description="item.email_address"
                                        />
                                        <Space>
                                            <Tag v-if="item.uuid === organization.owner.uuid" color="blue">
                                                Owner
                                            </Tag>
                                            <Tag v-else :color="item.is_manager ? 'purple' : 'default'">
                                                {{ item.is_manager ? 'Manager' : 'Member' }}
                                            </Tag>
                                            <Button
                                                v-if="item.uuid !== organization.owner.uuid"
                                                danger
                                                size="small"
                                                @click="removeMember(item.uuid)"
                                            >
                                                Remove
                                            </Button>
                                        </Space>
                                    </List.Item>
                                </template>
                            </List>
                            <Typography.Paragraph v-else type="secondary">
                                {{ memberEmptyMessage }}
                            </Typography.Paragraph>
                        </div>
                    </Tabs.TabPane>

                    <Tabs.TabPane key="invites" tab="Invites">
                        <div class="section">
                            <div class="section-header">
                                <Typography.Title :level="4" style="color: #1f2937 !important">
                                    Invite Tokens
                                </Typography.Title>
                                <Space>
                                    <InputNumber v-model:value="newInviteMaxUses" :min="1" />
                                    <Button type="primary" @click="createInvite">
                                        Create Invite
                                    </Button>
                                </Space>
                            </div>

                            <List
                                v-if="invites.length > 0"
                                :data-source="invites"
                                :bordered="false"
                            >
                                <template #renderItem="{ item }">
                                    <List.Item class="invite-item">
                                        <List.Item.Meta
                                            :title="`Created by ${item.created_by.first_name} ${item.created_by.last_name}`"
                                            :description="`Expires: ${new Date(item.expires_at).toLocaleDateString()}`"
                                        />
                                        <Space>
                                            <Tag :color="item.is_valid ? 'green' : 'red'">
                                                {{ item.is_valid ? 'Valid' : 'Expired' }}
                                            </Tag>
                                            <Tag class="white-tag">
                                                Uses: {{ item.uses || 0 }} /
                                                {{ item.max_uses || 1 }}
                                            </Tag>
                                            <Button size="small" @click="copyUrl(item.invite_url)">
                                                Copy URL
                                            </Button>
                                            <Button
                                                danger
                                                size="small"
                                                @click="revokeInvite(item.uuid)"
                                            >
                                                Revoke
                                            </Button>
                                        </Space>
                                    </List.Item>
                                </template>
                            </List>
                            <Typography.Paragraph v-else type="secondary">
                                No active invites. Create one to invite new members.
                            </Typography.Paragraph>
                        </div>
                    </Tabs.TabPane>

                    <Tabs.TabPane key="Roles" tab="Roles">
                        <div class="section">
                            <div class="section-header">
                                <Typography.Title :level="4" style="color: #1f2937 !important">
                                    Roles ({{ filteredRoles.length }})
                                </Typography.Title>
                                <Space>
                                    <Input
                                        v-model:value="roleSearch"
                                        allow-clear
                                        class="search-input"
                                        placeholder="Search roles by name or description"
                                        style="width: 300px"
                                    />
                                    <Button type="primary" @click="roleModalVisible = true">
                                        Create Role
                                    </Button>
                                </Space>
                            </div>

                            <List
                                v-if="filteredRoles.length > 0"
                                :data-source="filteredRoles"
                                :bordered="false"
                            >
                                <template #renderItem="{ item }">
                                    <List.Item class="Role-item">
                                        <List.Item.Meta
                                            :title="item.name"
                                            :description="item.description || 'No description'"
                                        />
                                        <Space>
                                            <Tag>{{ item.member_count }} members</Tag>
                                            <Button size="small" @click="openRoleMembersModal(item)">
                                                View Members
                                            </Button>
                                            <Button
                                                danger
                                                size="small"
                                                :loading="deletingRoleUuid === item.uuid"
                                                @click="deleteRole(item)"
                                            >
                                                Delete
                                            </Button>
                                        </Space>
                                    </List.Item>
                                </template>
                            </List>
                            <Typography.Paragraph v-else type="secondary">
                                {{ roleEmptyMessage }}
                            </Typography.Paragraph>
                        </div>
                    </Tabs.TabPane>
                </Tabs>
            </Card>
        </Spin>

        <Modal
            v-model:open="roleModalVisible"
            title="Create Role"
            ok-text="Create"
            cancel-text="Cancel"
            :ok-button-props="{ loading: creatingRole }"
            @ok="createRole"
            @cancel="resetRoleForm"
        >
            <div style="display: flex; flex-direction: column; gap: 0.75rem">
                <Input
                    v-model:value="createRoleForm.name"
                    placeholder="Role name"
                    :maxlength="100"
                    @pressEnter="createRole"
                />
                <Input.TextArea
                    v-model:value="createRoleForm.description"
                    placeholder="Role description"
                    :rows="4"
                    :maxlength="1000"
                />
            </div>
        </Modal>

        <Modal
            v-model:open="inviteModalVisible"
            title="Invite Created"
            @ok="inviteModalVisible = false"
        >
            <div>
                <Typography.Paragraph>
                    Share this URL with people you want to invite:
                </Typography.Paragraph>
                <Input
                    :value="newInviteUrl"
                    readonly
                    @click="copyInviteUrl"
                    style="cursor: pointer"
                />
                <Button type="primary" block style="margin-top: 1rem" @click="copyInviteUrl">
                    Copy to Clipboard
                </Button>
            </div>
        </Modal>

        <Modal
            v-model:open="roleMembersModalVisible"
            :title="`Members in ${selectedRoleForMembers?.name || 'Role'}`"
            :footer="null"
        >
            <List
                v-if="selectedRoleMembers.length > 0"
                :data-source="selectedRoleMembers"
                :bordered="false"
            >
                <template #renderItem="{ item }">
                    <List.Item>
                        <List.Item.Meta
                            :title="`${item.first_name} ${item.last_name}`"
                            :description="item.email_address"
                        />
                        <Tag :color="item.is_manager ? 'purple' : 'default'">
                            {{ item.is_manager ? 'Manager' : 'Member' }}
                        </Tag>
                    </List.Item>
                </template>
            </List>
            <Typography.Paragraph v-else type="secondary">
                No members assigned to this role yet.
            </Typography.Paragraph>
        </Modal>
    </div>
</template>

<style scoped>
.page {
    padding: 1rem;
}

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.section {
    margin: 2rem 0;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.white-tag {
    background-color: #ffffff !important;
    color: #000000 !important;
}

:deep(.ant-typography),
:deep(.ant-typography p),
:deep(.ant-typography span),
:deep(.ant-typography h4),
:deep(.ant-list-item),
:deep(.ant-list-item-meta-title),
:deep(.ant-list-item-meta-description),
:deep(.ant-tabs-tab),
:deep(.ant-input-number),
:deep(.ant-input-number-input) {
    color: #1f2937 !important;
}

:deep(.ant-typography-secondary) {
    color: #6b7280 !important;
}

:deep(.ant-input-number) {
    background: #ffffff;
    border-color: #d0d8e2;
}

:deep(.search-input) {
    background: #ffffff !important;
    border-color: #d0d8e2 !important;
    color: #1f2937 !important;
}

:deep(.search-input::placeholder) {
    color: #6b7280 !important;
}

:deep(.search-input::selection) {
    background: #dbeafe !important;
    color: #1f2937 !important;
}
</style>
