import InputError from '@/Components/InputError';
import InputLabel from '@/Components/InputLabel';
import PrimaryButton from '@/Components/PrimaryButton';
import TextInput from '@/Components/TextInput';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { PageProps } from '@/types';
import { CompanyContract, Paginated } from '@/types/crm';
import { Head, Link, router, useForm } from '@inertiajs/react';
import { FormEventHandler, ReactNode, useState } from 'react';

type AvailableProposal = {
    id: number;
    company_id: number;
    reference: string;
    title: string;
    company: { id: number; name: string };
};

type Props = PageProps<{
    contracts: Paginated<CompanyContract>;
    companies: Array<{ id: number; name: string }>;
    proposals: AvailableProposal[];
    filters: { search: string; status: string };
    statusLabels: Record<string, string>;
    stats: {
        total: number;
        active: number;
        pending: number;
        ended: number;
        annualValue: number;
    };
    flash?: { success?: string | null };
}>;

export default function ContractsIndex({ contracts, companies, proposals, filters, statusLabels, stats, flash }: Props) {
    const [search, setSearch] = useState(filters.search);
    const [status, setStatus] = useState(filters.status);
    const form = useForm({
        company_id: companies[0]?.id.toString() ?? '',
        proposal_id: '',
        title: '',
        amount: '',
        billing_frequency: 'monthly',
        status: 'pending',
        signed_at: '',
        starts_at: '',
        ends_at: '',
        notes: '',
    });
    const relatedProposals = proposals.filter((proposal) => proposal.company_id.toString() === form.data.company_id);

    const filter: FormEventHandler = (event) => {
        event.preventDefault();
        router.get(route('contracts.index'), { search, status }, { preserveState: true });
    };
    const submit: FormEventHandler = (event) => {
        event.preventDefault();
        form.post(route('contracts.store'), { onSuccess: () => form.reset('proposal_id', 'title', 'amount', 'notes') });
    };

    return (
        <AuthenticatedLayout
            header={
                <div>
                    <h1 className="text-2xl font-bold text-[#062853]">Contrats</h1>
                    <p className="mt-1 text-sm text-slate-500">Suivi des engagements signés et de leur valeur active</p>
                </div>
            }
        >
            <Head title="Contrats" />
            <div className="mx-auto max-w-[1500px] space-y-5 px-4 py-5 sm:px-6 lg:px-7">
                {flash?.success && <Alert message={flash.success} />}
                <section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
                    <Metric label="Contrats" value={stats.total.toString()} tone="blue" />
                    <Metric label="En cours" value={stats.active.toString()} tone="green" />
                    <Metric label="En attente" value={stats.pending.toString()} tone="amber" />
                    <Metric label="Terminés" value={stats.ended.toString()} tone="purple" />
                    <Metric label="Valeur annualisée" value={currency(stats.annualValue)} tone="green" />
                </section>
                <div className="grid gap-5 xl:grid-cols-[340px_1fr]">
                    <form onSubmit={submit} className="space-y-4 rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
                        <h2 className="text-sm font-bold uppercase tracking-wide text-[#062853]">Créer un contrat</h2>
                        <Field label="Entreprise" htmlFor="contract_company">
                            <select
                                id="contract_company"
                                value={form.data.company_id}
                                onChange={(event) => form.setData((current) => ({ ...current, company_id: event.target.value, proposal_id: '' }))}
                                className="mt-1 w-full rounded-lg border-slate-200 text-sm"
                            >
                                {companies.map((company) => <option key={company.id} value={company.id}>{company.name}</option>)}
                            </select>
                        </Field>
                        <Field label="Devis associé" htmlFor="contract_proposal">
                            <select id="contract_proposal" value={form.data.proposal_id} onChange={(event) => form.setData('proposal_id', event.target.value)} className="mt-1 w-full rounded-lg border-slate-200 text-sm">
                                <option value="">Aucun devis lié</option>
                                {relatedProposals.map((proposal) => <option key={proposal.id} value={proposal.id}>{proposal.reference} - {proposal.title}</option>)}
                            </select>
                            <InputError message={form.errors.proposal_id} className="mt-1" />
                        </Field>
                        <Field label="Contrat" htmlFor="contract_title">
                            <TextInput id="contract_title" value={form.data.title} onChange={(event) => form.setData('title', event.target.value)} className="mt-1 w-full" />
                            <InputError message={form.errors.title} className="mt-1" />
                        </Field>
                        <div className="grid grid-cols-2 gap-3">
                            <Field label="Montant HT" htmlFor="contract_amount">
                                <TextInput id="contract_amount" type="number" min="0" step="0.01" value={form.data.amount} onChange={(event) => form.setData('amount', event.target.value)} className="mt-1 w-full" />
                                <InputError message={form.errors.amount} className="mt-1" />
                            </Field>
                            <Field label="Périodicité" htmlFor="contract_frequency">
                                <select id="contract_frequency" value={form.data.billing_frequency} onChange={(event) => form.setData('billing_frequency', event.target.value)} className="mt-1 w-full rounded-lg border-slate-200 text-sm">
                                    <option value="monthly">Mensuel</option>
                                    <option value="annual">Annuel</option>
                                    <option value="one_off">Forfait</option>
                                </select>
                            </Field>
                        </div>
                        <Field label="Statut" htmlFor="contract_status">
                            <select id="contract_status" value={form.data.status} onChange={(event) => form.setData('status', event.target.value)} className="mt-1 w-full rounded-lg border-slate-200 text-sm">
                                {Object.entries(statusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}
                            </select>
                        </Field>
                        <PrimaryButton disabled={form.processing}>Enregistrer le contrat</PrimaryButton>
                    </form>
                    <section className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
                        <form onSubmit={filter} className="flex flex-wrap justify-between gap-3 border-b border-slate-100 p-4">
                            <h2 className="self-center text-sm font-bold uppercase tracking-wide text-[#062853]">Liste des contrats</h2>
                            <div className="flex gap-2">
                                <TextInput value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Référence, contrat, client..." />
                                <select value={status} onChange={(event) => setStatus(event.target.value)} className="rounded-lg border-slate-200 text-sm">
                                    <option value="">Tous</option>
                                    {Object.entries(statusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}
                                </select>
                                <button className="rounded-lg bg-[#12529c] px-4 text-sm font-semibold text-white">Filtrer</button>
                            </div>
                        </form>
                        <div className="overflow-x-auto">
                            <table className="min-w-full text-sm">
                                <thead className="bg-slate-50 text-xs uppercase tracking-wide text-slate-500">
                                    <tr><th className="px-4 py-3 text-left">N° contrat</th><th className="px-4 py-3 text-left">Client</th><th className="px-4 py-3 text-left">Formule</th><th className="px-4 py-3 text-left">Montant</th><th className="px-4 py-3 text-left">Statut</th></tr>
                                </thead>
                                <tbody className="divide-y divide-slate-100">
                                    {contracts.data.length === 0 && <tr><td colSpan={5} className="px-4 py-12 text-center text-slate-500">Aucun contrat enregistré.</td></tr>}
                                    {contracts.data.map((contract) => (
                                        <tr key={contract.id}>
                                            <td className="px-4 py-4 font-medium text-blue-700">{contract.reference}</td>
                                            <td className="px-4 py-4">
                                                <Link href={route('companies.show', contract.company.id)} className="font-semibold text-slate-900">{contract.company.name}</Link>
                                                <p className="text-xs text-slate-500">{contract.title}</p>
                                            </td>
                                            <td className="px-4 py-4 text-slate-600">{frequencyLabel(contract.billing_frequency)}</td>
                                            <td className="px-4 py-4 font-semibold">{currency(Number(contract.amount))}</td>
                                            <td className="px-4 py-4"><StatusBadge value={contract.status} label={statusLabels[contract.status]} /></td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>
                    </section>
                </div>
            </div>
        </AuthenticatedLayout>
    );
}

function Field({ label, htmlFor, children }: { label: string; htmlFor: string; children: ReactNode }) {
    return <div><InputLabel htmlFor={htmlFor} value={label} />{children}</div>;
}

function Alert({ message }: { message: string }) {
    return <div className="rounded-lg border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-semibold text-emerald-700">{message}</div>;
}

function Metric({ label, value, tone }: { label: string; value: string; tone: string }) {
    const tones: Record<string, string> = { blue: 'text-blue-700', amber: 'text-amber-600', green: 'text-emerald-700', purple: 'text-violet-700' };
    return <div className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm"><p className="text-xs font-bold uppercase text-slate-500">{label}</p><p className={`mt-3 text-2xl font-bold ${tones[tone]}`}>{value}</p></div>;
}

function StatusBadge({ value, label }: { value: string; label: string }) {
    const styles: Record<string, string> = { pending: 'bg-amber-50 text-amber-700', active: 'bg-emerald-50 text-emerald-700', ended: 'bg-blue-50 text-blue-700', cancelled: 'bg-rose-50 text-rose-700' };
    return <span className={`rounded-full px-3 py-1 text-xs font-semibold ${styles[value]}`}>{label}</span>;
}

function frequencyLabel(value: string) {
    return ({ monthly: 'Abonnement mensuel', annual: 'Abonnement annuel', one_off: 'Forfait' } as Record<string, string>)[value] ?? value;
}

function currency(value: number) {
    return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(value);
}
