import { useCallback, useEffect, useMemo, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faKey, faToggleOn, faUserPlus, faUserShield } from '@fortawesome/pro-duotone-svg-icons';
import { Avatar } from '@/components/base/avatar/avatar';
import { Badge } from '@/components/base/badges/badges';
import { Button } from '@/components/base/buttons/button';
import { Select } from '@/components/base/select/select';
import { Table, TableCard } from '@/components/application/table/table';
import { SlideoutMenu } from '@/components/application/slideout-menus/slideout-menu';
import { TopBar } from '@/components/layout/top-bar';
import {
    EmployeeCreateForm,
    emptyEmployeeCreateFormValues,
    type EmployeeCreateFormValues,
    type RoleOption,
} from '@/components/forms/employee-create-form';
import { apiClient } from '@/lib/api-client';
import { notify } from '@/lib/toast';
import { getInitials } from '@/lib/format';

// /settings/team — in-place employee management. Fetches real roles + SIP
// seats from the platform and uses the sidecar's /api/team/members
// endpoint to create workspace members directly with a temp password
// that the admin hands out (no email invitations — see
// feedback-no-invites in memory). Also lets admins change a member's
// role via updateWorkspaceMemberRole.

type MemberRole = {
    id: string;
    label: string;
};

type WorkspaceMember = {
    id: string;
    name: { firstName: string; lastName: string } | null;
    userEmail: string;
    avatarUrl: string | null;
    // Platform returns null (not []) for members with no role assigned —
    // optional-chain when reading.
    roles: MemberRole[] | null;
};

type CreatedMemberResponse = {
    id: string;
    userEmail: string;
    firstName: string;
    lastName: string;
    roleId: string;
};

// Combined query — workspace members + assignable roles. Bundled to
// save a round-trip and keep the table consistent across the join.
const TEAM_QUERY = `{
    workspaceMembers(first: 100) {
        edges {
            node {
                id
                name { firstName lastName }
                userEmail
                avatarUrl
                roles { id label }
            }
        }
    }
    getRoles {
        id
        label
        description
        canBeAssignedToUsers
    }
}`;

export const TeamSettingsPage = () => {
    const [members, setMembers] = useState<WorkspaceMember[]>([]);
    const [roles, setRoles] = useState<RoleOption[]>([]);
    const [loading, setLoading] = useState(true);
    const [createOpen, setCreateOpen] = useState(false);
    const [createValues, setCreateValues] = useState<EmployeeCreateFormValues>(
        emptyEmployeeCreateFormValues,
    );
    const [isCreating, setIsCreating] = useState(false);

    const fetchData = useCallback(async () => {
        try {
            const data = await apiClient.graphql<{
                workspaceMembers: { edges: { node: WorkspaceMember }[] };
                getRoles: {
                    id: string;
                    label: string;
                    description: string | null;
                    canBeAssignedToUsers: boolean;
                }[];
            }>(TEAM_QUERY, undefined, { silent: true });

            setMembers(data.workspaceMembers.edges.map((e) => e.node));
            const assignable = data.getRoles.filter((r) => r.canBeAssignedToUsers);
            setRoles(
                assignable.map((r) => ({
                    id: r.id,
                    label: r.label,
                    supportingText: r.description ?? undefined,
                })),
            );
        } catch {
            // silently fail
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        fetchData();
    }, [fetchData]);

    const [search, setSearch] = useState('');
    const [page, setPage] = useState(1);
    const PAGE_SIZE = 10;

    const filtered = useMemo(() => {
        if (!search.trim()) return members;
        const q = search.toLowerCase();
        return members.filter((m) => {
            const name = `${m.name?.firstName ?? ''} ${m.name?.lastName ?? ''}`.toLowerCase();
            return name.includes(q) || m.userEmail.toLowerCase().includes(q);
        });
    }, [members, search]);

    const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
    const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);

    const handleResetPassword = (member: WorkspaceMember) => {
        notify.info('Password Reset', `Password reset link would be sent to ${member.userEmail}`);
    };

    const handleChangeRole = async (memberId: string, newRoleId: string) => {
        try {
            await apiClient.graphql(
                `mutation UpdateRole($workspaceMemberId: UUID!, $roleId: UUID!) {
                    updateWorkspaceMemberRole(workspaceMemberId: $workspaceMemberId, roleId: $roleId) {
                        id
                    }
                }`,
                { workspaceMemberId: memberId, roleId: newRoleId },
            );
            const newRole = roles.find((r) => r.id === newRoleId);
            setMembers((prev) =>
                prev.map((m) =>
                    m.id === memberId
                        ? { ...m, roles: newRole ? [{ id: newRole.id, label: newRole.label }] : [] }
                        : m,
                ),
            );
            notify.success('Role updated', newRole ? `Role set to ${newRole.label}` : 'Role updated');
        } catch (err) {
            console.error('[team] role update failed', err);
        }
    };

    const handleCreateMember = async (close: () => void) => {
        const firstName = createValues.firstName.trim();
        const email = createValues.email.trim();
        if (!firstName) {
            notify.error('First name is required');
            return;
        }
        if (!email) {
            notify.error('Email is required');
            return;
        }
        if (!createValues.password) {
            notify.error('Temporary password is required');
            return;
        }
        if (!createValues.roleId) {
            notify.error('Pick a role');
            return;
        }

        setIsCreating(true);
        try {
            await apiClient.post<CreatedMemberResponse>('/api/team/members', {
                firstName,
                lastName: createValues.lastName.trim(),
                email,
                password: createValues.password,
                roleId: createValues.roleId,
            });
            notify.success(
                'Employee created',
                `${firstName} ${createValues.lastName.trim()}`.trim() || email,
            );
            setCreateValues(emptyEmployeeCreateFormValues);
            await fetchData();
            close();
        } catch (err) {
            console.error('[team] create failed', err);
        } finally {
            setIsCreating(false);
        }
    };

    return (
        <div className="flex flex-1 flex-col overflow-hidden">
            <TopBar title="Team" subtitle="Manage workspace members and their roles" />

            <div className="flex-1 overflow-y-auto p-6 space-y-6">
                <TableCard.Root size="sm">
                    <TableCard.Header
                        title="Employees"
                        badge={members.length}
                        description="Manage team members and their roles"
                        contentTrailing={
                            <div className="flex items-center gap-3">
                                <div className="w-48">
                                    <input
                                        placeholder="Search employees..."
                                        value={search}
                                        onChange={(e) => {
                                            setSearch(e.target.value);
                                            setPage(1);
                                        }}
                                        className="w-full rounded-lg border border-secondary bg-primary px-3 py-1.5 text-sm text-primary placeholder:text-placeholder outline-none focus:border-brand focus:ring-2 focus:ring-brand-100"
                                    />
                                </div>
                                <Button
                                    size="sm"
                                    color="primary"
                                    iconLeading={({ className }: { className?: string }) => (
                                        <FontAwesomeIcon icon={faUserPlus} className={className} />
                                    )}
                                    onClick={() => {
                                        setCreateValues(emptyEmployeeCreateFormValues);
                                        setCreateOpen(true);
                                    }}
                                >
                                    Add employee
                                </Button>
                            </div>
                        }
                    />
                    {loading ? (
                        <div className="flex items-center justify-center py-12">
                            <p className="text-sm text-tertiary">Loading employees...</p>
                        </div>
                    ) : (
                        <>
                            <Table>
                                <Table.Header>
                                    <Table.Head label="EMPLOYEE" isRowHeader />
                                    <Table.Head label="EMAIL" />
                                    <Table.Head label="ROLE" />
                                    <Table.Head label="STATUS" />
                                    <Table.Head label="ACTIONS" />
                                </Table.Header>
                                <Table.Body items={paged}>
                                    {(member) => {
                                        const firstName = member.name?.firstName ?? '';
                                        const lastName = member.name?.lastName ?? '';
                                        const fullName = `${firstName} ${lastName}`.trim() || 'Unnamed';
                                        const initials = getInitials(firstName || '?', lastName || '?');
                                        const memberRoles = member.roles ?? [];
                                        const currentRoleId = memberRoles[0]?.id ?? null;

                                        return (
                                            <Table.Row id={member.id}>
                                                <Table.Cell>
                                                    <div className="flex items-center gap-3">
                                                        <Avatar
                                                            size="sm"
                                                            initials={initials}
                                                            src={member.avatarUrl ?? undefined}
                                                        />
                                                        <span className="text-sm font-medium text-primary">{fullName}</span>
                                                    </div>
                                                </Table.Cell>
                                                <Table.Cell>
                                                    <span className="text-sm text-tertiary">{member.userEmail}</span>
                                                </Table.Cell>
                                                <Table.Cell>
                                                    {roles.length > 0 ? (
                                                        <div className="w-56">
                                                            <Select
                                                                placeholder="No role"
                                                                placeholderIcon={
                                                                    <FontAwesomeIcon
                                                                        icon={faUserShield}
                                                                        data-icon
                                                                        className="size-4"
                                                                    />
                                                                }
                                                                items={roles}
                                                                selectedKey={currentRoleId}
                                                                onSelectionChange={(key) =>
                                                                    handleChangeRole(member.id, key as string)
                                                                }
                                                            >
                                                                {(item) => (
                                                                    <Select.Item id={item.id} label={item.label} />
                                                                )}
                                                            </Select>
                                                        </div>
                                                    ) : memberRoles.length > 0 ? (
                                                        <Badge size="sm" color="gray">
                                                            {memberRoles[0].label}
                                                        </Badge>
                                                    ) : (
                                                        <span className="text-xs text-quaternary">No role</span>
                                                    )}
                                                </Table.Cell>
                                                <Table.Cell>
                                                    <Badge size="sm" color="success" type="pill-color">
                                                        <FontAwesomeIcon icon={faToggleOn} className="mr-1 size-3" />
                                                        Active
                                                    </Badge>
                                                </Table.Cell>
                                                <Table.Cell>
                                                    <Button
                                                        size="sm"
                                                        color="secondary"
                                                        iconLeading={({ className }: { className?: string }) => (
                                                            <FontAwesomeIcon icon={faKey} className={className} />
                                                        )}
                                                        onClick={() => handleResetPassword(member)}
                                                    >
                                                        Reset Password
                                                    </Button>
                                                </Table.Cell>
                                            </Table.Row>
                                        );
                                    }}
                                </Table.Body>
                            </Table>
                            {totalPages > 1 && (
                                <div className="flex items-center justify-between border-t border-secondary px-5 py-3">
                                    <span className="text-xs text-tertiary">
                                        {(page - 1) * PAGE_SIZE + 1}&ndash;{Math.min(page * PAGE_SIZE, filtered.length)} of{' '}
                                        {filtered.length}
                                    </span>
                                    <div className="flex items-center gap-1">
                                        <button
                                            onClick={() => setPage(Math.max(1, page - 1))}
                                            disabled={page === 1}
                                            className="px-2 py-1 text-xs font-medium text-secondary rounded-md hover:bg-primary_hover disabled:text-disabled disabled:cursor-not-allowed"
                                        >
                                            Previous
                                        </button>
                                        <button
                                            onClick={() => setPage(Math.min(totalPages, page + 1))}
                                            disabled={page === totalPages}
                                            className="px-2 py-1 text-xs font-medium text-secondary rounded-md hover:bg-primary_hover disabled:text-disabled disabled:cursor-not-allowed"
                                        >
                                            Next
                                        </button>
                                    </div>
                                </div>
                            )}
                        </>
                    )}
                </TableCard.Root>
            </div>

            <SlideoutMenu isOpen={createOpen} onOpenChange={setCreateOpen} isDismissable>
                {({ close }) => (
                    <>
                        <SlideoutMenu.Header onClose={close}>
                            <div className="flex items-center gap-3 pr-8">
                                <div className="flex size-10 items-center justify-center rounded-lg bg-brand-secondary">
                                    <FontAwesomeIcon icon={faUserPlus} className="size-5 text-fg-brand-primary" />
                                </div>
                                <div>
                                    <h2 className="text-lg font-semibold text-primary">Add employee</h2>
                                    <p className="text-sm text-tertiary">
                                        Create supervisors, CC agents and admins in place
                                    </p>
                                </div>
                            </div>
                        </SlideoutMenu.Header>

                        <SlideoutMenu.Content>
                            <EmployeeCreateForm
                                value={createValues}
                                onChange={setCreateValues}
                                roles={roles}
                            />
                            <p className="mt-4 text-xs text-tertiary">
                                The employee logs in with this email and the temporary password
                                you set. Share both with them directly — no email is sent.
                            </p>
                        </SlideoutMenu.Content>

                        <SlideoutMenu.Footer>
                            <div className="flex items-center justify-end gap-3">
                                <Button size="md" color="secondary" onClick={close}>
                                    Cancel
                                </Button>
                                <Button
                                    size="md"
                                    color="primary"
                                    isLoading={isCreating}
                                    showTextWhileLoading
                                    onClick={() => handleCreateMember(close)}
                                >
                                    {isCreating ? 'Creating…' : 'Create employee'}
                                </Button>
                            </div>
                        </SlideoutMenu.Footer>
                    </>
                )}
            </SlideoutMenu>
        </div>
    );
};
