import { router, usePage } from '@inertiajs/react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Icon } from '@/components/ui/icon';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { LoadingButton } from '@/components/ui/loading-button';
import {
    Sheet,
    SheetClose,
    SheetContent,
    SheetDescription,
    SheetFooter,
    SheetHeader,
    SheetTitle,
} from '@/components/ui/sheet';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
    ClientFormAccountantsSection,
    ClientFormContactsSection,
    ClientFormGeneralSection,
    ClientFormLocationSection,
} from '@/features/clients/components/client-form-sheet-sections';
import type { ClientFormDraft } from '@/features/clients/lib/client-form-draft';
import {
    clientEntityToFormDraft,
    emptyClientFormDraft,
} from '@/features/clients/lib/client-form-draft';
import type { ClientEntity, ClientFormSelectUser } from '@/features/clients/types';
import { useI18n } from '@/hooks/use-i18n';
import { cn } from '@/lib/utils';

type ClientFormStep = 'lookup' | 'form';
type ClientFormTabId = 'general' | 'location' | 'contacts' | 'accountants';

type AnafLookupResult = {
    name: string;
    trade_register_number: string;
    phone: string;
    address: string;
    city: string;
    county: string;
    country: string;
    is_vat_payer: boolean;
};

type ClientFormSheetProps = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    mode: 'create' | 'edit';
    client: ClientEntity | null;
    accountants: ClientFormSelectUser[];
    canManageContacts: boolean;
    canAssignAccountants: boolean;
    onAfterSave: () => void;
};

export function ClientFormSheet({
    open,
    onOpenChange,
    mode,
    client,
    accountants,
    canManageContacts,
    canAssignAccountants,
    onAfterSave,
}: ClientFormSheetProps) {
    const { t } = useI18n();
    const page = usePage<{ errors: Record<string, string | string[]> }>();

    const [submitting, setSubmitting] = useState(false);
    const [tab, setTab] = useState<ClientFormTabId>('general');
    const [step, setStep] = useState<ClientFormStep>(mode === 'create' ? 'lookup' : 'form');
    const [cuiInput, setCuiInput] = useState('');
    const [lookupLoading, setLookupLoading] = useState(false);
    const [lookupError, setLookupError] = useState<string | null>(null);
    const [lookupSuccess, setLookupSuccess] = useState(false);
    const cuiRef = useRef<HTMLInputElement>(null);
    const [form, setForm] = useState<ClientFormDraft>(() =>
        mode === 'edit' && client ? clientEntityToFormDraft(client) : emptyClientFormDraft(t('clients.admin_form.defaults.country')),
    );

    useEffect(() => {
        if (!open) {
            return;
        }

        setTab('general');
        setLookupError(null);
        setLookupSuccess(false);

        if (mode === 'create') {
            setStep('lookup');
            setCuiInput('');
            setForm(emptyClientFormDraft(t('clients.admin_form.defaults.country')));

            return;
        }

        setStep('form');
        if (mode === 'edit' && client) {
            setForm(clientEntityToFormDraft(client));
        }
    }, [open, mode, client, t]);

    useEffect(() => {
        if (open && step === 'lookup') {
            setTimeout(() => cuiRef.current?.focus(), 50);
        }
    }, [open, step]);

    const handleAnafLookup = async () => {
        const cui = cuiInput.trim();
        if (!cui) return;

        setLookupLoading(true);
        setLookupError(null);
        setLookupSuccess(false);

        try {
            const res = await fetch(`/admin/clients/anaf-lookup?cui=${encodeURIComponent(cui)}`);
            const data = (await res.json()) as AnafLookupResult & { error?: string };

            if (!res.ok) {
                setLookupError(data.error ?? t('clients.admin_form.anaf_lookup.not_found'));
                return;
            }

            setForm((prev) => ({
                ...prev,
                name: data.name || prev.name,
                cif: cui,
                trade_register_number: data.trade_register_number || prev.trade_register_number,
                phone: data.phone || prev.phone,
                address: data.address || prev.address,
                city: data.city || prev.city,
                county: data.county || prev.county,
                country: data.country || prev.country,
                is_vat_payer: data.is_vat_payer,
                is_individual: false,
            }));

            setLookupSuccess(true);
            setStep('form');
        } catch {
            setLookupError(t('clients.admin_form.anaf_lookup.service_error'));
        } finally {
            setLookupLoading(false);
        }
    };

    useEffect(() => {
        if (tab === 'contacts' && !canManageContacts) {
            setTab('general');
        }
        if (tab === 'accountants' && !canAssignAccountants) {
            setTab('general');
        }
    }, [tab, canManageContacts, canAssignAccountants]);

    const title = step === 'lookup'
        ? t('clients.admin_form.anaf_lookup.step_title')
        : mode === 'create'
            ? t('clients.admin_form.sheet.title_create')
            : t('clients.admin_form.sheet.title_edit');

    const buildPayload = (): Record<string, unknown> => {
        const base: Record<string, unknown> = {
            name: form.name.trim(),
            is_individual: form.is_individual,
            is_vat_payer: form.is_vat_payer,
            active: form.active,
            cif: form.is_individual ? null : form.cif.trim() || null,
            trade_register_number: form.is_individual ? null : form.trade_register_number.trim() || null,
            phone: form.phone.trim() || null,
            email: form.email.trim() || null,
            country: form.country.trim(),
            county: form.county.trim(),
            city: form.city.trim(),
            address: form.address.trim(),
        };

        if (canAssignAccountants) {
            base.accountant_user_ids = form.accountant_user_ids;
        }

        if (canManageContacts) {
            const cleaned = form.contacts
                .filter((row) => row.name.trim() !== '')
                .map((row) => ({
                    ...(row.id ? { id: row.id } : {}),
                    name: row.name.trim(),
                    email: row.email.trim() || null,
                    phone: row.phone.trim() || null,
                    position: row.position.trim() || null,
                    is_primary: row.is_primary,
                }));
            base.contacts = cleaned;
        }

        return base;
    };

    const submit = () => {
        const payload = buildPayload();

        const options = {
            preserveScroll: true,
            onStart: () => setSubmitting(true),
            onFinish: () => setSubmitting(false),
            onSuccess: () => {
                onOpenChange(false);
                onAfterSave();
            },
        };

        if (mode === 'create') {
            router.post('/admin/clients', payload as Parameters<typeof router.post>[1], options);
        } else if (client) {
            router.patch(`/admin/clients/${client.id}`, payload as Parameters<typeof router.patch>[1], options);
        }
    };

    const errorBanner = useMemo(() => {
        const errs = page.props.errors ?? {};
        const keys = Object.keys(errs);

        if (keys.length === 0) {
            return null;
        }

        const first = errs[keys[0] ?? ''];
        const message = Array.isArray(first) ? first[0] : first;

        return (
            <div className="rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
                {message ?? t('clients.admin_form.sheet.error_fallback')}
            </div>
        );
    }, [page.props.errors, t]);

    const lookupBody = (
        <div className="flex flex-1 flex-col items-center justify-center px-6 py-10">
            <div className="w-full max-w-sm space-y-6">
                <p className="text-sm text-muted-foreground text-center">
                    {t('clients.admin_form.anaf_lookup.step_description')}
                </p>

                <div className="space-y-2">
                    <Label htmlFor="anaf-cui">{t('clients.admin_form.anaf_lookup.cui_label')}</Label>
                    <Input
                        id="anaf-cui"
                        ref={cuiRef}
                        value={cuiInput}
                        onChange={(e) => { setCuiInput(e.target.value); setLookupError(null); }}
                        placeholder={t('clients.admin_form.anaf_lookup.cui_placeholder')}
                        onKeyDown={(e) => { if (e.key === 'Enter') void handleAnafLookup(); }}
                        autoComplete="off"
                    />
                    {lookupError ? (
                        <p className="text-sm text-destructive">{lookupError}</p>
                    ) : null}
                </div>

                <LoadingButton
                    type="button"
                    className="w-full"
                    loading={lookupLoading}
                    loadingPosition="end"
                    onClick={() => void handleAnafLookup()}
                >
                    {t('clients.admin_form.anaf_lookup.search_button')}
                </LoadingButton>

                <div className="text-center">
                    <button
                        type="button"
                        className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
                        onClick={() => setStep('form')}
                    >
                        {t('clients.admin_form.anaf_lookup.skip_link')}
                    </button>
                </div>
            </div>
        </div>
    );

    const sheetBody =
        mode === 'edit' && !client ? (
            <p className="text-sm text-muted-foreground">{t('clients.admin_form.sheet.loading_client')}</p>
        ) : (
            <Tabs
                value={tab}
                onValueChange={(value) => setTab(value as ClientFormTabId)}
                className="flex min-h-0 flex-1 flex-col gap-0 sm:flex-row sm:items-stretch"
                aria-label={title}
            >
                <TabsList className="h-auto w-full shrink-0 flex-row gap-1.5 rounded-none border-b border-border bg-transparent px-3 py-2 sm:h-auto sm:w-52 sm:flex-col sm:items-stretch sm:justify-start sm:rounded-none sm:border-b-0 sm:border-r sm:px-3 sm:py-3">
                    <TabsTrigger value="general" className="w-full flex-none basis-auto">
                        {t('clients.admin_form.tabs.general')}
                    </TabsTrigger>
                    <TabsTrigger value="location" className="w-full flex-none basis-auto">
                        {t('clients.admin_form.tabs.location')}
                    </TabsTrigger>
                    {canManageContacts ? (
                        <TabsTrigger value="contacts" className="w-full flex-none basis-auto">
                            {t('clients.admin_form.tabs.contacts')}
                        </TabsTrigger>
                    ) : null}
                    {canAssignAccountants ? (
                        <TabsTrigger value="accountants" className="w-full flex-none basis-auto">
                            {t('clients.admin_form.tabs.accountants')}
                        </TabsTrigger>
                    ) : null}
                </TabsList>

                <div className="flex min-h-0 min-w-0 flex-1 flex-col">
                    <TabsContent value="general" className="m-0 mt-0 flex-1 overflow-y-auto p-4 sm:p-5">
                        <ClientFormGeneralSection form={form} setForm={setForm} t={t} />
                    </TabsContent>
                    <TabsContent value="location" className="m-0 mt-0 flex-1 overflow-y-auto p-4 sm:p-5">
                        <ClientFormLocationSection form={form} setForm={setForm} t={t} />
                    </TabsContent>
                    {canManageContacts ? (
                        <TabsContent value="contacts" className="m-0 mt-0 flex-1 overflow-y-auto p-4 sm:p-5">
                            <ClientFormContactsSection form={form} setForm={setForm} t={t} />
                        </TabsContent>
                    ) : null}
                    {canAssignAccountants ? (
                        <TabsContent value="accountants" className="m-0 mt-0 flex-1 overflow-y-auto p-4 sm:p-5">
                            <ClientFormAccountantsSection form={form} setForm={setForm} accountants={accountants} t={t} />
                        </TabsContent>
                    ) : null}
                </div>
            </Tabs>
        );

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent
                showCloseButton={false}
                side="right"
                className="h-full w-full gap-0 border-l p-0 sm:max-w-xl lg:max-w-3xl"
            >
                <SheetHeader className="shrink-0 flex-row items-start justify-between gap-4 border-b border-border px-4 py-4">
                    <div className="min-w-0 space-y-1">
                        <SheetTitle className="text-lg">{title}</SheetTitle>
                        <SheetDescription>{t('clients.admin_form.sheet.description')}</SheetDescription>
                    </div>
                    <SheetClose
                        className={cn(
                            'inline-flex h-10 w-10 shrink-0 cursor-pointer items-center justify-center rounded-full text-muted-foreground transition-colors',
                            'hover:bg-muted/60 hover:text-foreground',
                            'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
                        )}
                    >
                        <Icon icon="material-symbols:close" className="size-5" />
                        <span className="sr-only">{t('clients.admin_form.sheet.close_sr')}</span>
                    </SheetClose>
                </SheetHeader>

                <div className="flex min-h-0 flex-1 flex-col overflow-hidden">
                    {lookupSuccess && step === 'form' ? (
                        <div className="shrink-0 border-b border-border px-4 py-3 sm:px-5">
                            <div className="flex items-center gap-2 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-800 dark:border-green-800 dark:bg-green-950 dark:text-green-300">
                                <Icon icon="material-symbols:check-circle-outline" className="size-4 shrink-0" />
                                {t('clients.admin_form.anaf_lookup.found_hint')}
                            </div>
                        </div>
                    ) : errorBanner ? (
                        <div className="shrink-0 border-b border-border px-4 py-3 sm:px-5">{errorBanner}</div>
                    ) : null}
                    <div className="flex min-h-0 flex-1 flex-col overflow-hidden">
                        {step === 'lookup' ? lookupBody : sheetBody}
                    </div>
                </div>

                <SheetFooter className="shrink-0 flex-row justify-end gap-2 border-t border-border bg-background px-4 py-4">
                    <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
                        {t('clients.admin_form.footer.cancel')}
                    </Button>
                    {step === 'form' ? (
                        <LoadingButton
                            type="button"
                            loading={submitting}
                            loadingPosition="end"
                            disabled={mode === 'edit' && !client}
                            onClick={submit}
                        >
                            {mode === 'create' ? t('clients.admin_form.footer.create') : t('clients.admin_form.footer.save')}
                        </LoadingButton>
                    ) : null}
                </SheetFooter>
            </SheetContent>
        </Sheet>
    );
}
