import { Head, router, useForm } from '@inertiajs/react';
import type { FormEvent } from 'react';
import InputError from '@/components/input-error';
import PasswordInput from '@/components/password-input';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Card,
    CardContent,
    CardDescription,
    CardFooter,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Progress } from '@/components/ui/progress';
import { creditsLabel } from '@/lib/credits';
import { formatEuro } from '@/lib/format';
import { cn } from '@/lib/utils';
import onboarding from '@/routes/onboarding';
import type { Package } from '@/types';

type Step = 'company' | 'formatemp' | 'package';

type CompanyProfile = {
    name: string;
    vat_number: string | null;
    fiscal_code: string | null;
    address: string | null;
    city: string | null;
    zip: string | null;
    province: string | null;
    billing_email: string | null;
    sdi_code: string | null;
    pec: string | null;
    formatemp_username: string | null;
    formatemp_entity_code: string | null;
};

type Props = {
    step: Step;
    company: CompanyProfile;
    packages: Package[];
    selectedPackage: string | null;
    formatempConfigured: boolean;
};

const STEP_ORDER: Step[] = ['company', 'formatemp', 'package'];

const STEP_TITLES: Record<Step, string> = {
    company: "Profilo dell'ente",
    formatemp: 'Credenziali Forma.Temp',
    package: 'Scegli il piano',
};

const STEP_DESCRIPTIONS: Record<Step, string> = {
    company:
        'Dati anagrafici e di fatturazione del tuo ente di formazione. Potrai modificarli in qualsiasi momento dalle impostazioni.',
    formatemp:
        'Credenziali per inviare in automatico i dati delle aule a Forma.Temp. Puoi configurarle in un secondo momento.',
    package:
        'Il piano accredita i suoi crediti a ogni fattura pagata. 1 credito vale 4 ore d\u2019aula fino a 30 discenti: un corso da 8 ore costa 2 crediti.',
};

function SkipWizardLink() {
    return (
        <button
            type="button"
            onClick={() => router.post(onboarding.skip().url)}
            className="text-muted-foreground text-sm hover:underline"
        >
            Salta la configurazione
        </button>
    );
}

function WizardShell({
    step,
    children,
}: {
    step: Step;
    children: React.ReactNode;
}) {
    const stepIndex = STEP_ORDER.indexOf(step);

    return (
        <>
            <Head title="Configurazione guidata" />

            <div className="mx-auto flex w-full max-w-2xl flex-1 flex-col gap-6 p-4">
                <div className="space-y-2">
                    <p className="text-muted-foreground text-sm">
                        Passo {stepIndex + 1} di {STEP_ORDER.length}
                    </p>
                    <Progress
                        value={((stepIndex + 1) / STEP_ORDER.length) * 100}
                    />
                </div>

                <Card>
                    <CardHeader>
                        <CardTitle>{STEP_TITLES[step]}</CardTitle>
                        <CardDescription>
                            {STEP_DESCRIPTIONS[step]}
                        </CardDescription>
                    </CardHeader>
                    {children}
                </Card>
            </div>
        </>
    );
}

function CompanyStep({ company }: { company: CompanyProfile }) {
    const form = useForm({
        step: 'company' as const,
        name: company.name ?? '',
        vat_number: company.vat_number ?? '',
        fiscal_code: company.fiscal_code ?? '',
        address: company.address ?? '',
        city: company.city ?? '',
        zip: company.zip ?? '',
        province: company.province ?? '',
        billing_email: company.billing_email ?? '',
        sdi_code: company.sdi_code ?? '',
        pec: company.pec ?? '',
    });

    function submit(e: FormEvent) {
        e.preventDefault();
        form.post(onboarding.store().url);
    }

    return (
        <form onSubmit={submit}>
            <CardContent className="space-y-6">
                <div className="grid gap-2">
                    <Label htmlFor="name">Ragione sociale</Label>
                    <Input
                        id="name"
                        required
                        value={form.data.name}
                        onChange={(e) => form.setData('name', e.target.value)}
                        placeholder="Nome ente / azienda"
                    />
                    <InputError message={form.errors.name} />
                </div>

                <div className="grid gap-4 sm:grid-cols-2">
                    <div className="grid gap-2">
                        <Label htmlFor="vat_number">Partita IVA</Label>
                        <Input
                            id="vat_number"
                            value={form.data.vat_number}
                            onChange={(e) =>
                                form.setData('vat_number', e.target.value)
                            }
                        />
                        <InputError message={form.errors.vat_number} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="fiscal_code">Codice fiscale</Label>
                        <Input
                            id="fiscal_code"
                            value={form.data.fiscal_code}
                            onChange={(e) =>
                                form.setData('fiscal_code', e.target.value)
                            }
                        />
                        <InputError message={form.errors.fiscal_code} />
                    </div>
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="address">Indirizzo</Label>
                    <Input
                        id="address"
                        value={form.data.address}
                        onChange={(e) =>
                            form.setData('address', e.target.value)
                        }
                    />
                    <InputError message={form.errors.address} />
                </div>

                <div className="grid gap-4 sm:grid-cols-4">
                    <div className="grid gap-2 sm:col-span-2">
                        <Label htmlFor="city">Città</Label>
                        <Input
                            id="city"
                            value={form.data.city}
                            onChange={(e) =>
                                form.setData('city', e.target.value)
                            }
                        />
                        <InputError message={form.errors.city} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="zip">CAP</Label>
                        <Input
                            id="zip"
                            value={form.data.zip}
                            onChange={(e) =>
                                form.setData('zip', e.target.value)
                            }
                        />
                        <InputError message={form.errors.zip} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="province">Provincia</Label>
                        <Input
                            id="province"
                            value={form.data.province}
                            onChange={(e) =>
                                form.setData('province', e.target.value)
                            }
                        />
                        <InputError message={form.errors.province} />
                    </div>
                </div>

                <div className="grid gap-4 sm:grid-cols-2">
                    <div className="grid gap-2">
                        <Label htmlFor="billing_email">
                            Email fatturazione
                        </Label>
                        <Input
                            id="billing_email"
                            type="email"
                            value={form.data.billing_email}
                            onChange={(e) =>
                                form.setData('billing_email', e.target.value)
                            }
                        />
                        <InputError message={form.errors.billing_email} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="sdi_code">Codice SDI</Label>
                        <Input
                            id="sdi_code"
                            value={form.data.sdi_code}
                            onChange={(e) =>
                                form.setData('sdi_code', e.target.value)
                            }
                        />
                        <InputError message={form.errors.sdi_code} />
                    </div>
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="pec">PEC</Label>
                    <Input
                        id="pec"
                        type="email"
                        value={form.data.pec}
                        onChange={(e) => form.setData('pec', e.target.value)}
                    />
                    <InputError message={form.errors.pec} />
                </div>
            </CardContent>

            <CardFooter className="flex items-center justify-between gap-4">
                <SkipWizardLink />
                <Button type="submit" disabled={form.processing}>
                    Continua
                </Button>
            </CardFooter>
        </form>
    );
}

function FormatempStep({
    company,
    formatempConfigured,
}: {
    company: CompanyProfile;
    formatempConfigured: boolean;
}) {
    const form = useForm({
        step: 'formatemp' as const,
        formatemp_username: company.formatemp_username ?? '',
        formatemp_password: '',
        formatemp_entity_code: company.formatemp_entity_code ?? '',
    });

    function submit(e: FormEvent) {
        e.preventDefault();
        form.post(onboarding.store().url);
    }

    function later() {
        router.post(onboarding.store().url, { step: 'formatemp' });
    }

    return (
        <form onSubmit={submit}>
            <CardContent className="space-y-6">
                {formatempConfigured && (
                    <Badge variant="secondary">
                        Credenziali già configurate
                    </Badge>
                )}

                <div className="grid gap-2">
                    <Label htmlFor="formatemp_username">Nome utente</Label>
                    <Input
                        id="formatemp_username"
                        value={form.data.formatemp_username}
                        onChange={(e) =>
                            form.setData('formatemp_username', e.target.value)
                        }
                    />
                    <InputError message={form.errors.formatemp_username} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="formatemp_password">Password</Label>
                    <PasswordInput
                        id="formatemp_password"
                        autoComplete="new-password"
                        value={form.data.formatemp_password}
                        onChange={(e) =>
                            form.setData('formatemp_password', e.target.value)
                        }
                        placeholder={
                            formatempConfigured
                                ? '••••••• (lascia vuoto per non modificare)'
                                : ''
                        }
                    />
                    <InputError message={form.errors.formatemp_password} />
                </div>

                <div className="grid gap-2">
                    <Label htmlFor="formatemp_entity_code">Codice ente</Label>
                    <Input
                        id="formatemp_entity_code"
                        value={form.data.formatemp_entity_code}
                        onChange={(e) =>
                            form.setData(
                                'formatemp_entity_code',
                                e.target.value,
                            )
                        }
                    />
                    <InputError message={form.errors.formatemp_entity_code} />
                </div>
            </CardContent>

            <CardFooter className="flex items-center justify-between gap-4">
                <SkipWizardLink />
                <div className="flex items-center gap-3">
                    <Button
                        type="button"
                        variant="outline"
                        onClick={later}
                        disabled={form.processing}
                    >
                        Lo farò dopo
                    </Button>
                    <Button type="submit" disabled={form.processing}>
                        Continua
                    </Button>
                </div>
            </CardFooter>
        </form>
    );
}

/** "40 crediti al mese", con periodo corretto. */
function planCreditsLine(pkg: Package): string {
    const period = pkg.interval === 'year' ? "all'anno" : 'al mese';

    return `${creditsLabel(pkg.credits)} ${period}`;
}

function PackageStep({
    packages,
    selectedPackage,
}: {
    packages: Package[];
    selectedPackage: string | null;
}) {
    function choose(slug: string) {
        router.post(onboarding.store().url, { step: 'package', slug });
    }

    return (
        <>
            <CardContent className="space-y-4">
                {packages.length === 0 ? (
                    <p className="text-muted-foreground text-sm">
                        Nessun piano disponibile al momento. Potrai attivarne
                        uno in seguito dalla sezione piano e crediti.
                    </p>
                ) : (
                    <div className="grid gap-4 sm:grid-cols-2">
                        {packages.map((pkg) => {
                            const isSelected = selectedPackage === pkg.slug;

                            return (
                                <Card
                                    key={pkg.id}
                                    className={cn(
                                        'flex flex-col',
                                        isSelected &&
                                            'border-primary ring-primary/20 ring-2',
                                    )}
                                >
                                    <CardHeader>
                                        <div className="flex items-center justify-between gap-2">
                                            <CardTitle className="text-base">
                                                {pkg.name}
                                            </CardTitle>
                                            {isSelected && (
                                                <Badge>Selezionato</Badge>
                                            )}
                                        </div>
                                    </CardHeader>
                                    <CardContent className="flex-1 space-y-1">
                                        <p className="tabular-nums">
                                            <span className="text-2xl font-bold">
                                                {formatEuro(pkg.price_cents)}
                                            </span>
                                            <span className="text-muted-foreground ml-1 text-sm">
                                                {pkg.interval === 'year'
                                                    ? '/anno'
                                                    : '/mese'}
                                            </span>
                                        </p>
                                        {!pkg.description?.startsWith(
                                            creditsLabel(pkg.credits),
                                        ) && (
                                            <p className="text-sm">
                                                {planCreditsLine(pkg)}
                                            </p>
                                        )}
                                        {pkg.description && (
                                            <p className="text-muted-foreground text-sm">
                                                {pkg.description}
                                            </p>
                                        )}
                                    </CardContent>
                                    <CardFooter>
                                        <Button
                                            className="w-full"
                                            variant={
                                                isSelected
                                                    ? 'secondary'
                                                    : 'default'
                                            }
                                            onClick={() => choose(pkg.slug)}
                                        >
                                            Continua con {pkg.name}
                                        </Button>
                                    </CardFooter>
                                </Card>
                            );
                        })}
                    </div>
                )}
            </CardContent>

            <CardFooter className="flex items-center justify-between gap-4">
                <SkipWizardLink />
            </CardFooter>
        </>
    );
}

export default function OnboardingIndex({
    step,
    company,
    packages,
    selectedPackage,
    formatempConfigured,
}: Props) {
    return (
        <WizardShell step={step}>
            {step === 'company' && <CompanyStep company={company} />}
            {step === 'formatemp' && (
                <FormatempStep
                    company={company}
                    formatempConfigured={formatempConfigured}
                />
            )}
            {step === 'package' && (
                <PackageStep
                    packages={packages}
                    selectedPackage={selectedPackage}
                />
            )}
        </WizardShell>
    );
}
