import { useForm } from '@inertiajs/react';
import { useEffect, useMemo } from 'react';
import {
    AlertDialog,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { formatMoneyAmountOrDash } from '@/lib/dates';
import { salaryBeforeAfterIncrement } from '@/lib/permanent-salary-increment';
import { cn } from '@/lib/utils';

/**
 * @param {object} props
 * @param {boolean} props.open
 * @param {(open: boolean) => void} props.onOpenChange
 * @param {string} props.updateUrl
 * @param {object | null} props.record
 * @param {Record<string, string>} props.labels
 * @param {'en'|'fa'} props.locale
 */
export function PermanentSalaryEditDialog({
    open,
    onOpenChange,
    updateUrl,
    record,
    labels,
    locale,
}) {
    const form = useForm({
        allowance: '',
        salary_increment: '',
        advance_deduction: '',
    });

    useEffect(() => {
        if (!open || !record) {
            form.reset();
            form.clearErrors();
            return;
        }

        form.setData({
            allowance: record.allowance ?? '0',
            salary_increment: record.salary_increment ?? '0',
            advance_deduction: record.advance_deduction ?? record.advance_total ?? '0',
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps -- Inertia form identity is unstable
    }, [open, record]);

    const incrementSalaries = useMemo(() => {
        if (!record) {
            return null;
        }

        return salaryBeforeAfterIncrement({
            ...record,
            allowance: form.data.allowance,
            salary_increment: form.data.salary_increment,
        });
    }, [record, form.data.allowance, form.data.salary_increment]);

    const outstandingBalance = Number(record?.outstanding_advance_balance) || 0;

    const totalPreview = useMemo(() => {
        if (!record) {
            return '';
        }

        const base = Number(record.base_salary) || 0;
        const allowance = Number(form.data.allowance) || 0;
        const increment = Number(form.data.salary_increment) || 0;
        const deduction = record.deduct_absent_days
            ? Number(record.absent_deduction) || 0
            : 0;
        const punishment = Number(record.punishment_total) || 0;
        const advance = Number(form.data.advance_deduction) || 0;

        return String(Math.max(0, base + allowance + increment - deduction - punishment - advance));
    }, [record, form.data.allowance, form.data.salary_increment, form.data.advance_deduction]);

    function submit() {
        if (!updateUrl) {
            return;
        }

        const advance = Number(form.data.advance_deduction);
        if (Number.isFinite(advance) && advance > outstandingBalance + 0.0001) {
            form.setError(
                'advance_deduction',
                labels.advanceDeductionExceedsBalance?.replace(
                    '{balance}',
                    formatMoneyAmountOrDash(outstandingBalance, locale),
                ) ?? labels.advanceDeductionHint.replace(
                    '{balance}',
                    formatMoneyAmountOrDash(outstandingBalance, locale),
                ),
            );

            return;
        }

        form.put(updateUrl, {
            preserveScroll: true,
            onSuccess: () => onOpenChange(false),
        });
    }

    if (!record) {
        return null;
    }

    return (
        <AlertDialog open={open} onOpenChange={onOpenChange}>
            <AlertDialogContent className="max-w-md">
                <AlertDialogHeader>
                    <AlertDialogTitle>{labels.editTitle}</AlertDialogTitle>
                    <AlertDialogDescription>
                        {labels.editBody.replace('{name}', record.staff_name)}
                    </AlertDialogDescription>
                </AlertDialogHeader>

                <div className="space-y-4">
                    <div className="rounded-lg border bg-muted/30 px-4 py-3 text-sm">
                        <p>
                            <span className="text-muted-foreground">{labels.contractSalary}: </span>
                            <span className="font-medium tabular-nums">
                                {formatMoneyAmountOrDash(record.contract_salary, locale)}
                            </span>
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">{labels.baseSalary}: </span>
                            <span className="font-medium tabular-nums">
                                {formatMoneyAmountOrDash(record.base_salary, locale)}
                            </span>
                            {record.is_prorated ? (
                                <span className="text-muted-foreground ms-1 text-xs">
                                    {labels.proratedBaseHint
                                        .replace('{employed}', String(record.employed_days ?? 0))
                                        .replace('{total}', String(record.days_in_month ?? 0))}
                                </span>
                            ) : null}
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">{labels.absentDays}: </span>
                            <span className="font-medium tabular-nums">{record.absent_days ?? 0}</span>
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">{labels.absentDeduction}: </span>
                            <span className="font-medium tabular-nums text-destructive">
                                {formatMoneyAmountOrDash(record.absent_deduction, locale)}
                            </span>
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">
                                {labels.punishmentDeduction}:{' '}
                            </span>
                            <span className="font-medium tabular-nums text-destructive">
                                {Number(record.punishment_total) > 0
                                    ? `−${formatMoneyAmountOrDash(record.punishment_total, locale)}`
                                    : formatMoneyAmountOrDash(0, locale)}
                            </span>
                        </p>
                        <p className="mt-1">
                            <span className="text-muted-foreground">
                                {labels.outstandingAdvanceBalance}:{' '}
                            </span>
                            <span className="font-medium tabular-nums">
                                {formatMoneyAmountOrDash(outstandingBalance, locale)}
                            </span>
                        </p>
                        {incrementSalaries ? (
                            <>
                                <p className="mt-1">
                                    <span className="text-muted-foreground">{labels.oldSalary}: </span>
                                    <span className="font-medium tabular-nums">
                                        {formatMoneyAmountOrDash(incrementSalaries.before, locale)}
                                    </span>
                                </p>
                                <p className="mt-1">
                                    <span className="text-muted-foreground">{labels.newSalary}: </span>
                                    <span className="font-semibold tabular-nums text-emerald-700 dark:text-emerald-400">
                                        {formatMoneyAmountOrDash(incrementSalaries.after, locale)}
                                    </span>
                                </p>
                            </>
                        ) : null}
                        <p className="mt-1">
                            <span className="text-muted-foreground">{labels.totalSalary}: </span>
                            <span className="font-semibold tabular-nums">
                                {formatMoneyAmountOrDash(totalPreview, locale)}
                            </span>
                        </p>
                    </div>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="space-y-2">
                            <Label htmlFor="salary_allowance">{labels.allowance}</Label>
                            <Input
                                id="salary_allowance"
                                type="number"
                                min="0"
                                step="0.01"
                                value={form.data.allowance}
                                onChange={(e) => {
                                    form.setData('allowance', e.target.value);
                                    if (form.errors.allowance) {
                                        form.clearErrors('allowance');
                                    }
                                }}
                                aria-invalid={Boolean(form.errors.allowance)}
                                className={cn(form.errors.allowance && 'border-destructive')}
                            />
                            {form.errors.allowance ? (
                                <p className="text-destructive text-sm">{form.errors.allowance}</p>
                            ) : null}
                        </div>
                        <div className="space-y-2">
                            <Label htmlFor="salary_increment">{labels.salaryIncrement}</Label>
                            <Input
                                id="salary_increment"
                                type="number"
                                min="0"
                                step="0.01"
                                value={form.data.salary_increment}
                                onChange={(e) => {
                                    form.setData('salary_increment', e.target.value);
                                    if (form.errors.salary_increment) {
                                        form.clearErrors('salary_increment');
                                    }
                                }}
                                aria-invalid={Boolean(form.errors.salary_increment)}
                                className={cn(form.errors.salary_increment && 'border-destructive')}
                            />
                            {form.errors.salary_increment ? (
                                <p className="text-destructive text-sm">
                                    {form.errors.salary_increment}
                                </p>
                            ) : null}
                        </div>
                        <div className="space-y-2 sm:col-span-2">
                            <Label htmlFor="advance_deduction">{labels.advanceDeduction}</Label>
                            <Input
                                id="advance_deduction"
                                type="number"
                                min="0"
                                max={outstandingBalance > 0 ? outstandingBalance : undefined}
                                step="0.01"
                                value={form.data.advance_deduction}
                                onChange={(e) => {
                                    form.setData('advance_deduction', e.target.value);
                                    if (form.errors.advance_deduction) {
                                        form.clearErrors('advance_deduction');
                                    }
                                }}
                                aria-invalid={Boolean(form.errors.advance_deduction)}
                                className={cn(form.errors.advance_deduction && 'border-destructive')}
                            />
                            <p className="text-muted-foreground text-xs">
                                {labels.advanceDeductionHint.replace(
                                    '{balance}',
                                    formatMoneyAmountOrDash(outstandingBalance, locale),
                                )}
                            </p>
                            {form.errors.advance_deduction ? (
                                <p className="text-destructive text-sm">
                                    {form.errors.advance_deduction}
                                </p>
                            ) : null}
                        </div>
                    </div>
                </div>

                <AlertDialogFooter>
                    <AlertDialogCancel disabled={form.processing}>{labels.cancel}</AlertDialogCancel>
                    <Button type="button" disabled={form.processing} onClick={submit}>
                        {form.processing ? (
                            <>
                                <Spinner className="size-4" />
                                {labels.saving}
                            </>
                        ) : (
                            labels.save
                        )}
                    </Button>
                </AlertDialogFooter>
            </AlertDialogContent>
        </AlertDialog>
    );
}
