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 { CompanyProposal, Paginated } from '@/types/crm';
import { Head, Link, router, useForm } from '@inertiajs/react';
import { FormEventHandler, ReactNode, useState } from 'react';

type Props = PageProps<{
    proposals: Paginated<CompanyProposal>;
    companies: Array<{ id: number; name: string }>;
    filters: { search: string; status: string };
    statusLabels: Record<string, string>;
    stats: {
        total: number;
        sent: number;
        accepted: number;
        rejected: number;
        pending: number;
        acceptedAmount: number;
    };
    flash?: { success?: string | null };
}>;

export default function ProposalsIndex({ proposals, companies, 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() ?? '',
        title: '',
        amount: '',
        status: 'draft',
        probability: '25',
        sent_at: '',
        accepted_at: '',
        expires_at: '',
        notes: '',
    });

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

    return (
        <AuthenticatedLayout
            header={
                <div>
                    <h1 className="text-2xl font-bold text-[#062853]">Devis &amp; Propositions</h1>
                    <p className="mt-1 text-sm text-slate-500">Suivi commercial des offres envoyées aux prospects</p>
                </div>
            }
        >
            <Head title="Devis & Propositions" />
            <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-6">
                    <Metric label="Total émis" value={stats.total.toString()} tone="blue" />
                    <Metric label="Envoyés" value={stats.sent.toString()} tone="amber" />
                    <Metric label="Acceptés" value={stats.accepted.toString()} tone="green" />
                    <Metric label="Refusés" value={stats.rejected.toString()} tone="rose" />
                    <Metric label="En attente" value={stats.pending.toString()} tone="purple" />
                    <Metric label="Accepté HT" value={currency(stats.acceptedAmount)} 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 devis</h2>
                        <Field label="Entreprise" htmlFor="proposal_company">
                            <select
                                id="proposal_company"
                                value={form.data.company_id}
                                onChange={(event) => form.setData('company_id', event.target.value)}
                                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>
                            <InputError message={form.errors.company_id} className="mt-1" />
                        </Field>
                        <Field label="Offre" htmlFor="proposal_title">
                            <TextInput id="proposal_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="proposal_amount">
                                <TextInput id="proposal_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="Probabilité %" htmlFor="proposal_probability">
                                <TextInput id="proposal_probability" type="number" min="0" max="100" value={form.data.probability} onChange={(event) => form.setData('probability', event.target.value)} className="mt-1 w-full" />
                            </Field>
                        </div>
                        <Field label="Statut" htmlFor="proposal_status">
                            <select id="proposal_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 devis</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 devis</h2>
                            <div className="flex gap-2">
                                <TextInput value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Référence, offre, 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° devis</th><th className="px-4 py-3 text-left">Client / offre</th><th className="px-4 py-3 text-left">Montant</th><th className="px-4 py-3 text-left">Statut</th><th className="px-4 py-3 text-left">Probabilité</th></tr>
                                </thead>
                                <tbody className="divide-y divide-slate-100">
                                    {proposals.data.length === 0 && <tr><td colSpan={5} className="px-4 py-12 text-center text-slate-500">Aucun devis enregistré.</td></tr>}
                                    {proposals.data.map((proposal) => (
                                        <tr key={proposal.id}>
                                            <td className="px-4 py-4 font-medium text-blue-700">{proposal.reference}</td>
                                            <td className="px-4 py-4">
                                                <Link href={route('companies.show', proposal.company.id)} className="font-semibold text-slate-900">{proposal.company.name}</Link>
                                                <p className="text-xs text-slate-500">{proposal.title}</p>
                                            </td>
                                            <td className="px-4 py-4 font-semibold">{currency(Number(proposal.amount))}</td>
                                            <td className="px-4 py-4"><StatusBadge value={proposal.status} label={statusLabels[proposal.status]} /></td>
                                            <td className="px-4 py-4"><Progress value={proposal.probability} /></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', rose: 'text-rose-600', 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> = { draft: 'bg-slate-100 text-slate-600', sent: 'bg-amber-50 text-amber-700', accepted: 'bg-emerald-50 text-emerald-700', rejected: 'bg-rose-50 text-rose-700' };
    return <span className={`rounded-full px-3 py-1 text-xs font-semibold ${styles[value]}`}>{label}</span>;
}

function Progress({ value }: { value: number }) {
    return <div className="w-28"><span className="text-xs font-semibold">{value}%</span><div className="mt-1 h-1.5 rounded bg-slate-100"><div className="h-1.5 rounded bg-emerald-500" style={{ width: `${value}%` }} /></div></div>;
}

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