import { useForm } from '@inertiajs/react';
import { Network, Plus, Trash2 } from 'lucide-react';
import React from 'react';

import { syncMemberships } from '@/actions/App/Domains/Shared/Http/Controllers/Admin/UserController';

import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import type { AdminUser, DivisionOption } from '@/types/admin';

/** Satu baris form; division_id 0 berarti belum dipilih. */
interface MembershipDraft {
    division_id: number;
    role_type: string;
    role_label: string;
}

interface UserMembershipsDialogProps {
    user: AdminUser | null;
    divisions: DivisionOption[];
    divisionRoleOptions: string[];
    open: boolean;
    onOpenChange: (open: boolean) => void;
}

export function UserMembershipsDialog({
    user,
    divisions,
    divisionRoleOptions,
    open,
    onOpenChange,
}: UserMembershipsDialogProps) {
    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="flex max-h-[calc(100dvh-4rem)] flex-col sm:max-w-150 [&>button:last-child]:hidden">
                {user && (
                    <UserMembershipsForm
                        key={user.id}
                        user={user}
                        divisions={divisions}
                        divisionRoleOptions={divisionRoleOptions}
                        onClose={() => onOpenChange(false)}
                    />
                )}
            </DialogContent>
        </Dialog>
    );
}

function UserMembershipsForm({
    user,
    divisions,
    divisionRoleOptions,
    onClose,
}: {
    user: AdminUser;
    divisions: DivisionOption[];
    divisionRoleOptions: string[];
    onClose: () => void;
}) {
    const { data, setData, put, processing, errors } = useForm<{
        memberships: MembershipDraft[];
    }>({
        memberships: user.memberships.map((membership) => ({
            division_id: membership.division_id,
            role_type: membership.role_type,
            role_label: membership.role_label ?? '',
        })),
    });

    // Error validasi bersarang datang dengan key seperti
    // "memberships.0.division_id", yang tidak tercakup tipe errors bawaan.
    const nestedErrors = errors as unknown as Record<string, string>;

    const takenDivisionIds = new Set(
        data.memberships.map((membership) => membership.division_id),
    );

    const updateRow = (index: number, patch: Partial<MembershipDraft>) => {
        setData(
            'memberships',
            data.memberships.map((membership, position) =>
                position === index ? { ...membership, ...patch } : membership,
            ),
        );
    };

    const addRow = () => {
        setData('memberships', [
            ...data.memberships,
            {
                division_id: 0,
                role_type: divisionRoleOptions[0] ?? 'member',
                role_label: '',
            },
        ]);
    };

    const removeRow = (index: number) => {
        setData(
            'memberships',
            data.memberships.filter((_, position) => position !== index),
        );
    };

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

        put(syncMemberships({ user: user.id }).url, {
            preserveScroll: true,
            onSuccess: onClose,
        });
    };

    return (
        <>
            <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                    <Network className="h-5 w-5" />
                    Division Memberships
                </DialogTitle>
                <DialogDescription>
                    Map{' '}
                    <span className="font-medium text-foreground">
                        {user.name}
                    </span>{' '}
                    to divisions. Removing a row revokes that membership.
                </DialogDescription>
            </DialogHeader>

            <form
                onSubmit={handleSubmit}
                className="flex min-h-0 flex-1 flex-col"
            >
                <div className="min-h-0 flex-1 space-y-3 overflow-y-auto py-4">
                    {/* Sama seperti dialog dari sisi divisi: penolakan K9
                        menempel pada atribut induk, jadi harus dirender di luar
                        daftar barisnya. */}
                    {nestedErrors.memberships && (
                        <p className="rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive">
                            {nestedErrors.memberships}
                        </p>
                    )}

                    {data.memberships.length === 0 && (
                        <p className="rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground">
                            This user has no division yet.
                        </p>
                    )}

                    {data.memberships.map((membership, index) => (
                        <div
                            key={index}
                            className="grid gap-3 rounded-lg border bg-muted/30 p-3 sm:grid-cols-[minmax(0,1fr)_9rem_minmax(0,1fr)_auto]"
                        >
                            <div className="space-y-1.5">
                                <Label
                                    className="text-xs text-muted-foreground"
                                    htmlFor={`membership-division-${index}`}
                                >
                                    Division
                                </Label>
                                <Select
                                    value={
                                        membership.division_id === 0
                                            ? ''
                                            : String(membership.division_id)
                                    }
                                    onValueChange={(value) =>
                                        updateRow(index, {
                                            division_id: Number(value),
                                        })
                                    }
                                >
                                    <SelectTrigger
                                        id={`membership-division-${index}`}
                                        className="w-full"
                                    >
                                        <SelectValue placeholder="Select division" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {divisions.map((division) => (
                                            <SelectItem
                                                key={division.id}
                                                value={String(division.id)}
                                                disabled={
                                                    division.id !==
                                                        membership.division_id &&
                                                    takenDivisionIds.has(
                                                        division.id,
                                                    )
                                                }
                                            >
                                                {division.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                {nestedErrors[
                                    `memberships.${index}.division_id`
                                ] && (
                                    <p className="text-xs text-destructive">
                                        {
                                            nestedErrors[
                                                `memberships.${index}.division_id`
                                            ]
                                        }
                                    </p>
                                )}
                            </div>

                            <div className="space-y-1.5">
                                <Label
                                    className="text-xs text-muted-foreground"
                                    htmlFor={`membership-role-${index}`}
                                >
                                    Role
                                </Label>
                                <Select
                                    value={membership.role_type}
                                    onValueChange={(value) =>
                                        updateRow(index, { role_type: value })
                                    }
                                >
                                    <SelectTrigger
                                        id={`membership-role-${index}`}
                                        className="w-full capitalize"
                                    >
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {divisionRoleOptions.map((role) => (
                                            <SelectItem
                                                key={role}
                                                value={role}
                                                className="capitalize"
                                            >
                                                {role}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                {nestedErrors[
                                    `memberships.${index}.role_type`
                                ] && (
                                    <p className="text-xs text-destructive">
                                        {
                                            nestedErrors[
                                                `memberships.${index}.role_type`
                                            ]
                                        }
                                    </p>
                                )}
                            </div>

                            <div className="space-y-1.5">
                                <Label
                                    className="text-xs text-muted-foreground"
                                    htmlFor={`membership-label-${index}`}
                                >
                                    Job Title (optional)
                                </Label>
                                <Input
                                    id={`membership-label-${index}`}
                                    value={membership.role_label}
                                    onChange={(
                                        e: React.ChangeEvent<HTMLInputElement>,
                                    ) =>
                                        updateRow(index, {
                                            role_label: e.target.value,
                                        })
                                    }
                                    placeholder="e.g. Kepala Cabang Jakarta"
                                />
                                {nestedErrors[
                                    `memberships.${index}.role_label`
                                ] && (
                                    <p className="text-xs text-destructive">
                                        {
                                            nestedErrors[
                                                `memberships.${index}.role_label`
                                            ]
                                        }
                                    </p>
                                )}
                            </div>

                            <div className="flex items-end">
                                <Button
                                    type="button"
                                    variant="ghost"
                                    size="icon"
                                    aria-label="Remove membership"
                                    onClick={() => removeRow(index)}
                                >
                                    <Trash2 className="h-4 w-4 text-destructive" />
                                </Button>
                            </div>
                        </div>
                    ))}

                    <Button
                        type="button"
                        variant="outline"
                        onClick={addRow}
                        disabled={data.memberships.length >= divisions.length}
                    >
                        <Plus className="mr-1 h-4 w-4" />
                        Add Division
                    </Button>
                </div>

                <DialogFooter className="border-t pt-4">
                    <Button type="button" variant="outline" onClick={onClose}>
                        Cancel
                    </Button>
                    <Button type="submit" disabled={processing}>
                        {processing ? 'Saving...' : 'Save Memberships'}
                    </Button>
                </DialogFooter>
            </form>
        </>
    );
}
