import { useForm } from '@inertiajs/react';
import { ShieldCheck, UserPlus, X } from 'lucide-react';
import React, { useEffect, useState } from 'react';
import { toast } from 'sonner';

import {
    getEligibleMembersForProject,
    addMember as projectAddMember,
} from '@/actions/App/Domains/Project/Http/Controllers/ProjectController';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import type {
    ProjectEligibleMember,
    ProjectMemberFormData,
} from '@/types/project';

interface AddMemberDialogProps {
    projectId: number;
    existingMemberIds: number[];
    open: boolean;
    onOpenChange: (open: boolean) => void;
}

export function AddMemberDialog({
    projectId,
    existingMemberIds,
    open,
    onOpenChange,
}: AddMemberDialogProps) {
    const [eligibleMembers, setEligibleMembers] = useState<
        ProjectEligibleMember[]
    >([]);
    const [isLoadingMembers, setIsLoadingMembers] = useState(false);

    const { data, setData, post, processing, reset } = useForm<{
        members: ProjectMemberFormData[];
    }>({
        members: [],
    });

    useEffect(() => {
        if (!open) {
            reset();
            setEligibleMembers([]);

            return;
        }

        const controller = new AbortController();

        const fetchMembers = async () => {
            setIsLoadingMembers(true);

            try {
                const response = await fetch(
                    getEligibleMembersForProject({ project: projectId }).url,
                    { signal: controller.signal },
                );

                if (!response.ok) {
                    throw new Error(
                        `Failed to fetch eligible members (${response.status})`,
                    );
                }

                const users =
                    (await response.json()) as ProjectEligibleMember[];
                setEligibleMembers(users);
            } catch (error) {
                if (error instanceof Error && error.name === 'AbortError') {
                    return;
                }

                console.error('Failed to fetch eligible members:', error);
                toast.error('Gagal memuat anggota yang tersedia');
            } finally {
                if (!controller.signal.aborted) {
                    setIsLoadingMembers(false);
                }
            }
        };

        fetchMembers();

        return () => controller.abort();
    }, [open, reset, projectId]);

    const addMember = (userId: string) => {
        const user = eligibleMembers.find((u) => u.id.toString() === userId);

        if (!user || data.members.some((m) => m.user_id === user.id)) {
            return;
        }

        setData('members', [
            ...data.members,
            {
                user_id: user.id,
                name: user.name,
                email: user.email,
                role: 'member',
                is_admin: user.is_admin,
                division_name: user.division_name,
            },
        ]);
    };

    const removeMember = (userId: number) => {
        setData(
            'members',
            data.members.filter((m) => m.user_id !== userId),
        );
    };

    const updateMemberRole = (userId: number, role: string) => {
        setData(
            'members',
            data.members.map((m) =>
                m.user_id === userId ? { ...m, role } : m,
            ),
        );
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();

        post(projectAddMember({ project: projectId }).url, {
            onSuccess: () => {
                onOpenChange(false);
                reset();
            },
        });
    };

    // Filter out users already in the project AND already in the selection list
    const availableOptions = eligibleMembers.filter(
        (u) =>
            !existingMemberIds.includes(u.id) &&
            !data.members.some((m) => m.user_id === u.id),
    );

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="overflow-hidden p-0 sm:max-w-xl [&>button:last-child]:hidden">
                <div className="p-6 pb-0">
                    <DialogHeader>
                        <DialogTitle className="flex items-center gap-2">
                            <UserPlus className="h-5 w-5 text-primary" />
                            Add Team Members
                        </DialogTitle>
                        <DialogDescription className="mt-2">
                            Select one or more users to join this project and
                            assign their roles.
                        </DialogDescription>
                    </DialogHeader>
                </div>

                <form onSubmit={handleSubmit} className="space-y-6">
                    <div className="space-y-6 px-6">
                        <div className="space-y-3">
                            <Label className="text-xs font-bold text-muted-foreground uppercase">
                                Select Member
                            </Label>
                            <Select onValueChange={addMember}>
                                <SelectTrigger className="h-11 w-full bg-muted/20">
                                    <SelectValue
                                        placeholder={
                                            isLoadingMembers
                                                ? 'Loading...'
                                                : 'Choose a member'
                                        }
                                    />
                                </SelectTrigger>

                                <SelectContent>
                                    {availableOptions.map((user) => (
                                        <SelectItem
                                            key={user.id}
                                            value={user.id.toString()}
                                        >
                                            <div className="flex flex-col py-0.5">
                                                <div className="flex items-center gap-2">
                                                    <span className="font-bold">
                                                        {user.name}
                                                    </span>
                                                    {user.is_admin && (
                                                        <Badge
                                                            variant="secondary"
                                                            className="h-4 px-1 text-[8px] font-bold uppercase"
                                                        >
                                                            Admin
                                                        </Badge>
                                                    )}
                                                </div>
                                                <span className="text-[10px] text-muted-foreground">
                                                    {user.division_name ||
                                                        'No Division'}
                                                </span>
                                            </div>
                                        </SelectItem>
                                    ))}
                                    {availableOptions.length === 0 &&
                                        !isLoadingMembers && (
                                            <div className="p-2 text-center text-xs text-muted-foreground">
                                                No more members available
                                            </div>
                                        )}
                                </SelectContent>
                            </Select>
                        </div>

                        <div className="overflow-hidden rounded-xl border bg-background">
                            <Table>
                                <TableHeader className="bg-muted/50">
                                    <TableRow>
                                        <TableHead className="text-[10px] font-bold tracking-wider uppercase">
                                            Member
                                        </TableHead>
                                        <TableHead className="w-27.5 text-[10px] font-bold tracking-wider uppercase">
                                            Role
                                        </TableHead>
                                        <TableHead className="w-10"></TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {data.members.map((member) => (
                                        <TableRow
                                            key={member.user_id}
                                            className="group"
                                        >
                                            <TableCell className="py-2">
                                                <div className="flex min-w-0 flex-col">
                                                    <div className="flex items-center gap-1.5 truncate">
                                                        <span className="truncate text-sm font-bold">
                                                            {member.name}
                                                        </span>
                                                        {member.is_admin && (
                                                            <ShieldCheck className="h-3 w-3 shrink-0 text-primary" />
                                                        )}
                                                    </div>
                                                    <div className="flex flex-col truncate text-[10px] text-muted-foreground">
                                                        <span className="truncate">
                                                            {member.email}
                                                        </span>
                                                        {member.division_name && (
                                                            <span className="truncate font-medium text-primary/70">
                                                                {
                                                                    member.division_name
                                                                }
                                                            </span>
                                                        )}
                                                    </div>
                                                </div>
                                            </TableCell>
                                            <TableCell className="py-2">
                                                <Select
                                                    value={member.role}
                                                    onValueChange={(val) =>
                                                        updateMemberRole(
                                                            member.user_id,
                                                            val,
                                                        )
                                                    }
                                                >
                                                    <SelectTrigger className="h-8 bg-muted/20 text-[11px] font-medium">
                                                        <SelectValue />
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        <SelectItem value="person-in-charge">
                                                            PIC
                                                        </SelectItem>
                                                        <SelectItem value="member">
                                                            Member
                                                        </SelectItem>
                                                        <SelectItem value="viewer">
                                                            Viewer
                                                        </SelectItem>
                                                    </SelectContent>
                                                </Select>
                                            </TableCell>
                                            <TableCell className="py-2 text-right">
                                                <Button
                                                    type="button"
                                                    variant="ghost"
                                                    size="icon"
                                                    className="h-7 w-7 rounded-full text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive"
                                                    onClick={() =>
                                                        removeMember(
                                                            member.user_id,
                                                        )
                                                    }
                                                    aria-label={`Hapus ${member.name} dari daftar anggota`}
                                                >
                                                    <X className="h-4 w-4" />
                                                </Button>
                                            </TableCell>
                                        </TableRow>
                                    ))}
                                    {data.members.length === 0 && (
                                        <TableRow>
                                            <TableCell
                                                colSpan={3}
                                                className="h-24 text-center text-sm text-muted-foreground"
                                            >
                                                No members added yet.
                                            </TableCell>
                                        </TableRow>
                                    )}
                                </TableBody>
                            </Table>
                        </div>
                    </div>

                    <DialogFooter className="flex flex-col gap-2 bg-neutral-50 p-6 sm:flex-row dark:bg-neutral-800/50">
                        <Button
                            type="button"
                            variant="ghost"
                            onClick={() => onOpenChange(false)}
                            className="h-11 flex-1 rounded-xl font-medium hover:bg-neutral-200 dark:hover:bg-neutral-700"
                        >
                            Cancel
                        </Button>
                        <Button
                            type="submit"
                            disabled={processing || data.members.length === 0}
                            className="h-11 flex-1 rounded-xl font-bold shadow-lg shadow-primary/20"
                        >
                            {processing ? 'Adding...' : 'Add to Project'}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
