import { Head, router } from '@inertiajs/react';
import { useCallback, useMemo, useState } from 'react';

import HeadingSmall from '@/components/heading-small';
import { Checkbox } from '@/components/ui/checkbox';
import AppLayout from '@/layouts/app-layout';
import { index as zipCodesIndex } from '@/routes/admin/zip-codes';
import { sync as syncUtilities } from '@/routes/admin/zip-codes/utilities';

type State = {
    id: number;
    code: string;
    name: string;
};

type ZipCode = {
    id: number;
    zipcode: string;
    place_name: string | null;
    state_id: number;
    state: State | null;
};

type Utility = {
    id: number;
    name: string;
    code: string | null;
};

type Props = {
    zipCode: ZipCode;
    utilities: Utility[];
    assignedIds: number[];
};

const breadcrumbs = (zipCode: ZipCode) => [
    { title: 'Zip Codes', href: zipCodesIndex.url() },
    { title: zipCode.zipcode, href: '#' },
];

export default function ZipCodeUtilities({ zipCode, utilities, assignedIds }: Props) {
    const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set(assignedIds));
    const [saving, setSaving] = useState(false);

    const toggle = useCallback((id: number) => {
        setSelectedIds((prev) => {
            const next = new Set(prev);
            if (next.has(id)) {
                next.delete(id);
            } else {
                next.add(id);
            }
            return next;
        });
    }, []);

    const handleSave = useCallback(() => {
        setSaving(true);

        router.put(
            syncUtilities.url(zipCode.id),
            { utility_ids: Array.from(selectedIds) },
            { onFinish: () => setSaving(false) },
        );
    }, [zipCode, selectedIds]);

    const sortedUtilities = useMemo(
        () => [...utilities].sort((a, b) => a.name.localeCompare(b.name)),
        [utilities],
    );

    return (
        <AppLayout breadcrumbs={breadcrumbs(zipCode)}>
            <Head title={`Utilities for ${zipCode.zipcode}`} />

            <div className="space-y-6">
                <HeadingSmall
                    title={`Utilities for ${zipCode.zipcode}`}
                    description={
                        zipCode.state
                            ? `All utilities operating in ${zipCode.state.name} (${zipCode.state.code}). Toggle which ones serve ${zipCode.zipcode}${zipCode.place_name ? ` (${zipCode.place_name})` : ''}.`
                            : `All utilities operating in this zip code's state.`
                    }
                />

                <div className="flex items-center justify-between text-sm text-zinc-600 dark:text-zinc-400">
                    <span>
                        {selectedIds.size} of {sortedUtilities.length} utilities assigned
                    </span>
                    <button
                        type="button"
                        onClick={handleSave}
                        disabled={saving}
                        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"
                    >
                        {saving ? 'Saving…' : 'Save'}
                    </button>
                </div>

                <div className="overflow-hidden rounded-md border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950">
                    {sortedUtilities.length === 0 ? (
                        <div className="p-4 text-center text-sm text-zinc-500">
                            No utilities found for this state.
                        </div>
                    ) : (
                        sortedUtilities.map((u) => (
                            <label
                                key={u.id}
                                className="flex cursor-pointer items-center gap-3 border-b border-zinc-100 px-4 py-3 last:border-b-0 hover:bg-zinc-50 dark:border-zinc-800/50 dark:hover:bg-zinc-900"
                            >
                                <Checkbox
                                    checked={selectedIds.has(u.id)}
                                    onCheckedChange={() => toggle(u.id)}
                                />
                                <span className="text-sm font-medium">{u.name}</span>
                                {u.code && (
                                    <span className="font-mono text-xs text-zinc-500 dark:text-zinc-400">
                                        {u.code}
                                    </span>
                                )}
                            </label>
                        ))
                    )}
                </div>
            </div>
        </AppLayout>
    );
}
