import { Link } from '@inertiajs/react';
import { useId, useState } from 'react';
import { FaqAccordion, type Faq } from '@/components/marketing/faq-accordion';
import {
    MarketingPackageCard,
    PricingPackageCard,
    formatPackagePrice,
    packageCreditPrice,
    type PricingPackage,
} from '@/components/marketing/package-card';
import { useCreditRule } from '@/hooks/use-credit-rule';
import MarketingLayout from '@/layouts/marketing-layout';
import {
    type CreditRule,
    classroomHours,
    creditCost,
    creditsLabel,
    parseCount,
    recommendPlan,
} from '@/lib/credits';
import { formatEuro, formatHours } from '@/lib/format';
import { register } from '@/routes';

type Props = {
    /** Piani in abbonamento (mensili). */
    packages: PricingPackage[];
    /** Ricariche una tantum. */
    topups?: PricingPackage[];
};

/* -------------------------------------------------------------------------
 * Classi condivise (vedi resources/js/pages/marketing/home.tsx)
 * ---------------------------------------------------------------------- */

const container = 'mx-auto w-full max-w-[72rem] px-6';
const section = 'py-12 sm:py-16';

const focusRing =
    'rounded-marketing-sm outline-marketing-primary focus-visible:outline-2 focus-visible:outline-offset-2';

const primaryButton = `inline-flex items-center justify-center rounded-marketing-sm bg-marketing-primary px-5 py-3 text-[0.9375rem] leading-none font-medium text-marketing-primary-foreground transition-colors hover:bg-marketing-primary-hover ${focusRing}`;

const sectionTitle =
    'font-display text-[1.75rem] leading-[1.15] font-bold tracking-[-0.005em] sm:text-[2.25rem]';

const lead =
    'max-w-[38rem] text-[1.125rem] leading-[1.55] text-marketing-ink/80 sm:text-[1.25rem]';

/* -------------------------------------------------------------------------
 * Il costo del problema (docs/marketing/analisi-strategia-pricing.md §3.5,
 * §3.7): è l'ancora con cui il visitatore deve leggere i prezzi.
 * ---------------------------------------------------------------------- */

/** Ore amministrative per corso: registro, calendario e relazione. */
const ADMIN_HOURS_PER_COURSE = 1.4;

/** Costo aziendale di un'ora di lavoro amministrativo, in centesimi. */
const ADMIN_HOURLY_CENTS = 2500;

/** Il piano di riferimento in vetrina: preselezionato anche in onboarding. */
const FEATURED_SLUG = 'pro';

/** Il piano che si chiude su preventivo: prezzo "da", contratto annuale. */
const QUOTED_SLUG = 'enterprise';

/* -------------------------------------------------------------------------
 * Confronto tra piani
 * ---------------------------------------------------------------------- */

type ComparisonRow = {
    label: string;
    value: (pkg: PricingPackage) => string;
    mono: boolean;
};

function comparisonRows(rule: Required<CreditRule>): ComparisonRow[] {
    // Il corso di riferimento: 8 ore, discenti entro la fascia base.
    const standardCourseCost = creditCost(rule.participantsBand, 8, rule);

    return [
        {
            label: 'Crediti al mese',
            value: (pkg) => `${pkg.credits}`,
            mono: true,
        },
        {
            label: "Ore d'aula al mese",
            value: (pkg) =>
                `${classroomHours(pkg.credits, rule.hoursPerCredit)}`,
            mono: true,
        },
        {
            label: 'Costo per credito',
            value: (pkg) => packageCreditPrice(pkg).replace(' a credito', ''),
            mono: true,
        },
        {
            label: 'Corsi da 8 ore al mese',
            value: (pkg) =>
                standardCourseCost > 0
                    ? `${Math.floor(pkg.credits / standardCourseCost)}`
                    : '—',
            mono: true,
        },
        {
            label: 'Ricariche una tantum',
            value: () => 'Disponibili',
            mono: false,
        },
        {
            label: 'Registro presenze CSV',
            value: () => 'Incluso',
            mono: false,
        },
        {
            label: 'Invio a Forma.Temp',
            value: () => 'Incluso',
            mono: false,
        },
        {
            label: 'Assistente AI',
            value: () => 'Incluso',
            mono: false,
        },
        {
            label: 'Supporto',
            value: () => 'Email',
            mono: false,
        },
    ];
}

/* -------------------------------------------------------------------------
 * Calcolatore: corsi al mese → euro al mese
 * ---------------------------------------------------------------------- */

const calcInput =
    'w-20 rounded-marketing-sm border border-marketing-ink/25 bg-marketing-surface px-3 py-2 text-[0.9375rem] text-marketing-ink outline-marketing-primary focus-visible:outline-2 focus-visible:outline-offset-2';

const calcLabel = 'text-marketing-ink/70 text-sm';

function CalcField({
    id,
    label,
    hint,
    value,
    onChange,
}: {
    id: string;
    label: string;
    hint?: string;
    value: string;
    onChange: (value: string) => void;
}) {
    const hintId = `${id}-hint`;

    return (
        <div className="flex flex-col gap-2">
            <label htmlFor={id} className={calcLabel}>
                {label}
            </label>
            <input
                id={id}
                type="number"
                inputMode="numeric"
                min={1}
                step={1}
                value={value}
                onChange={(e) => onChange(e.target.value)}
                // Senza questo la nota resta muta per chi usa uno screen reader:
                // la legge solo chi vede il paragrafo accanto al campo.
                aria-describedby={hint ? hintId : undefined}
                className={calcInput}
            />
            {hint && (
                <p
                    id={hintId}
                    className="text-marketing-ink/50 max-w-[14rem] text-[0.8125rem] leading-[1.4]"
                >
                    {hint}
                </p>
            )}
        </div>
    );
}

function ResultRow({ label, value }: { label: string; value: string }) {
    return (
        <div className="border-marketing-border flex items-baseline justify-between gap-4 border-t pt-2">
            <span className="text-marketing-ink/70 text-sm">{label}</span>
            <span className="marketing-data text-[0.9375rem]">{value}</span>
        </div>
    );
}

/**
 * Il visitatore sa quanti corsi fa e quanto durano; non sa quanti crediti
 * sono. Il calcolatore parte da quello che sa e restituisce quello che deve
 * decidere: quanto paga al mese, con quale piano, e quanto gli costa un corso.
 */
function PlanCalculator({
    plans,
    topups,
    rule,
}: {
    plans: PricingPackage[];
    topups: PricingPackage[];
    rule: Required<CreditRule>;
}) {
    const [courses, setCourses] = useState('4');
    const [hours, setHours] = useState('8');
    const [participants, setParticipants] = useState('20');

    const coursesId = useId();
    const hoursId = useId();
    const participantsId = useId();

    const coursesPerMonth = parseCount(courses);
    const hoursPerCourse = parseCount(hours);
    const peoplePerCourse = parseCount(participants);

    const costPerCourse = creditCost(peoplePerCourse, hoursPerCourse, rule);
    const creditsPerMonth = costPerCourse * coursesPerMonth;
    const recommendation = recommendPlan(
        creditsPerMonth,
        plans,
        topups,
        coursesPerMonth,
    );

    const adminHours = coursesPerMonth * ADMIN_HOURS_PER_COURSE;
    const adminCents = Math.round(adminHours * ADMIN_HOURLY_CENTS);

    const planLine = recommendation
        ? recommendation.topup && recommendation.topupCount > 0
            ? `${recommendation.plan.name} + ${recommendation.topupCount} × ${recommendation.topup.name}`
            : recommendation.plan.name
        : null;

    // Nessuna combinazione copre il fabbisogno: il numero che mostreremmo non sarebbe
    // il prezzo di quello che serve, quindi non lo mostriamo.
    const short = recommendation?.short ?? false;

    // Il piano che si chiude su preventivo ha un prezzo "da": vale nella card e vale qui,
    // altrimenti il calcolatore promette una cifra che la trattativa non rispetta.
    const quoted = recommendation?.plan.slug === QUOTED_SLUG;

    return (
        <div className="rounded-marketing bg-marketing-surface border-marketing-border max-w-[42rem] border p-6">
            <div className="flex flex-wrap items-start gap-x-6 gap-y-4">
                <CalcField
                    id={coursesId}
                    label="Corsi al mese"
                    value={courses}
                    onChange={setCourses}
                />
                <CalcField
                    id={hoursId}
                    label="Ore per corso"
                    value={hours}
                    onChange={setHours}
                />
                <CalcField
                    id={participantsId}
                    label="Discenti per corso"
                    hint={`Entro i ${rule.participantsBand} il prezzo non cambia: serve solo se le tue aule sono più grandi.`}
                    value={participants}
                    onChange={setParticipants}
                />
            </div>

            {/* La regione resta montata: un aria-live che compare insieme al suo
                contenuto non viene annunciato la prima volta. */}
            <div className="mt-8" aria-live="polite">
                {creditsPerMonth > 0 && recommendation ? (
                    <>
                        {short ? (
                            <p className="font-display max-w-[32rem] text-[1.0625rem] leading-[1.45] font-semibold">
                                Questo volume supera il piano più grande:
                                contattaci per un contratto su misura.
                            </p>
                        ) : (
                            <p className="flex flex-wrap items-baseline gap-x-2">
                                {quoted && (
                                    <span className="text-marketing-ink/60 text-[0.9375rem]">
                                        da
                                    </span>
                                )}
                                <span className="marketing-data text-[2rem] leading-none">
                                    {formatPackagePrice(
                                        recommendation.monthlyCents,
                                    )}
                                </span>
                                <span className="text-marketing-ink/70 text-[0.9375rem]">
                                    al mese con {planLine}
                                </span>
                            </p>
                        )}

                        <div className="mt-5 flex flex-col gap-2">
                            <ResultRow
                                label="Crediti al mese"
                                value={creditsLabel(creditsPerMonth)}
                            />
                            {!short && (
                                <ResultRow
                                    label="Costo di un corso"
                                    value={
                                        recommendation.perCourseCents !== null
                                            ? `${quoted ? 'da ' : ''}${formatEuro(
                                                  recommendation.perCourseCents,
                                              )}`
                                            : '—'
                                    }
                                />
                            )}
                            <ResultRow
                                label={
                                    short
                                        ? `Crediti compresi in ${recommendation.plan.name}`
                                        : 'Crediti compresi nel piano'
                                }
                                value={creditsLabel(
                                    recommendation.creditsCovered,
                                )}
                            />
                        </div>

                        <p className="text-marketing-ink/70 border-marketing-border mt-5 border-t pt-4 text-sm leading-[1.55]">
                            Gli stessi {coursesPerMonth} corsi ti costano oggi
                            circa{' '}
                            <span className="marketing-data">
                                {formatHours(adminHours)}
                            </span>{' '}
                            ore al mese fra registro, calendario e relazione: a
                            25 € l&apos;ora sono{' '}
                            {formatPackagePrice(adminCents)} di lavoro che non
                            fai più.
                        </p>
                    </>
                ) : (
                    <p className="text-marketing-ink/60 text-sm">
                        Metti i corsi che fai in un mese e la loro durata: ti
                        diciamo quanto paghi e con quale piano.
                    </p>
                )}
            </div>
        </div>
    );
}

/* -------------------------------------------------------------------------
 * FAQ (docs/marketing-copy.md §9)
 * ---------------------------------------------------------------------- */

function pricingFaqs(rule: Required<CreditRule>): Faq[] {
    return [
        {
            question: 'Come funziona un credito?',
            answer: `Un credito vale ${rule.hoursPerCredit} ore d'aula fino a ${rule.participantsBand} discenti: mezza giornata. Un corso da 8 ore con 20 discenti costa 2 crediti. Le ore si contano a scatti di ${rule.hoursPerCredit} e i discenti a fasce di ${rule.participantsBand}: lo stesso corso con 45 discenti costa 4 crediti.`,
        },
        {
            question: 'Devo dichiarare i discenti esatti?',
            answer: `No, e non conviene farlo al centesimo. Entro la fascia di ${rule.participantsBand} discenti il prezzo è lo stesso, quindi puoi impostare il limite dell'aula largo senza pagare di più.`,
        },
        {
            question: 'Come pago?',
            answer: 'Con carta, tramite Stripe. Il piano si rinnova ogni mese e le ricariche si pagano una volta sola, quando servono.',
        },
        {
            question: 'Cosa succede ai crediti che non uso?',
            answer: 'I crediti del piano non consumati passano al periodo successivo, fino a un massimo pari ai crediti che il piano accredita ogni mese. I crediti delle ricariche hanno una loro scadenza, indipendente dal piano.',
        },
        {
            question: 'Conviene comprare ricariche o salire di piano?',
            answer: 'Quasi sempre salire di piano: il credito di una ricarica costa più del credito del piano superiore. Se sfori tutti i mesi, il piano più grande costa meno della somma delle ricariche.',
        },
        {
            question: 'Posso cambiare piano?',
            answer: 'Sì, in qualsiasi momento dalla pagina crediti. Il cambio è immediato e Stripe calcola il conguaglio sul periodo già pagato.',
        },
        {
            question: 'Se cancello un’aula riprendo i crediti?',
            answer: "Sì, finché l'aula è in bozza: i crediti tornano sulle partite da cui erano stati presi, se non sono ancora scadute.",
        },
        {
            question: 'Le ricariche si possono rimborsare?',
            answer: "Le ricariche si acquistano e si consumano all'uso: una volta attivate non sono rimborsabili, salvo diversa indicazione.",
        },
        {
            question: 'Posso disdire?',
            answer: 'Sì. Disdici dal portale di fatturazione: il piano resta attivo fino alla fine del periodo già pagato e i crediti già accreditati restano utilizzabili.',
        },
        {
            question: 'Chi vede le registrazioni?',
            answer: 'Il registro presenze è visibile a chi amministra l’account dell’ente, con nome e orari di ogni discente, esportabile in CSV in qualsiasi momento.',
        },
    ];
}

export default function Pricing({ packages, topups }: Props) {
    const extras = topups ?? [];
    const rule = useCreditRule();
    const rows = comparisonRows(rule);
    const faqs = pricingFaqs(rule);

    return (
        <MarketingLayout title="Prezzi">
            {/* Titolo */}
            <section className={`${container} pt-12 pb-4 sm:pt-16`}>
                <h1 className={sectionTitle}>
                    Un piano al mese, un solo numero da guardare
                </h1>
                <p className={`mt-5 ${lead}`}>
                    Il piano accredita crediti ogni mese e un&apos;aula li
                    consuma in base a quanto dura e a quanti discenti ospita. Il
                    cambio è uno solo, e si impara in una volta.
                </p>
                <p className="border-marketing-border marketing-data mt-6 max-w-[38rem] border-t border-b py-4 text-[1.0625rem] leading-[1.5] sm:text-[1.25rem]">
                    1 credito = {rule.hoursPerCredit} ore d&apos;aula fino a{' '}
                    {rule.participantsBand} discenti
                </p>
                <p className="text-marketing-ink/70 mt-4 max-w-[38rem] text-[0.9375rem] leading-[1.55]">
                    Mezza giornata. Le ore si contano a scatti di{' '}
                    {rule.hoursPerCredit}, i discenti a fasce di{' '}
                    {rule.participantsBand}.
                </p>
            </section>

            {/* Piani */}
            <section className={`${container} pt-8 pb-12 sm:pb-16`}>
                {packages.length === 0 ? (
                    <p className={lead}>
                        I piani non sono disponibili in questo momento. Scrivici
                        e ti diamo i prezzi aggiornati.
                    </p>
                ) : (
                    <>
                        <p className="text-marketing-ink/70 border-marketing-border mx-auto mb-10 max-w-[64rem] border-t pt-4 text-[0.9375rem] leading-[1.55]">
                            Un corso costa a un ente circa{' '}
                            <span className="marketing-data">
                                {formatHours(ADMIN_HOURS_PER_COURSE)}
                            </span>{' '}
                            ore di lavoro amministrativo solo per registro,
                            calendario e relazione. I prezzi qui sotto si
                            leggono a partire da quella cifra.
                        </p>

                        {/* La cifra è una stima e va etichettata come tale. */}
                        <p className="text-marketing-ink/60 mx-auto -mt-8 mb-10 max-w-[64rem] text-[0.8125rem]">
                            Stima a partire dai tempi misurati sulle operazioni
                            che EasyForma automatizza.
                        </p>

                        <div className="mx-auto grid max-w-[64rem] items-stretch gap-6 sm:grid-cols-2 lg:grid-cols-3">
                            {packages.map((pkg) => (
                                <PricingPackageCard
                                    key={pkg.id}
                                    pkg={pkg}
                                    featured={pkg.slug === FEATURED_SLUG}
                                    priceFrom={pkg.slug === QUOTED_SLUG}
                                />
                            ))}
                        </div>
                        <p className="text-marketing-ink/60 mx-auto mt-6 max-w-[64rem] text-sm">
                            Prezzi IVA esclusa.
                        </p>
                    </>
                )}
            </section>

            {/* Calcolatore */}
            <section
                id="calcolatore"
                className={`${container} ${section} border-marketing-border scroll-mt-20 border-t`}
            >
                <h2 className={sectionTitle}>Quanto ti costa al mese.</h2>
                <p className={`mt-5 ${lead}`}>
                    Quanti corsi fai in un mese e quanto durano. Da lì ricaviamo
                    i crediti che ti servono, il piano che li copre e quanto ti
                    viene a costare un corso.
                </p>
                <div className="mt-8">
                    <PlanCalculator
                        plans={packages}
                        topups={extras}
                        rule={rule}
                    />
                </div>
            </section>

            {/* Ricariche */}
            {extras.length > 0 && (
                <section
                    id="ricariche"
                    className={`${container} ${section} border-marketing-border scroll-mt-20 border-t`}
                >
                    <h2 className={sectionTitle}>Ricariche.</h2>
                    <p className={`mt-5 ${lead}`}>
                        Crediti extra da comprare una volta sola, quando quelli
                        del mese non bastano. Se ti servono tutti i mesi, sali
                        di piano: costano meno.
                    </p>

                    <div
                        className={`mx-auto mt-10 grid items-stretch gap-6 sm:grid-cols-2 ${
                            extras.length > 2
                                ? 'max-w-[64rem] lg:grid-cols-3'
                                : 'max-w-[42rem]'
                        }`}
                    >
                        {extras.map((topup) => (
                            <MarketingPackageCard
                                key={topup.id}
                                pkg={topup}
                                featured={false}
                                heading="h3"
                                idPrefix="pricing-topup"
                            />
                        ))}
                    </div>
                </section>
            )}

            {/* Confronto */}
            {packages.length > 0 && (
                <section
                    className={`${container} ${section} border-marketing-border border-t`}
                >
                    <h2 className={sectionTitle}>Confronto tra piani.</h2>

                    <div className="mt-8 overflow-x-auto">
                        <table className="w-full min-w-[36rem] border-collapse">
                            <caption className="sr-only">
                                Confronto dettagliato tra i piani in abbonamento
                            </caption>
                            <thead>
                                <tr className="border-marketing-border border-b text-left">
                                    <th
                                        scope="col"
                                        className="text-marketing-ink/55 py-3 pr-4 text-[0.8125rem] font-medium"
                                    >
                                        Cosa include
                                    </th>
                                    {packages.map((pkg) => (
                                        <th
                                            key={pkg.id}
                                            scope="col"
                                            className="font-display py-3 pr-4 text-[0.9375rem] font-semibold"
                                        >
                                            {pkg.name}
                                        </th>
                                    ))}
                                </tr>
                            </thead>
                            <tbody>
                                {rows.map((row) => (
                                    <tr
                                        key={row.label}
                                        className="border-marketing-border border-b"
                                    >
                                        <th
                                            scope="row"
                                            className="py-3 pr-4 text-left text-[0.9375rem] font-medium"
                                        >
                                            {row.label}
                                        </th>
                                        {packages.map((pkg) => (
                                            <td
                                                key={pkg.id}
                                                className={`text-marketing-ink/80 py-3 pr-4 text-[0.9375rem] ${
                                                    row.mono
                                                        ? 'marketing-data'
                                                        : ''
                                                }`}
                                            >
                                                {row.value(pkg)}
                                            </td>
                                        ))}
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                </section>
            )}

            {/* FAQ prezzi */}
            <section
                className={`${container} ${section} border-marketing-border border-t`}
            >
                <h2 className={sectionTitle}>
                    Domande su prezzi e fatturazione.
                </h2>
                <div className="mt-8">
                    <FaqAccordion faqs={faqs} idPrefix="pricing-faq" />
                </div>
            </section>

            {/* CTA finale */}
            <section className="border-marketing-border bg-marketing-surface border-t">
                <div className={`${container} ${section}`}>
                    <h2 className={sectionTitle}>
                        Pronto a semplificare la prossima FAD sincrona?
                    </h2>
                    <p className={`mt-5 ${lead}`}>
                        Crea il tuo account, attiva un piano e apri la tua prima
                        aula in pochi minuti.
                    </p>
                    <Link href={register()} className={`mt-8 ${primaryButton}`}>
                        Crea il tuo account
                    </Link>
                </div>
            </section>
        </MarketingLayout>
    );
}
