import { Boxes } from 'lucide-react';
import React from 'react';

import {
    store as divisionStore,
    update as divisionUpdate,
} from '@/actions/App/Domains/Shared/Http/Controllers/Admin/DivisionController';

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 { Textarea } from '@/components/ui/textarea';
import { useYupForm } from '@/hooks/use-yup-form';
import {
    DIVISION_PREFIX_PATTERN,
    DIVISION_PREFIX_TITLE,
} from '@/lib/field-constraints';
import { divisionSchema } from '@/lib/validation/division';
import type { AdminDivision } from '@/types/admin';

interface DivisionFormDialogProps {
    /** Null berarti dialog dipakai untuk membuat divisi baru. */
    division: AdminDivision | null;
    open: boolean;
    onOpenChange: (open: boolean) => void;
}

export function DivisionFormDialog({
    division,
    open,
    onOpenChange,
}: DivisionFormDialogProps) {
    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="sm:max-w-125 [&>button:last-child]:hidden">
                {open && (
                    <DivisionForm
                        key={division?.id ?? 'new'}
                        division={division}
                        onClose={() => onOpenChange(false)}
                    />
                )}
            </DialogContent>
        </Dialog>
    );
}

function DivisionForm({
    division,
    onClose,
}: {
    division: AdminDivision | null;
    onClose: () => void;
}) {
    const isEditing = division !== null;

    const { data, setData, processing, errors, validateField, submit } =
        useYupForm(divisionSchema, {
            name: division?.name ?? '',
            prefix: division?.prefix ?? '',
            description: division?.description ?? '',
        });

    const prefixLocked = isEditing && division.task_count > 0;

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

        const options = { preserveScroll: true, onSuccess: onClose };

        submit((form) => {
            if (isEditing) {
                form.put(
                    divisionUpdate({ division: division.slug }).url,
                    options,
                );

                return;
            }

            form.post(divisionStore().url, options);
        });
    };

    return (
        <>
            <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                    <Boxes className="h-5 w-5" />
                    {isEditing ? 'Edit Division' : 'New Division'}
                </DialogTitle>
                <DialogDescription>
                    {isEditing
                        ? 'Update the division identity.'
                        : 'Create a division. Its URL is derived from the name and stays fixed afterwards.'}
                </DialogDescription>
            </DialogHeader>

            <form onSubmit={handleSubmit} className="space-y-4 py-4" noValidate>
                <div className="space-y-2">
                    <Label htmlFor="division-name">Name</Label>
                    <Input
                        id="division-name"
                        value={data.name}
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
                            setData('name', e.target.value)
                        }
                        onBlur={() => validateField('name')}
                        placeholder="e.g. Software Development"
                        required
                    />
                    {errors.name && (
                        <p className="text-xs text-destructive">
                            {errors.name}
                        </p>
                    )}
                </div>

                <div className="space-y-2">
                    <Label htmlFor="division-prefix">Task Code Prefix</Label>
                    <Input
                        id="division-prefix"
                        value={data.prefix}
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
                            setData('prefix', e.target.value.toUpperCase())
                        }
                        onBlur={() => validateField('prefix')}
                        placeholder="e.g. SK"
                        className="uppercase"
                        maxLength={10}
                        pattern={DIVISION_PREFIX_PATTERN}
                        title={DIVISION_PREFIX_TITLE}
                        disabled={prefixLocked}
                        required
                    />
                    <p className="text-xs text-muted-foreground">
                        {prefixLocked ? (
                            <>
                                Locked because this division already has{' '}
                                {division.task_count} task
                                {division.task_count === 1 ? '' : 's'} using it.
                            </>
                        ) : (
                            <>
                                Becomes the prefix of every task code in this
                                division, e.g.{' '}
                                <span className="font-mono">
                                    {(data.prefix || 'SK').toUpperCase()}-000001
                                </span>
                                .
                            </>
                        )}
                    </p>
                    {errors.prefix && (
                        <p className="text-xs text-destructive">
                            {errors.prefix}
                        </p>
                    )}
                </div>

                <div className="space-y-2">
                    <Label htmlFor="division-description">
                        Description (optional)
                    </Label>
                    <Textarea
                        id="division-description"
                        value={data.description}
                        onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
                            setData('description', e.target.value)
                        }
                        onBlur={() => validateField('description')}
                        rows={3}
                        placeholder="What this division is responsible for"
                    />
                    {errors.description && (
                        <p className="text-xs text-destructive">
                            {errors.description}
                        </p>
                    )}
                </div>

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