import { Head, Link } from '@inertiajs/react';
import { Folder, UserPlus, Users, X } from 'lucide-react';
import React, { useEffect, useState } from 'react';
import { toast } from 'sonner';

import {
    getEligibleMembersForCreate,
    store as projectStore,
} from '@/actions/App/Domains/Project/Http/Controllers/ProjectController';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { DateTimePicker } from '@/components/ui/datetime-picker';
import { Input } from '@/components/ui/input';
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 { Textarea } from '@/components/ui/textarea';
import { useYupForm } from '@/hooks/use-yup-form';
import { projectCreateSchema } from '@/lib/validation/project';
import { index as projectsIndex } from '@/routes/projects';
import type {
    ProjectEligibleMember,
    ProjectMemberFormData,
} from '@/types/project';

interface CreateProjectProps {
    isSupervisor: boolean;
    defaultDivisionId?: number | null;
}

/** Penanda field wajib. Mengikuti aturan validasi di ProjectController::store. */
function RequiredMark() {
    return (
        <span className="text-destructive" aria-hidden="true">
            *
        </span>
    );
}

export default function CreateProject({
    isSupervisor,
    defaultDivisionId = null,
}: CreateProjectProps) {
    const [eligibleMembers, setEligibleMembers] = useState<
        ProjectEligibleMember[]
    >([]);
    const [isLoadingMembers, setIsLoadingMembers] = useState(false);
    const [selectedSelectValue, setSelectedSelectValue] = useState<string>('');

    const { data, setData, processing, errors, validateField, submit } =
        useYupForm(projectCreateSchema, {
            projectName: '',
            description: '',
            deadline: '',
            status: 'DRAFT',
            division_id: defaultDivisionId,
            assign_to_admin: false,
            members: [] as ProjectMemberFormData[],
        });

    useEffect(() => {
        const controller = new AbortController();

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

            try {
                // Kandidat bergantung divisi tujuan; kirim agar server tidak
                // menebak divisi pembuat yang keliru saat ia multi-divisi.
                const url = new URL(
                    getEligibleMembersForCreate().url,
                    window.location.origin,
                );

                if (data.division_id) {
                    url.searchParams.set(
                        'division_id',
                        data.division_id.toString(),
                    );
                }

                const response = await fetch(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('Failed to load available members');
            } finally {
                if (!controller.signal.aborted) {
                    setIsLoadingMembers(false);
                }
            }
        };

        fetchMembers();

        return () => controller.abort();
    }, [data.division_id]);

    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,
                role_label: user.role_label,
            },
        ]);
        setSelectedSelectValue('');
    };

    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();

        submit((form) => form.post(projectStore().url));
    };

    // Filter out users already in the member list for the dropdown
    const availableOptions = eligibleMembers.filter(
        (u) => !data.members.some((m) => m.user_id === u.id),
    );

    return (
        <>
            <Head title="Create New Project" />

            {/* min-h-full + flex-col agar form bisa memanjang mengisi tinggi
                container; tanpa itu footer aksi berhenti di tengah layar saat
                isi form masih pendek. */}
            <div className="mx-auto flex min-h-full max-w-7xl flex-col overscroll-none px-4 py-6">
                <div className="mb-6">
                    <div className="flex items-center gap-3">
                        <div className="flex h-12 w-12 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm">
                            <Folder className="h-6 w-6" />
                        </div>
                        <div>
                            <h1 className="text-2xl font-extrabold tracking-tight md:text-3xl">
                                Create New Project
                            </h1>
                            <p className="text-muted-foreground">
                                Fill in the details below to start your new
                                collaboration.
                            </p>
                        </div>
                    </div>
                </div>

                <form
                    onSubmit={handleSubmit}
                    className="grid flex-1 grid-rows-[auto_1fr] gap-6 lg:grid-cols-5"
                    noValidate
                >
                    <div className="space-y-6 lg:col-span-3">
                        <div className="rounded-lg border bg-background p-5 shadow-sm md:p-6">
                            <div className="grid gap-4">
                                <div className="space-y-3">
                                    <Label
                                        htmlFor="projectName"
                                        className="text-base font-semibold"
                                    >
                                        Project Name <RequiredMark />
                                    </Label>
                                    <Input
                                        id="projectName"
                                        value={data.projectName}
                                        onChange={(e) =>
                                            setData(
                                                'projectName',
                                                e.target.value.toUpperCase(),
                                            )
                                        }
                                        onBlur={() =>
                                            validateField('projectName')
                                        }
                                        placeholder="e.g. DESIGN SYSTEM 2.0"
                                        className="h-11"
                                        maxLength={255}
                                        required
                                    />
                                    {errors.projectName && (
                                        <p className="text-xs text-destructive">
                                            {errors.projectName}
                                        </p>
                                    )}
                                </div>

                                <div className="space-y-3">
                                    <Label
                                        htmlFor="description"
                                        className="text-base font-semibold"
                                    >
                                        Description{' '}
                                        <span className="text-sm font-normal text-muted-foreground">
                                            (optional)
                                        </span>
                                    </Label>
                                    <Textarea
                                        id="description"
                                        value={data.description}
                                        onChange={(e) =>
                                            setData(
                                                'description',
                                                e.target.value,
                                            )
                                        }
                                        placeholder="Briefly describe what this project is about..."
                                        rows={5}
                                        className="resize-none"
                                    />
                                </div>

                                <div className="space-y-3">
                                    <Label
                                        htmlFor="deadline"
                                        className="text-base font-semibold"
                                    >
                                        Deadline <RequiredMark />
                                    </Label>
                                    <DateTimePicker
                                        value={data.deadline}
                                        onChange={(val) =>
                                            setData('deadline', val)
                                        }
                                        placeholder="Pick a deadline date & time"
                                    />
                                    {errors.deadline && (
                                        <p className="text-xs text-destructive">
                                            {errors.deadline}
                                        </p>
                                    )}
                                </div>

                                {isSupervisor && (
                                    <div className="flex items-start space-x-3 rounded-md border bg-muted/30 p-4">
                                        <Checkbox
                                            id="assign_to_admin"
                                            checked={data.assign_to_admin}
                                            onCheckedChange={(checked) =>
                                                setData(
                                                    'assign_to_admin',
                                                    checked as boolean,
                                                )
                                            }
                                            className="mt-1"
                                        />
                                        <div className="grid gap-1.5 leading-none">
                                            <Label
                                                htmlFor="assign_to_admin"
                                                className="text-sm leading-none font-bold peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
                                            >
                                                Set Admin as Project Owner
                                            </Label>
                                            <p className="text-xs text-muted-foreground">
                                                If checked, the administrator
                                                will be the primary owner of
                                                this project.
                                            </p>
                                        </div>
                                    </div>
                                )}
                            </div>
                        </div>
                    </div>

                    <div className="space-y-6 lg:col-span-2">
                        <div className="rounded-lg border bg-background p-5 shadow-sm">
                            <div className="mb-4 flex items-center gap-2">
                                <UserPlus className="h-5 w-5 text-primary" />
                                <h2 className="text-lg font-bold">
                                    Team Members{' '}
                                    <span className="text-sm font-normal text-muted-foreground">
                                        (optional)
                                    </span>
                                </h2>
                            </div>

                            <div className="space-y-3">
                                <div className="space-y-2">
                                    <Label
                                        htmlFor="select-member"
                                        className="text-sm font-semibold"
                                    >
                                        Select a member to add
                                    </Label>
                                    <p className="text-xs text-muted-foreground">
                                        Picking a name adds them to the list
                                        below, where you can set their role.
                                    </p>
                                    <Select
                                        value={selectedSelectValue}
                                        onValueChange={addMember}
                                    >
                                        <SelectTrigger
                                            id="select-member"
                                            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.role_label && (
                                                                <Badge
                                                                    variant="secondary"
                                                                    className="h-4 px-1 text-[8px] font-bold uppercase"
                                                                >
                                                                    {
                                                                        user.role_label
                                                                    }
                                                                </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-md 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.role_label && (
                                                                    <Badge
                                                                        variant="secondary"
                                                                        className="h-3 px-1 text-[8px] font-bold uppercase"
                                                                    >
                                                                        {
                                                                            member.role_label
                                                                        }
                                                                    </Badge>
                                                                )}
                                                            </div>
                                                            <div className="flex flex-col truncate text-[10px] text-muted-foreground">
                                                                {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,
                                                                )
                                                            }
                                                        >
                                                            <X className="h-4 w-4" />
                                                        </Button>
                                                    </TableCell>
                                                </TableRow>
                                            ))}
                                            {data.members.length === 0 && (
                                                <TableRow className="hover:bg-transparent">
                                                    <TableCell
                                                        colSpan={3}
                                                        className="h-28 text-center"
                                                    >
                                                        <Users className="mx-auto mb-2 h-6 w-6 text-muted-foreground/60" />
                                                        <p className="text-sm font-medium text-foreground">
                                                            No members added yet
                                                        </p>
                                                        <p className="mt-0.5 text-xs text-muted-foreground">
                                                            You can invite them
                                                            later from the
                                                            project page.
                                                        </p>
                                                    </TableCell>
                                                </TableRow>
                                            )}
                                        </TableBody>
                                    </Table>
                                </div>
                            </div>
                        </div>
                    </div>

                    {/* Aksi form membentang di bawah kedua kolom agar tetap
                        berada di ujung alur pengisian, bukan terpisah di
                        salah satu kolom. Sticky di semua ukuran layar: form
                        pendek menyisakan ruang kosong di bawah, dan daftar
                        anggota yang panjang bisa mendorong tombol ke luar
                        layar — keduanya teratasi dengan menempel ke dasar
                        viewport. */}
                    <div className="sticky bottom-0 z-10 -mx-4 mt-auto border-t bg-background/95 px-4 py-3 backdrop-blur supports-[backdrop-filter]:bg-background/80 lg:col-span-5">
                        <div className="flex flex-col-reverse gap-3 sm:flex-row sm:items-center sm:justify-end">
                            <p className="hidden text-xs text-muted-foreground sm:mr-auto sm:block">
                                <RequiredMark /> Required fields
                            </p>
                            <Button
                                type="button"
                                variant="outline"
                                size="lg"
                                asChild
                                className="sm:w-auto"
                            >
                                <Link href={projectsIndex().url}>Cancel</Link>
                            </Button>
                            <Button
                                type="submit"
                                size="lg"
                                disabled={processing}
                                className="font-bold sm:w-auto"
                            >
                                {processing ? 'Creating...' : 'Create Project'}
                            </Button>
                        </div>
                    </div>
                </form>
            </div>
        </>
    );
}

CreateProject.layout = {
    breadcrumbs: [
        {
            title: 'Projects',
            href: projectsIndex().url,
        },
        {
            title: 'Create',
        },
    ],
};
