import { Form, Head, router, useForm } from '@inertiajs/react';
import { Plus, Trash2 } from 'lucide-react';
import { useState } from 'react';

import HeadingSmall from '@/components/heading-small';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import AppLayout from '@/layouts/app-layout';
import { destroy, index, store, update } from '@/routes/admin/supplier-web-form-fields';

const FIELD_TYPES = ['text', 'email', 'tel', 'date', 'select', 'checkbox', 'textarea'] as const;
type FieldType = (typeof FIELD_TYPES)[number];

const WEB_FORM_TYPES = [
    { value: 'enrollment', label: 'Enrollment' },
    { value: 'credit_check', label: 'Credit Check' },
] as const;

type WebFormTypeValue = (typeof WEB_FORM_TYPES)[number]['value'];

type Option = { value: string; label: string };

type SupplierOption = { id: number; name: string; slug: string };

type SupplierWebFormField = {
    id: number;
    supplier_id: number;
    form_type: WebFormTypeValue | null;
    name: string;
    label: string;
    type: FieldType;
    options: Option[] | null;
    required: boolean;
    placeholder: string | null;
    validation_pattern: string | null;
    validation_message: string | null;
    help_text: string | null;
};

type Props = {
    suppliers: SupplierOption[];
    selectedSupplierId: number | null;
    fields: SupplierWebFormField[];
};

type FieldFormData = {
    form_type: WebFormTypeValue | '';
    name: string;
    label: string;
    type: FieldType | '';
    options: Option[];
    required: string;
    placeholder: string;
    validation_pattern: string;
    validation_message: string;
    help_text: string;
};

const emptyForm: FieldFormData = {
    form_type: '',
    name: '',
    label: '',
    type: '',
    options: [],
    required: '1',
    placeholder: '',
    validation_pattern: '',
    validation_message: '',
    help_text: '',
};

function fieldToForm(f: SupplierWebFormField): FieldFormData {
    return {
        form_type: f.form_type ?? '',
        name: f.name,
        label: f.label,
        type: f.type,
        options: f.options ?? [],
        required: f.required ? '1' : '0',
        placeholder: f.placeholder ?? '',
        validation_pattern: f.validation_pattern ?? '',
        validation_message: f.validation_message ?? '',
        help_text: f.help_text ?? '',
    };
}

function FieldError({ message }: { message?: string }) {
    if (!message) return null;
    return <div className="text-xs text-red-600">{message}</div>;
}

function OptionsEditor({
    options,
    onChange,
}: {
    options: Option[];
    onChange: (opts: Option[]) => void;
}) {
    function updateOption(idx: number, key: 'value' | 'label', val: string) {
        const updated = options.map((o, i) => (i === idx ? { ...o, [key]: val } : o));
        onChange(updated);
    }

    function addOption() {
        onChange([...options, { value: '', label: '' }]);
    }

    function removeOption(idx: number) {
        onChange(options.filter((_, i) => i !== idx));
    }

    return (
        <div className="space-y-2">
            {options.map((opt, idx) => (
                <div key={idx} className="flex items-center gap-2">
                    <input
                        value={opt.value}
                        onChange={(e) => updateOption(idx, 'value', e.target.value)}
                        placeholder="value"
                        className="w-32 rounded-md border border-zinc-200 bg-white px-2 py-1.5 text-xs dark:border-zinc-800 dark:bg-zinc-950"
                    />
                    <input
                        value={opt.label}
                        onChange={(e) => updateOption(idx, 'label', e.target.value)}
                        placeholder="Label"
                        className="flex-1 rounded-md border border-zinc-200 bg-white px-2 py-1.5 text-xs dark:border-zinc-800 dark:bg-zinc-950"
                    />
                    <button
                        type="button"
                        onClick={() => removeOption(idx)}
                        className="text-red-600 hover:text-red-800 dark:text-red-400"
                    >
                        <Trash2 className="size-3.5" />
                    </button>
                </div>
            ))}
            <button
                type="button"
                onClick={addOption}
                className="flex items-center gap-1 text-xs text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
            >
                <Plus className="size-3.5" />
                Add option
            </button>
        </div>
    );
}

function FieldModal({
    open,
    onOpenChange,
    supplierId,
    field,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    supplierId: number;
    field: SupplierWebFormField | null;
}) {
    const isEditing = field !== null;
    const form = useForm<FieldFormData>(field ? fieldToForm(field) : emptyForm);

    const inputClass =
        'rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm dark:border-zinc-800 dark:bg-zinc-950';
    const labelClass = 'text-xs font-medium text-zinc-700 dark:text-zinc-300';

    function handleSubmit(e: React.FormEvent) {
        e.preventDefault();

        form.transform((data) => ({
            ...data,
            form_type: data.form_type === '' ? null : data.form_type,
            options: data.type === 'select' ? data.options : [],
        }));

        const submitOptions = {
            onSuccess: () => {
                onOpenChange(false);
                form.reset();
            },
        };

        if (isEditing) {
            form.put(
                update.url({ supplier: supplierId, supplierWebFormField: field.id }),
                submitOptions,
            );
        } else {
            form.post(store.url(supplierId), submitOptions);
        }
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-2xl">
                <DialogHeader>
                    <DialogTitle>
                        {isEditing ? `Edit "${field.name}"` : 'Add supplier field'}
                    </DialogTitle>
                </DialogHeader>

                <form onSubmit={handleSubmit} className="space-y-4 pt-2">
                    <div className="grid grid-cols-1 gap-3 sm:grid-cols-6">
                        <div className="flex flex-col gap-1 sm:col-span-2">
                            <label className={labelClass}>Form type</label>
                            <select
                                value={form.data.form_type}
                                onChange={(e) =>
                                    form.setData('form_type', e.target.value as WebFormTypeValue | '')
                                }
                                className={inputClass}
                            >
                                <option value="">All forms</option>
                                {WEB_FORM_TYPES.map((t) => (
                                    <option key={t.value} value={t.value}>
                                        {t.label} only
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.form_type} />
                        </div>

                        <div className="sm:col-span-4" />

                        <div className="flex flex-col gap-1 sm:col-span-2">
                            <label className={labelClass}>Name</label>
                            <input
                                value={form.data.name}
                                onChange={(e) => form.setData('name', e.target.value)}
                                className={inputClass}
                                placeholder="birth_date"
                            />
                            <FieldError message={form.errors.name} />
                        </div>

                        <div className="flex flex-col gap-1 sm:col-span-2">
                            <label className={labelClass}>Label</label>
                            <input
                                value={form.data.label}
                                onChange={(e) => form.setData('label', e.target.value)}
                                className={inputClass}
                                placeholder="Date of Birth"
                            />
                            <FieldError message={form.errors.label} />
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Type</label>
                            <select
                                value={form.data.type}
                                onChange={(e) => form.setData('type', e.target.value as FieldType)}
                                className={inputClass}
                            >
                                <option value="" disabled>
                                    Select...
                                </option>
                                {FIELD_TYPES.map((t) => (
                                    <option key={t} value={t}>
                                        {t}
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.type} />
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Required</label>
                            <select
                                value={form.data.required}
                                onChange={(e) => form.setData('required', e.target.value)}
                                className={inputClass}
                            >
                                <option value="1">Yes</option>
                                <option value="0">No</option>
                            </select>
                        </div>

                        <div className="flex flex-col gap-1 sm:col-span-3">
                            <label className={labelClass}>Placeholder</label>
                            <input
                                value={form.data.placeholder}
                                onChange={(e) => form.setData('placeholder', e.target.value)}
                                className={inputClass}
                                placeholder="Enter value..."
                            />
                        </div>

                        <div className="flex flex-col gap-1 sm:col-span-3">
                            <label className={labelClass}>Help text</label>
                            <input
                                value={form.data.help_text}
                                onChange={(e) => form.setData('help_text', e.target.value)}
                                className={inputClass}
                                placeholder="Helpful description for the user"
                            />
                        </div>

                        <div className="flex flex-col gap-1 sm:col-span-3">
                            <label className={labelClass}>Validation pattern</label>
                            <input
                                value={form.data.validation_pattern}
                                onChange={(e) => form.setData('validation_pattern', e.target.value)}
                                className={inputClass}
                                placeholder="^\d{4}-\d{2}-\d{2}$"
                            />
                        </div>

                        <div className="flex flex-col gap-1 sm:col-span-3">
                            <label className={labelClass}>Validation message</label>
                            <input
                                value={form.data.validation_message}
                                onChange={(e) => form.setData('validation_message', e.target.value)}
                                className={inputClass}
                                placeholder="Please enter a valid value."
                            />
                        </div>

                        {form.data.type === 'select' && (
                            <div className="flex flex-col gap-1 sm:col-span-6">
                                <label className={labelClass}>Options</label>
                                <OptionsEditor
                                    options={form.data.options}
                                    onChange={(opts) => form.setData('options', opts)}
                                />
                                <FieldError message={form.errors.options} />
                            </div>
                        )}
                    </div>

                    <div className="flex items-center justify-end gap-3 pt-2">
                        <button
                            type="button"
                            onClick={() => onOpenChange(false)}
                            className="text-sm text-zinc-600 hover:underline dark:text-zinc-400"
                        >
                            Cancel
                        </button>
                        <button
                            type="submit"
                            disabled={form.processing}
                            className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white disabled:opacity-60 dark:bg-zinc-100 dark:text-zinc-900"
                        >
                            {isEditing ? 'Save changes' : 'Add field'}
                        </button>
                    </div>
                </form>
            </DialogContent>
        </Dialog>
    );
}

const breadcrumbs = [{ title: 'Supplier Web Form Fields', href: index.url() }];

export default function SupplierWebFormFields({ suppliers, selectedSupplierId, fields }: Props) {
    const [modalField, setModalField] = useState<SupplierWebFormField | null | undefined>(
        undefined,
    );
    const isModalOpen = modalField !== undefined;

    function handleSupplierChange(supplierId: string) {
        router.get(index.url(), { supplier_id: supplierId }, { preserveState: false });
    }

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Supplier Web Form Fields" />

            <h1 className="sr-only">Supplier Web Form Fields</h1>

            <div className="space-y-6">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                    <HeadingSmall
                        title="Supplier Web Form Fields"
                        description="Define supplier-specific fields that appear on web forms when a product from that supplier is selected."
                    />

                    {selectedSupplierId && (
                        <button
                            type="button"
                            onClick={() => setModalField(null)}
                            className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white dark:bg-zinc-100 dark:text-zinc-900"
                        >
                            Add field
                        </button>
                    )}
                </div>

                {/* Supplier selector */}
                <div className="rounded-md border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-950">
                    <div className="flex flex-col gap-1 sm:max-w-xs">
                        <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                            Supplier
                        </label>
                        <select
                            className="rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm dark:border-zinc-800 dark:bg-zinc-950"
                            value={selectedSupplierId ?? ''}
                            onChange={(e) => handleSupplierChange(e.target.value)}
                        >
                            {suppliers.length === 0 && (
                                <option value="" disabled>
                                    No suppliers available
                                </option>
                            )}
                            {suppliers.map((s) => (
                                <option key={s.id} value={s.id}>
                                    {s.name}
                                </option>
                            ))}
                        </select>
                    </div>
                </div>

                {/* Fields table */}
                {selectedSupplierId && (
                    <div className="overflow-hidden rounded-md border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950">
                        <div className="overflow-x-auto">
                            <table className="w-full text-left text-sm">
                                <thead className="border-b border-zinc-200 text-xs uppercase text-zinc-600 dark:border-zinc-800 dark:text-zinc-400">
                                    <tr>
                                        <th className="px-4 py-3">Name</th>
                                        <th className="px-4 py-3">Label</th>
                                        <th className="px-4 py-3">Type</th>
                                        <th className="px-4 py-3">Form</th>
                                        <th className="px-4 py-3">Required</th>
                                        <th className="px-4 py-3">Options</th>
                                        <th className="px-4 py-3" />
                                    </tr>
                                </thead>
                                <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
                                    {fields.map((f) => (
                                        <tr key={f.id}>
                                            <td className="px-4 py-3 font-mono text-xs font-medium">
                                                {f.name}
                                            </td>
                                            <td className="px-4 py-3">{f.label}</td>
                                            <td className="px-4 py-3 text-zinc-600 dark:text-zinc-400">
                                                {f.type}
                                            </td>
                                            <td className="px-4 py-3 text-zinc-600 dark:text-zinc-400">
                                                {f.form_type
                                                    ? (WEB_FORM_TYPES.find((t) => t.value === f.form_type)?.label ?? f.form_type)
                                                    : <span className="text-zinc-400">All</span>}
                                            </td>
                                            <td className="px-4 py-3 text-zinc-600 dark:text-zinc-400">
                                                {f.required ? 'Yes' : 'No'}
                                            </td>
                                            <td className="px-4 py-3 text-zinc-600 dark:text-zinc-400">
                                                {f.options && f.options.length > 0 ? (
                                                    <span className="font-mono text-xs">
                                                        {f.options.map((o) => o.value).join(', ')}
                                                    </span>
                                                ) : (
                                                    <span className="text-zinc-400">—</span>
                                                )}
                                            </td>
                                            <td className="px-4 py-3 text-right">
                                                <div className="flex items-center justify-end gap-4">
                                                    <button
                                                        type="button"
                                                        onClick={() => setModalField(f)}
                                                        className="text-sm text-zinc-700 hover:underline dark:text-zinc-300"
                                                    >
                                                        Edit
                                                    </button>
                                                    <Form
                                                        method="delete"
                                                        action={destroy.url({
                                                            supplier: selectedSupplierId,
                                                            supplierWebFormField: f.id,
                                                        })}
                                                    >
                                                        {({ processing }) => (
                                                            <button
                                                                type="submit"
                                                                disabled={processing}
                                                                className="text-sm text-red-700 hover:underline disabled:opacity-60 dark:text-red-400"
                                                            >
                                                                Delete
                                                            </button>
                                                        )}
                                                    </Form>
                                                </div>
                                            </td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>

                        {fields.length === 0 && (
                            <div className="p-4 text-sm text-zinc-600 dark:text-zinc-400">
                                No supplier fields defined for this supplier yet.
                            </div>
                        )}
                    </div>
                )}
            </div>

            {selectedSupplierId && (
                <FieldModal
                    key={modalField?.id ?? 'new'}
                    open={isModalOpen}
                    onOpenChange={(open) => {
                        if (!open) setModalField(undefined);
                    }}
                    supplierId={selectedSupplierId}
                    field={modalField ?? null}
                />
            )}
        </AppLayout>
    );
}
