// -----------------------------------------------------------------------------
// Lou-Ka — Agrégateur de logements à louer (province de Québec)
// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
// fiche/NeighborhoodStats.tsx : « Quartier » — KPI compacts du recensement
// (aire de diffusion), accessibilité StatCan en lignes compactes (4 par
// défaut + « Voir tous les indicateurs »), îlot de chaleur, criminalité
// (résumé + détail par catégorie en accordéon), sources.
// -----------------------------------------------------------------------------
import { useState } from "react";
import { Quartier } from "../api";
import { IcoUsers } from "../components/Icons";
import { Accordion, MoreButton, SectionCard, SourceLine, StatTile, StatusBadge, NBSP } from "./ui";
const fmtMoney = (v: number | null | undefined) => (v == null ? null : `${Math.round(v / 1000)}${NBSP}k$`);
const fmtPct = (v: number | null | undefined) => (v == null ? null : `${Math.round(v)}${NBSP}%`);
const PROX: [string, string][] = [
["prox_epicerie", "Épiceries"], ["prox_transport", "Transport"], ["prox_pharmacie", "Pharmacies"],
["prox_parc", "Parcs"], ["prox_ecole_prim", "Écoles primaires"], ["prox_ecole_sec", "Écoles secondaires"],
["prox_sante", "Soins de santé"], ["prox_garderie", "Garderies"], ["prox_bibliotheque", "Bibliothèques"],
["prox_emploi", "Emplois"],
];
const niveau = (v: number) => (v >= 90 ? ["Excellent", "good"] : v >= 70 ? ["Très bon", "good"] : v >= 45 ? ["Moyen", "warn"] : ["Faible", "bad"]) as [string, string];
export default function NeighborhoodStats({ q }: { q: Quartier }) {
const [all, setAll] = useState(false);
const d = q.demographie;
const kpis: [string, string | null][] = d ? [
["Revenu médian", fmtMoney(d.revenu_median)],
["Locataires", fmtPct(d.pct_locataires)],
["Loyer moyen 2021", d.loyer_moyen != null ? `${Math.round(d.loyer_moyen).toLocaleString("fr-CA")}${NBSP}$` : null],
["Âge médian", d.age_median != null ? `${Math.round(d.age_median)} ans` : null],
["Français à la maison", fmtPct(d.pct_francais)],
["Universitaires", fmtPct(d.pct_univ)],
] : [];
const kpisOk = kpis.filter(([, v]) => v != null) as [string, string][];
const prox = q.proximite ?? {};
const proxOk = PROX.filter(([k]) => typeof prox[k] === "number")
.map(([k, l]) => [l, Math.round(Math.max(0, Math.min(1, prox[k])) * 100)] as [string, number]);
const shown = all ? proxOk : proxOk.slice(0, 4);
const crime = q.crime;
if (kpisOk.length === 0 && proxOk.length === 0 && !q.chaleur && !crime) return null;
return (
Actes criminels enregistrés par le SPVM (données ouvertes, position approximée à l'intersection) — 12 derniers mois vs les 12 précédents.
Indice de gravité de la criminalité (Statistique Canada) — {crime.ville}, {crime.annee} : {crime.indice}{crime.indice_canada != null ? ` · Canada : ${crime.indice_canada}` : ""}.
)}