import { Form, Head, router, useForm } from '@inertiajs/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, disable, enable, index, store, update } from '@/routes/admin/supplier-state-affirmations';

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

type AffirmationVersion = {
    id: number;
    version: number;
    text: string;
    is_current: boolean;
};

type Affirmation = {
    id: number;
    supplier_id: number | null;
    state_id: number | null;
    is_enabled: boolean;
    current_version: AffirmationVersion | null;
};

type Props = {
    suppliers: SupplierOption[];
    states: StateOption[];
    selectedSupplierId: number | null;
    selectedStateId: number | null;
    affirmations: Affirmation[];
};

type CreateFormData = { supplier_id: string; state_id: string; text: string };
type EditFormData = { supplier_id: string; state_id: string; text: string; is_enabled: string };

type ScopeKind = 'global' | 'state' | 'specific';

function getScopeKind(supplierId: number | null, stateId: number | null): ScopeKind {
    if (supplierId === null && stateId === null) return 'global';
    if (supplierId === null) return 'state';
    return 'specific';
}

function ScopeBadge({
    supplierId,
    stateId,
    suppliers,
    states,
}: {
    supplierId: number | null;
    stateId: number | null;
    suppliers: SupplierOption[];
    states: StateOption[];
}) {
    const kind = getScopeKind(supplierId, stateId);

    const supplierLabel = supplierId
        ? (suppliers.find((s) => s.id === supplierId)?.name ?? 'Unknown supplier')
        : 'All suppliers';
    const stateLabel = stateId
        ? (states.find((s) => s.id === stateId)?.name ?? 'Unknown state')
        : 'All states';

    const styles: Record<ScopeKind, string> = {
        global: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
        state: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
        specific: 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300',
    };

    return (
        <span
            className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${styles[kind]}`}
        >
            {supplierLabel} · {stateLabel}
        </span>
    );
}

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

function CreateModal({
    open,
    onOpenChange,
    suppliers,
    states,
    selectedSupplierId,
    selectedStateId,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    suppliers: SupplierOption[];
    states: StateOption[];
    selectedSupplierId: number | null;
    selectedStateId: number | null;
}) {
    const form = useForm<CreateFormData>({
        supplier_id: selectedSupplierId ? String(selectedSupplierId) : '',
        state_id: selectedStateId ? String(selectedStateId) : '',
        text: '',
    });

    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,
            supplier_id: data.supplier_id === '' ? null : Number(data.supplier_id),
            state_id: data.state_id === '' ? null : Number(data.state_id),
        }));
        form.post(store.url(), {
            onSuccess: () => {
                onOpenChange(false);
                form.reset();
            },
        });
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-2xl">
                <DialogHeader>
                    <DialogTitle>Add affirmation</DialogTitle>
                </DialogHeader>
                <form onSubmit={handleSubmit} className="space-y-4 pt-2">
                    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Applies to supplier</label>
                            <select
                                value={form.data.supplier_id}
                                onChange={(e) => form.setData('supplier_id', e.target.value)}
                                className={inputClass}
                            >
                                <option value="">All suppliers</option>
                                {suppliers.map((s) => (
                                    <option key={s.id} value={s.id}>
                                        {s.name}
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.supplier_id} />
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Applies to state</label>
                            <select
                                value={form.data.state_id}
                                onChange={(e) => form.setData('state_id', e.target.value)}
                                className={inputClass}
                            >
                                <option value="">All states</option>
                                {states.map((s) => (
                                    <option key={s.id} value={s.id}>
                                        {s.name} ({s.code})
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.state_id} />
                        </div>
                    </div>

                    <div className="flex flex-col gap-1">
                        <label className={labelClass}>Affirmation text</label>
                        <textarea
                            rows={5}
                            value={form.data.text}
                            onChange={(e) => form.setData('text', e.target.value)}
                            className={inputClass}
                            placeholder="I agree to the terms and conditions..."
                        />
                        <FieldError message={form.errors.text} />
                    </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"
                        >
                            Add affirmation
                        </button>
                    </div>
                </form>
            </DialogContent>
        </Dialog>
    );
}

function EditModal({
    open,
    onOpenChange,
    affirmation,
    suppliers,
    states,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    affirmation: Affirmation;
    suppliers: SupplierOption[];
    states: StateOption[];
}) {
    const form = useForm<EditFormData>({
        supplier_id: affirmation.supplier_id ? String(affirmation.supplier_id) : '',
        state_id: affirmation.state_id ? String(affirmation.state_id) : '',
        text: affirmation.current_version?.text ?? '',
        is_enabled: affirmation.is_enabled ? '1' : '0',
    });

    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,
            supplier_id: data.supplier_id === '' ? null : Number(data.supplier_id),
            state_id: data.state_id === '' ? null : Number(data.state_id),
            is_enabled: data.is_enabled === '1',
        }));
        form.put(update.url(affirmation.id), {
            onSuccess: () => onOpenChange(false),
        });
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-2xl">
                <DialogHeader>
                    <DialogTitle>Edit affirmation</DialogTitle>
                </DialogHeader>
                <form onSubmit={handleSubmit} className="space-y-4 pt-2">
                    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Applies to supplier</label>
                            <select
                                value={form.data.supplier_id}
                                onChange={(e) => form.setData('supplier_id', e.target.value)}
                                className={inputClass}
                            >
                                <option value="">All suppliers</option>
                                {suppliers.map((s) => (
                                    <option key={s.id} value={s.id}>
                                        {s.name}
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.supplier_id} />
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className={labelClass}>Applies to state</label>
                            <select
                                value={form.data.state_id}
                                onChange={(e) => form.setData('state_id', e.target.value)}
                                className={inputClass}
                            >
                                <option value="">All states</option>
                                {states.map((s) => (
                                    <option key={s.id} value={s.id}>
                                        {s.name} ({s.code})
                                    </option>
                                ))}
                            </select>
                            <FieldError message={form.errors.state_id} />
                        </div>
                    </div>

                    <div className="flex flex-col gap-1">
                        <div className="flex items-center gap-2">
                            <label className={labelClass}>Affirmation text</label>
                            {affirmation.current_version && (
                                <span className="text-xs text-zinc-400 dark:text-zinc-500">
                                    v{affirmation.current_version.version} — changing text publishes a new version
                                </span>
                            )}
                        </div>
                        <textarea
                            rows={5}
                            value={form.data.text}
                            onChange={(e) => form.setData('text', e.target.value)}
                            className={inputClass}
                        />
                        <FieldError message={form.errors.text} />
                    </div>

                    <div className="flex flex-col gap-1 sm:max-w-xs">
                        <label className={labelClass}>Status</label>
                        <select
                            value={form.data.is_enabled}
                            onChange={(e) => form.setData('is_enabled', e.target.value)}
                            className={inputClass}
                        >
                            <option value="1">Enabled</option>
                            <option value="0">Disabled</option>
                        </select>
                    </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"
                        >
                            Save changes
                        </button>
                    </div>
                </form>
            </DialogContent>
        </Dialog>
    );
}

const breadcrumbs = [{ title: 'Supplier State Affirmations', href: index.url() }];

export default function SupplierStateAffirmations({
    suppliers,
    states,
    selectedSupplierId,
    selectedStateId,
    affirmations,
}: Props) {
    const [showCreateModal, setShowCreateModal] = useState(false);
    const [editingAffirmation, setEditingAffirmation] = useState<Affirmation | null>(null);

    function handleSupplierChange(value: string) {
        router.get(
            index.url(),
            { supplier_id: value || undefined, state_id: selectedStateId || undefined },
            { preserveState: false },
        );
    }

    function handleStateChange(value: string) {
        router.get(
            index.url(),
            { supplier_id: selectedSupplierId || undefined, state_id: value || undefined },
            { preserveState: false },
        );
    }

    const isFiltered = selectedSupplierId !== null || selectedStateId !== null;

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Supplier State Affirmations" />

            <h1 className="sr-only">Supplier State Affirmations</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 State Affirmations"
                        description="Manage affirmation checkboxes presented to customers during enrollment. Affirmations can be scoped to a specific supplier and state, a specific state across all suppliers, or applied globally."
                    />

                    <button
                        type="button"
                        onClick={() => setShowCreateModal(true)}
                        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 affirmation
                    </button>
                </div>

                <div className="grid grid-cols-1 gap-4 rounded-md border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-950 sm:grid-cols-2">
                    <div className="flex flex-col gap-1">
                        <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                            Filter by 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)}
                        >
                            <option value="">All suppliers</option>
                            {suppliers.map((s) => (
                                <option key={s.id} value={s.id}>
                                    {s.name}
                                </option>
                            ))}
                        </select>
                    </div>

                    <div className="flex flex-col gap-1">
                        <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                            Filter by state
                        </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={selectedStateId ?? ''}
                            onChange={(e) => handleStateChange(e.target.value)}
                        >
                            <option value="">All states</option>
                            {states.map((s) => (
                                <option key={s.id} value={s.id}>
                                    {s.name} ({s.code})
                                </option>
                            ))}
                        </select>
                    </div>
                </div>

                <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">Scope</th>
                                    <th className="px-4 py-3">Text</th>
                                    <th className="px-4 py-3">Version</th>
                                    <th className="px-4 py-3">Status</th>
                                    <th className="px-4 py-3" />
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
                                {affirmations.map((a) => (
                                    <tr key={a.id}>
                                        <td className="px-4 py-3">
                                            <ScopeBadge
                                                supplierId={a.supplier_id}
                                                stateId={a.state_id}
                                                suppliers={suppliers}
                                                states={states}
                                            />
                                        </td>
                                        <td className="max-w-sm px-4 py-3">
                                            {a.current_version ? (
                                                <span className="line-clamp-2 text-sm text-zinc-800 dark:text-zinc-200">
                                                    {a.current_version.text}
                                                </span>
                                            ) : (
                                                <span className="italic text-zinc-400">No version</span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 text-zinc-600 dark:text-zinc-400">
                                            {a.current_version ? (
                                                <span className="font-mono text-xs">
                                                    v{a.current_version.version}
                                                </span>
                                            ) : (
                                                <span className="text-zinc-400">—</span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3">
                                            {a.is_enabled ? (
                                                <span className="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900/30 dark:text-green-400">
                                                    Enabled
                                                </span>
                                            ) : (
                                                <span className="inline-flex items-center rounded-full bg-zinc-100 px-2 py-0.5 text-xs font-medium text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400">
                                                    Disabled
                                                </span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 text-right">
                                            <div className="flex items-center justify-end gap-4">
                                                <button
                                                    type="button"
                                                    onClick={() => setEditingAffirmation(a)}
                                                    className="text-sm text-zinc-700 hover:underline dark:text-zinc-300"
                                                >
                                                    Edit
                                                </button>
                                                {a.is_enabled ? (
                                                    <Form method="post" action={disable.url(a.id)}>
                                                        {({ processing }) => (
                                                            <button
                                                                type="submit"
                                                                disabled={processing}
                                                                className="text-sm text-amber-700 hover:underline disabled:opacity-60 dark:text-amber-400"
                                                            >
                                                                Disable
                                                            </button>
                                                        )}
                                                    </Form>
                                                ) : (
                                                    <Form method="post" action={enable.url(a.id)}>
                                                        {({ processing }) => (
                                                            <button
                                                                type="submit"
                                                                disabled={processing}
                                                                className="text-sm text-green-700 hover:underline disabled:opacity-60 dark:text-green-400"
                                                            >
                                                                Enable
                                                            </button>
                                                        )}
                                                    </Form>
                                                )}
                                                <Form method="delete" action={destroy.url(a.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>

                    {affirmations.length === 0 && (
                        <div className="p-4 text-sm text-zinc-600 dark:text-zinc-400">
                            {isFiltered
                                ? 'No affirmations match the current filters.'
                                : 'No affirmations have been created yet.'}
                        </div>
                    )}
                </div>
            </div>

            <CreateModal
                key={showCreateModal ? 'open' : 'closed'}
                open={showCreateModal}
                onOpenChange={setShowCreateModal}
                suppliers={suppliers}
                states={states}
                selectedSupplierId={selectedSupplierId}
                selectedStateId={selectedStateId}
            />

            {editingAffirmation && (
                <EditModal
                    key={editingAffirmation.id}
                    open={editingAffirmation !== null}
                    onOpenChange={(open) => {
                        if (!open) setEditingAffirmation(null);
                    }}
                    affirmation={editingAffirmation}
                    suppliers={suppliers}
                    states={states}
                />
            )}
        </AppLayout>
    );
}
