import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { PageProps } from '@/types';
import { Company } from '@/types/crm';
import { Head, Link, router } from '@inertiajs/react';
import franceDepartments from '@svg-maps/france.departments';

type Department = {
    code: string;
    companies: number;
    contacts: number;
    activities: number;
    contracts: number;
    potential: number;
};

type DepartmentMap = {
    viewBox: string;
    locations: Array<{
        id: string;
        name: string;
        path: string;
    }>;
};

type Props = PageProps<{
    departments: Department[];
    selectedDepartment: string;
    companies: Company[];
    stats: {
        companies: number;
        contacts: number;
        activities: number;
        customers: number;
        potential: number;
    };
}>;

const departmentMap = franceDepartments as DepartmentMap;
const departmentNames = new Map<string, string>(
    departmentMap.locations.map((location) => [location.id.toUpperCase(), location.name]),
);

export default function MapIndex({ departments, selectedDepartment, companies, stats }: Props) {
    const departmentByCode = new Map(departments.map((department) => [department.code, department]));
    const selectedSummary = departmentByCode.get(selectedDepartment);
    const maxCompanies = Math.max(...departments.map((department) => department.companies), 1);

    return (
        <AuthenticatedLayout
            header={
                <div>
                    <h1 className="text-2xl font-bold text-[#062853]">Carte de France</h1>
                    <p className="mt-1 text-sm text-slate-500">Suivi de la prospection par département</p>
                </div>
            }
        >
            <Head title="Carte de France" />
            <div className="mx-auto max-w-[1500px] space-y-5 px-4 py-5 sm:px-6 lg:px-7">
                <section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
                    <Metric label="Entreprises" value={number(stats.companies)} />
                    <Metric label="Contacts" value={number(stats.contacts)} />
                    <Metric label="Activités" value={number(stats.activities)} />
                    <Metric label="Clients" value={number(stats.customers)} />
                    <Metric label="Potentiel" value={currency(stats.potential)} />
                </section>

                <div className="grid gap-5 xl:grid-cols-[1fr_390px]">
                    <section className="overflow-hidden rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
                        <div className="flex flex-wrap items-start justify-between gap-4">
                            <div>
                                <h2 className="text-sm font-bold uppercase tracking-wide text-[#062853]">Carte départementale</h2>
                                <p className="mt-1 text-xs text-slate-500">Cliquez sur un département coloré pour consulter le détail</p>
                            </div>
                            <div className="flex flex-wrap items-center gap-3 text-[11px] font-medium text-slate-500">
                                <Legend color="bg-slate-200" label="Aucune donnée" />
                                <Legend color="bg-emerald-200" label="Faible" />
                                <Legend color="bg-emerald-500" label="Actif" />
                                <Legend color="bg-emerald-700" label="Fort" />
                            </div>
                        </div>

                        <div className="mt-5 rounded-xl bg-slate-50 px-3 py-6 sm:px-6">
                            <svg
                                aria-label="Carte départementale de France"
                                className="mx-auto h-auto w-full max-w-[680px]"
                                role="img"
                                viewBox={departmentMap.viewBox}
                            >
                                <title>Carte réelle des départements de France</title>
                                {departmentMap.locations.map((location) => {
                                    const code = location.id.toUpperCase();
                                    const department = departmentByCode.get(code);
                                    const isSelected = selectedDepartment === code;
                                    const pathClass = `transition ${
                                        isSelected
                                            ? 'fill-blue-700 stroke-blue-950 stroke-[2]'
                                            : department
                                              ? mapFillColor(department.companies, maxCompanies)
                                              : 'fill-slate-200 stroke-white stroke-[1]'
                                    }`;

                                    if (!department) {
                                        return (
                                            <path key={code} className={pathClass} d={location.path}>
                                                <title>{`${code} - ${location.name}`}</title>
                                            </path>
                                        );
                                    }

                                    return (
                                        <path
                                            key={code}
                                            aria-label={`${code} - ${location.name} : ${department.companies} entreprise(s)`}
                                            className={`${pathClass} cursor-pointer`}
                                            d={location.path}
                                            role="button"
                                            tabIndex={0}
                                            onClick={() => router.get(route('geography.index'), { department: code })}
                                            onKeyDown={(event) => {
                                                if (event.key === 'Enter' || event.key === ' ') {
                                                    event.preventDefault();
                                                    router.get(route('geography.index'), { department: code });
                                                }
                                            }}
                                        >
                                            <title>{`${code} - ${location.name} : ${department.companies} entreprise(s)`}</title>
                                        </path>
                                    );
                                })}
                            </svg>
                        </div>
                        {departments.length > 0 && (
                            <div className="mt-5 flex flex-wrap gap-2">
                                <span className="mr-1 py-2 text-xs font-bold uppercase text-slate-500">Départements actifs</span>
                                {departments.map((department) => (
                                    <button
                                        key={department.code}
                                        type="button"
                                        onClick={() => router.get(route('geography.index'), { department: department.code })}
                                        className={`rounded-lg border px-3 py-2 text-xs font-semibold ${
                                            selectedDepartment === department.code
                                                ? 'border-blue-700 bg-blue-700 text-white'
                                                : 'border-slate-200 bg-white text-[#062853] hover:border-blue-300'
                                        }`}
                                    >
                                        {department.code} - {departmentName(department.code)}
                                    </button>
                                ))}
                            </div>
                        )}
                        <p className="mt-4 text-[11px] text-slate-400">
                            Fond cartographique :{' '}
                            <a
                                href="https://github.com/VictorCazanave/svg-maps/tree/master/packages/france.departments"
                                target="_blank"
                                rel="noreferrer"
                                className="underline hover:text-slate-600"
                            >
                                SVG Maps - France Departments
                            </a>{' '}
                            (CC-BY-4.0).
                        </p>
                    </section>

                    <aside className="space-y-5">
                        <section className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
                            <div className="bg-[#062853] px-5 py-4 text-white">
                                <div className="flex items-center justify-between gap-3">
                                    <div>
                                        <h2 className="text-lg font-bold">
                                            {selectedDepartment ? `${selectedDepartment} - ${departmentName(selectedDepartment)}` : 'France entière'}
                                        </h2>
                                        <p className="text-xs text-blue-100">
                                            {selectedDepartment ? 'Détail du département sélectionné' : 'Synthèse nationale'}
                                        </p>
                                    </div>
                                    {selectedDepartment && (
                                        <Link href={route('geography.index')} className="rounded-full bg-white/15 px-3 py-1 text-xs font-semibold hover:bg-white/25">
                                            Réinitialiser
                                        </Link>
                                    )}
                                </div>
                            </div>
                            <div className="space-y-3 p-5 text-sm">
                                <Summary label="Entreprises" value={number(stats.companies)} />
                                <Summary label="Contacts" value={number(stats.contacts)} tone="text-emerald-700" />
                                <Summary label="Activités" value={number(stats.activities)} />
                                <Summary label="Clients" value={number(stats.customers)} tone="text-blue-700" />
                                <Summary label="Potentiel généré" value={currency(stats.potential)} tone="text-emerald-700" highlight />
                            </div>
                            {selectedSummary && (
                                <div className="border-t border-slate-100 px-5 py-4 text-xs text-slate-500">
                                    {number(selectedSummary.contracts)} contrat(s) suivi(s) sur cette zone
                                </div>
                            )}
                        </section>
                    </aside>
                </div>

                <section className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
                    <div className="flex items-center justify-between border-b border-slate-100 px-5 py-4">
                        <h2 className="text-sm font-bold uppercase tracking-wide text-[#062853]">
                            {selectedDepartment ? `Comptes suivis - ${selectedDepartment} - ${departmentName(selectedDepartment)}` : 'Derniers comptes suivis'}
                        </h2>
                        {selectedDepartment && <span className="rounded-full bg-blue-50 px-3 py-1 text-xs font-semibold text-blue-700">{companies.length} résultat(s)</span>}
                    </div>
                    <div className="divide-y divide-slate-100 md:grid md:grid-cols-2 md:divide-x md:divide-y-0 xl:grid-cols-3">
                        {companies.length === 0 && <p className="p-5 text-sm text-slate-500">Aucune entreprise dans cette zone.</p>}
                        {companies.map((company) => (
                            <Link key={company.id} href={route('companies.show', company.id)} className="block p-5 hover:bg-slate-50">
                                <p className="font-semibold text-slate-900">{company.name}</p>
                                <p className="mt-1 text-xs text-slate-500">{company.postal_code ?? '-'} {company.city ?? 'Ville non renseignée'}</p>
                                <p className="mt-3 text-xs font-medium text-emerald-700">{company.estimated_potential ? currency(Number(company.estimated_potential)) : 'Potentiel non renseigné'}</p>
                            </Link>
                        ))}
                    </div>
                </section>
            </div>
        </AuthenticatedLayout>
    );
}

function Metric({ label, value }: { label: string; value: string }) {
    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 text-[#062853]">{value}</p></div>;
}

function Legend({ color, label }: { color: string; label: string }) {
    return <span className="flex items-center gap-1.5"><span className={`h-3 w-3 rounded-sm ${color}`} />{label}</span>;
}

function Summary({ label, value, tone = 'text-slate-900', highlight = false }: { label: string; value: string; tone?: string; highlight?: boolean }) {
    return (
        <div className={`flex items-center justify-between rounded-lg px-3 py-2 ${highlight ? 'bg-emerald-50' : ''}`}>
            <span className="font-medium text-slate-500">{label}</span>
            <span className={`font-bold ${tone}`}>{value}</span>
        </div>
    );
}

function mapFillColor(companies: number, maxCompanies: number) {
    const ratio = companies / maxCompanies;

    if (ratio >= 0.75) {
        return 'fill-emerald-700 stroke-white stroke-[1] hover:fill-emerald-800';
    }

    if (ratio >= 0.4) {
        return 'fill-emerald-500 stroke-white stroke-[1] hover:fill-emerald-600';
    }

    return 'fill-emerald-200 stroke-white stroke-[1] hover:fill-emerald-300';
}

function departmentName(code: string) {
    return departmentNames.get(code) ?? `Département ${code}`;
}

function number(value: number) {
    return new Intl.NumberFormat('fr-FR').format(value);
}

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