import { Head, Link, useForm, usePage, router } from '@inertiajs/react';
import AppLayout from '@/layouts/app-layout';
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import InputError from '@/components/input-error';
import { Checkbox } from '@/components/ui/checkbox';
import { Textarea } from '@/components/ui/textarea';
import { type BreadcrumbItem } from '@/types';
import { useMemo } from 'react';

// Ensure a Textarea component exists; if not, replace with <textarea className="..." />

type EntryField = 'form_name' | 'slug' | 'user_id' | 'approved' | 'approved_at' | 'origin_site' | 'seven_days_from' | 'last_updated_by_user_id' | 'last_page_filled' | 'death_cert_received' | 'pm_med_records_received' | 'title' | 'title_other' | 'first_name' | 'last_name' | 'address_1' | 'address_2' | 'city' | 'county' | 'country' | 'postcode' | 'telephone' | 'email' | 'relationship_type' | 'relationship_if_family' | 'relationship_if_friend' | 'relationship_if_professional' | 'consent' | 'agree_study_publications' | 'agree_further_research' | 'agree_use_of_info' | 'agree_use_of_info_part2' | 'allowed_to_contact' | 'preferred_contact' | 'wants_more_info_on_helping' | 'receive_enews' | 'allowed_to_contact_med_team' | 'medical_notice_details' | 'medical_notice_permission' | 'deceased_title' | 'deceased_first_name' | 'deceased_last_name' | 'deceased_known_as' | 'deceased_address_1' | 'deceased_address_2' | 'deceased_city' | 'deceased_county' | 'deceased_country' | 'deceased_postcode' | 'age_at_death' | 'exact_age_at_death' | 'deceased_gender' | 'deceased_gender_other' | 'date_of_birth' | 'date_of_death' | 'knows_where_death_occurred' | 'where_death_occurred' | 'coroner_or_fiscal' | 'gp' | 'knows_certified_cause' | 'type_of_death_certificate' | 'cause_1a' | 'cause_1b' | 'cause_1c' | 'cause_2' | 'other_type_certificate' | 'no_certificate_but_told_cause' | 'agree_to_contact_for_copy' | 'language' | 'nationality' | 'ethnicity' | 'ethnicity_other' | 'occupation' | 'occupation_other' | 'other_comments';

type Entry = { id: number } & { [K in EntryField]?: string | number | boolean | null };

const GROUPS: { key: string; title: string; fields: string[] }[] = [
    { key: 'meta', title: 'Meta & Status', fields: ['form_name', 'origin_site', 'seven_days_from', 'last_page_filled', 'approved', 'approved_at', 'death_cert_received', 'pm_med_records_received'] },
    { key: 'respondent', title: 'Respondent Details', fields: ['title', 'title_other', 'first_name', 'last_name', 'address_1', 'address_2', 'city', 'county', 'country', 'postcode', 'telephone', 'email', 'relationship_type', 'relationship_if_family', 'relationship_if_friend', 'relationship_if_professional'] },
    { key: 'consent', title: 'Consent', fields: ['consent', 'agree_study_publications', 'agree_further_research', 'agree_use_of_info', 'agree_use_of_info_part2', 'allowed_to_contact', 'preferred_contact', 'wants_more_info_on_helping', 'receive_enews', 'allowed_to_contact_med_team'] },
    { key: 'medical', title: 'Medical Notice', fields: ['medical_notice_details', 'medical_notice_permission'] },
    { key: 'deceased', title: 'Deceased Details', fields: ['deceased_title', 'deceased_first_name', 'deceased_last_name', 'deceased_known_as', 'deceased_address_1', 'deceased_address_2', 'deceased_city', 'deceased_county', 'deceased_country', 'deceased_postcode', 'age_at_death', 'exact_age_at_death', 'deceased_gender', 'deceased_gender_other', 'date_of_birth', 'date_of_death'] },
    { key: 'death', title: 'Death Circumstances', fields: ['knows_where_death_occurred', 'where_death_occurred', 'coroner_or_fiscal', 'gp', 'knows_certified_cause', 'type_of_death_certificate', 'cause_1a', 'cause_1b', 'cause_1c', 'cause_2', 'other_type_certificate', 'no_certificate_but_told_cause', 'agree_to_contact_for_copy'] },
    { key: 'demographics', title: 'Demographics', fields: ['language', 'nationality', 'ethnicity', 'ethnicity_other', 'occupation', 'occupation_other'] },
    { key: 'other', title: 'Other', fields: ['other_comments'] },
];

const BOOLEAN_FIELDS = new Set([
    'approved', 'death_cert_received', 'pm_med_records_received', 'consent', 'agree_study_publications', 'agree_further_research', 'agree_use_of_info', 'agree_use_of_info_part2', 'allowed_to_contact', 'wants_more_info_on_helping', 'receive_enews', 'allowed_to_contact_med_team', 'medical_notice_permission', 'knows_where_death_occurred', 'knows_certified_cause', 'no_certificate_but_told_cause', 'agree_to_contact_for_copy'
]);

const DATE_FIELDS = new Set(['approved_at', 'seven_days_from', 'date_of_birth', 'date_of_death']);

const TEXTAREA_FIELDS = new Set(['medical_notice_details', 'other_comments', 'cause_1a', 'cause_1b', 'cause_1c', 'cause_2']);

const NUMBER_FIELDS = new Set(['age_at_death']);

export default function EditEntry() {
    const { entry } = usePage<{ entry: Entry }>().props;
    const url = new URL(window.location.href);
    const stepParam = url.searchParams.get('step') || undefined;
    const step = stepParam || 'meta';
    const group = GROUPS.find(g => g.key === step) || GROUPS[0];

    const breadcrumbs: BreadcrumbItem[] = [
        { title: 'Entries', href: '/entries' },
        { title: String(entry.form_name || 'Entry'), href: `/entries/${entry.id}` },
        { title: group.title, href: `/entries/${entry.id}/edit?step=${group.key}` },
    ];

    const { data, setData, patch, processing, errors, wasSuccessful } = useForm<Entry>({ ...entry });

    const orderedGroups = useMemo(() => GROUPS.map(g => g.key), []);
    const currentIndex = orderedGroups.indexOf(group.key);

    const submit = (e: React.FormEvent) => {
        e.preventDefault();
        patch(route('entries.update', entry.id), { preserveScroll: true });
    };

    const gotoStep = (idx: number) => {
        if (!orderedGroups[idx]) return;
        router.visit(`/entries/${entry.id}/edit?step=${orderedGroups[idx]}`, { preserveScroll: true, preserveState: true });
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title={`Edit Entry - ${group.title}`} />
            <div className="space-y-6 max-w-5xl">
                <div className="flex items-center justify-between flex-wrap gap-2">
                    <h1 className="text-2xl font-semibold">Edit Entry: {group.title}</h1>
                    <div className="flex gap-2 flex-wrap">
                        {GROUPS.map(g => (
                            <Button key={g.key} variant={g.key === group.key ? 'default' : 'secondary'} size="sm" asChild>
                                <Link href={`/entries/${entry.id}/edit?step=${g.key}`}>{g.title}</Link>
                            </Button>
                        ))}
                    </div>
                </div>
                <form onSubmit={submit} className="space-y-8">
                    <div className="grid gap-6 md:grid-cols-2">
                        {group.fields.map(field => {
                            const f = field as EntryField;
                            const rawVal = data[f];
                            const value = rawVal ?? (BOOLEAN_FIELDS.has(f) ? false : '');
                            const commonProps = { id: f, name: f };
                            return (
                                <div key={f} className="flex flex-col gap-2">
                                    <Label htmlFor={f} className="capitalize">{f.replace(/_/g, ' ')}</Label>
                                    {BOOLEAN_FIELDS.has(f) ? (
                                        <div className="flex items-center gap-2">
                                            <Checkbox id={f} checked={!!value} onCheckedChange={(val) => setData(f, !!val)} />
                                        </div>
                                    ) : DATE_FIELDS.has(f) ? (
                                        <Input type="date" {...commonProps} value={value as string || ''} onChange={e => setData(f, e.target.value)} />
                                    ) : NUMBER_FIELDS.has(f) ? (
                                        <Input type="number" {...commonProps} value={value as number | string || ''} onChange={e => setData(f, e.target.value ? parseInt(e.target.value, 10) : '')} />
                                    ) : TEXTAREA_FIELDS.has(f) ? (
                                        <Textarea {...commonProps} value={value as string || ''} onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setData(f, e.target.value)} rows={3} />
                                    ) : (
                                        <Input type="text" {...commonProps} value={value as string || ''} onChange={e => setData(f, e.target.value)} />
                                    )}
                                    <InputError message={(errors as Record<string, string | undefined>)[f]} />
                                </div>
                            );
                        })}
                    </div>
                    <div className="flex items-center gap-4 flex-wrap">
                        <Button type="submit" disabled={processing}>Save {group.title}</Button>
                        {currentIndex > 0 && (
                            <Button type="button" variant="outline" onClick={() => gotoStep(currentIndex - 1)}>Previous</Button>
                        )}
                        {currentIndex < orderedGroups.length - 1 && (
                            <Button type="button" variant="secondary" onClick={() => gotoStep(currentIndex + 1)}>Next</Button>
                        )}
                        <Link href={route('entries.show', entry.id)} className="text-sm underline">Back to entry</Link>
                        {wasSuccessful && <span className="text-sm text-green-600">Saved</span>}
                    </div>
                </form>
            </div>
        </AppLayout>
    );
}
