// cloud/repository.jsx — Vue répertoire des soumissions

const { useState: useStateRepo, useEffect: useEffectRepo, useMemo: useMemoRepo, useCallback: useCallbackRepo } = React;

// ═══════════════════════════════════════════════════════════════════
// Repository — vue principale du répertoire (table + filtres)
// ═══════════════════════════════════════════════════════════════════
function Repository({ profile, isAdmin, onOpen, onNew }) {
  const [rows, setRows] = useStateRepo([]);
  const [loading, setLoading] = useStateRepo(true);
  const [err, setErr] = useStateRepo(null);
  const [search, setSearch] = useStateRepo("");
  const [statusFilter, setStatusFilter] = useStateRepo("all");
  const [creatorFilter, setCreatorFilter] = useStateRepo("all");
  const [creators, setCreators] = useStateRepo([]);

  const reload = useCallbackRepo(() => {
    setLoading(true);
    setErr(null);
    const filters = {};
    if (statusFilter !== "all")  filters.status = statusFilter;
    if (creatorFilter !== "all") filters.creator_id = creatorFilter;
    return window.RaycastDB.listSubmissions(filters)
      .then(setRows)
      .catch((e) => setErr(e.message || String(e)))
      .finally(() => setLoading(false));
  }, [statusFilter, creatorFilter]);

  useEffectRepo(() => { reload(); }, [reload]);
  useEffectRepo(() => {
    window.RaycastDB.listProfiles().then(setCreators).catch(() => {});
  }, []);

  // Filtrage texte côté client (rapide pour < 500 lignes)
  const filtered = useMemoRepo(() => {
    if (!search.trim()) return rows;
    const q = search.toLowerCase();
    return rows.filter(r =>
      (r.number || "").toLowerCase().includes(q) ||
      (r.client_name || "").toLowerCase().includes(q) ||
      (r.client_city || "").toLowerCase().includes(q) ||
      (r.creator_name || "").toLowerCase().includes(q)
    );
  }, [rows, search]);

  // Stats agrégées
  const stats = useMemoRepo(() => {
    const total = rows.length;
    const sent  = rows.filter(r => r.status === "envoye" || r.status === "accepte").length;
    const accepted = rows.filter(r => r.status === "accepte").length;
    const value = rows.reduce((s, r) => s + (Number(r.price_total) || 0), 0);
    return { total, sent, accepted, value };
  }, [rows]);

  const { fmtCAD0 } = window.RAYCAST_CALC || { fmtCAD0: v => `${Math.round(v||0).toLocaleString("fr-CA")} $` };

  return (
    <div style={repoCss.root}>
      {/* Header */}
      <div style={repoCss.header}>
        <div>
          <h1 style={repoCss.h1}>Répertoire des soumissions</h1>
          <div style={repoCss.sub}>Toutes les soumissions de l'équipe Raycom</div>
        </div>
        <button style={repoCss.btnPrimary} onClick={onNew}>
          <Icon name="plus" size={14}/>
          Nouvelle soumission
        </button>
      </div>

      {/* Stats */}
      <div style={repoCss.statsRow}>
        <StatCard label="Total"     value={stats.total} accent="#1a6fc4"/>
        <StatCard label="Envoyées"  value={stats.sent}  accent="#0ea5e9"/>
        <StatCard label="Acceptées" value={stats.accepted} accent="#1f8a5b"/>
        <StatCard label="Valeur"    value={fmtCAD0(stats.value)} accent="#7c3aed"/>
      </div>

      {/* Filtres */}
      <div style={repoCss.filters}>
        <div style={repoCss.searchWrap}>
          <Icon name="search" size={14}/>
          <input
            placeholder="Rechercher numéro, client, ville…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            style={repoCss.search}
          />
        </div>
        <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} style={repoCss.select}>
          <option value="all">Tous statuts</option>
          <option value="brouillon">Brouillons</option>
          <option value="envoye">Envoyées</option>
          <option value="accepte">Acceptées</option>
          <option value="refuse">Refusées</option>
          <option value="archive">Archivées</option>
        </select>
        <select value={creatorFilter} onChange={(e) => setCreatorFilter(e.target.value)} style={repoCss.select}>
          <option value="all">Tous vendeurs</option>
          {creators.map(c => <option key={c.id} value={c.id}>{c.name}{c.role === "admin" ? " (admin)" : ""}</option>)}
        </select>
        <button onClick={reload} style={repoCss.btnGhost} title="Rafraîchir">
          <Icon name="refresh-cw" size={13}/>
        </button>
      </div>

      {/* Table */}
      <div style={repoCss.tableWrap}>
        {loading ? (
          <div style={repoCss.empty}>Chargement…</div>
        ) : err ? (
          <div style={{...repoCss.empty, color: "#991b1b"}}>Erreur : {err}</div>
        ) : filtered.length === 0 ? (
          <EmptyState onNew={onNew}/>
        ) : (
          <table style={repoCss.table}>
            <thead>
              <tr>
                <Th>N°</Th>
                <Th>Statut</Th>
                <Th>Client</Th>
                <Th>Ville</Th>
                <Th>Projet</Th>
                <Th align="right">kW · kWh</Th>
                <Th align="right">Total</Th>
                <Th>Vendeur</Th>
                <Th>Modifié</Th>
                <Th></Th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(r => (
                <Row key={r.id} r={r} onOpen={onOpen} isAdmin={isAdmin} reload={reload} fmtCAD0={fmtCAD0}/>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

function Row({ r, onOpen, isAdmin, reload, fmtCAD0 }) {
  const project = ({
    solaire: "Solaire",
    solaire_batterie: "Solaire + Bat.",
    batterie: "Batterie",
    borne: "Borne VÉ"
  })[r.project_type] || (r.project_type || "—");

  const handleDelete = async (e) => {
    e.stopPropagation();
    if (!confirm(`Supprimer la soumission ${r.number || "brouillon"} ?`)) return;
    try {
      await window.RaycastDB.deleteSubmission(r.id);
      reload();
    } catch (ex) {
      alert("Suppression refusée : " + (ex.message || ex));
    }
  };

  return (
    <tr style={repoCss.tr} onClick={() => onOpen(r.id)}>
      <Td><span style={repoCss.number}>{r.number || <span style={repoCss.draftTag}>brouillon</span>}</span></Td>
      <Td><StatusBadge status={r.status}/></Td>
      <Td><div style={repoCss.clientName}>{r.client_name || "—"}</div></Td>
      <Td>{r.client_city || "—"}</Td>
      <Td><span style={repoCss.chip}>{project}</span></Td>
      <Td align="right" mono>
        {r.kw_total ? `${Number(r.kw_total).toFixed(1)} kW` : "—"}
        {r.kwh_total ? <span style={repoCss.kwhMuted}> · {Number(r.kwh_total).toFixed(1)} kWh</span> : null}
      </Td>
      <Td align="right" mono><b>{r.price_total ? fmtCAD0(r.price_total) : "—"}</b></Td>
      <Td>
        <div style={repoCss.creator}>
          <span style={{...repoCss.avatar, background: avatarColor(r.creator_name)}}>
            {(r.creator_initials || (r.creator_name || "?").slice(0, 2)).toUpperCase()}
          </span>
          <span>{r.creator_name || "—"}</span>
        </div>
      </Td>
      <Td>{fmtDate(r.updated_at)}</Td>
      <Td align="right">
        {isAdmin && (
          <button onClick={handleDelete} style={repoCss.deleteBtn} title="Supprimer">
            <Icon name="trash-2" size={13}/>
          </button>
        )}
      </Td>
    </tr>
  );
}

function StatusBadge({ status }) {
  const map = {
    brouillon: { label: "Brouillon", bg: "#f1f5f9", color: "#475569" },
    envoye:    { label: "Envoyée",   bg: "#dbeafe", color: "#1e40af" },
    accepte:   { label: "Acceptée",  bg: "#dcfce7", color: "#166534" },
    refuse:    { label: "Refusée",   bg: "#fee2e2", color: "#991b1b" },
    archive:   { label: "Archivée",  bg: "#e9d5ff", color: "#6b21a8" }
  };
  const s = map[status] || map.brouillon;
  return <span style={{...repoCss.statusBadge, background: s.bg, color: s.color}}>{s.label}</span>;
}

function StatCard({ label, value, accent }) {
  return (
    <div style={{...repoCss.stat, borderLeft: `3px solid ${accent}`}}>
      <div style={repoCss.statLabel}>{label}</div>
      <div style={repoCss.statValue}>{value}</div>
    </div>
  );
}

function EmptyState({ onNew }) {
  return (
    <div style={repoCss.emptyState}>
      <div style={repoCss.emptyIcon}><Icon name="folder" size={32}/></div>
      <h3 style={repoCss.emptyTitle}>Aucune soumission</h3>
      <p style={repoCss.emptySub}>Crée ta première soumission pour démarrer le répertoire.</p>
      <button style={repoCss.btnPrimary} onClick={onNew}>
        <Icon name="plus" size={14}/>
        Nouvelle soumission
      </button>
    </div>
  );
}

const Th = ({ children, align }) => (
  <th style={{...repoCss.th, textAlign: align || "left"}}>{children}</th>
);
const Td = ({ children, align, mono }) => (
  <td style={{
    ...repoCss.td,
    textAlign: align || "left",
    fontVariantNumeric: mono ? "tabular-nums" : undefined
  }}>{children}</td>
);

function fmtDate(s) {
  if (!s) return "—";
  const d = new Date(s);
  const today = new Date();
  const same = d.toDateString() === today.toDateString();
  if (same) return "Aujourd'hui · " + d.toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" });
  return d.toLocaleDateString("fr-CA", { year: "numeric", month: "short", day: "numeric" });
}

function avatarColor(name) {
  if (!name) return "#94a3b8";
  let h = 0;
  for (let i = 0; i < name.length; i++) h = name.charCodeAt(i) + ((h << 5) - h);
  const hue = Math.abs(h) % 360;
  return `hsl(${hue}, 45%, 50%)`;
}

const repoCss = {
  root: { padding: "28px 32px", background: "#f8fafc", minHeight: "100vh", flex: 1, overflowY: "auto" },
  header: {
    display: "flex", justifyContent: "space-between", alignItems: "flex-end",
    marginBottom: 22
  },
  h1: { margin: 0, fontSize: 24, fontWeight: 800, color: "#0f172a", letterSpacing: "-0.02em" },
  sub: { fontSize: 13, color: "#64748b", marginTop: 4 },
  btnPrimary: {
    display: "inline-flex", alignItems: "center", gap: 7,
    padding: "9px 16px",
    background: "linear-gradient(135deg, #1a6fc4 0%, #0d4a8a 100%)",
    color: "#fff", border: "none", borderRadius: 8,
    fontSize: 13, fontWeight: 600, cursor: "pointer",
    fontFamily: "inherit"
  },
  btnGhost: {
    padding: "8px 10px", background: "#fff", border: "1px solid #cbd5e1",
    borderRadius: 8, cursor: "pointer", color: "#475569",
    display: "inline-flex", alignItems: "center"
  },
  statsRow: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12, marginBottom: 18 },
  stat: { background: "#fff", padding: "12px 14px", borderRadius: 8, border: "1px solid #e2e8f0" },
  statLabel: { fontSize: 10, color: "#64748b", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em" },
  statValue: { fontSize: 22, fontWeight: 800, color: "#0f172a", marginTop: 4, fontVariantNumeric: "tabular-nums" },
  filters: { display: "flex", gap: 10, marginBottom: 14 },
  searchWrap: {
    flex: 1, display: "flex", alignItems: "center", gap: 8,
    padding: "0 12px", background: "#fff",
    border: "1px solid #cbd5e1", borderRadius: 8, color: "#94a3b8"
  },
  search: {
    flex: 1, padding: "10px 0", border: "none", outline: "none",
    fontSize: 13, fontFamily: "inherit", background: "transparent", color: "#0f172a"
  },
  select: {
    padding: "9px 12px", background: "#fff",
    border: "1px solid #cbd5e1", borderRadius: 8,
    fontSize: 13, fontFamily: "inherit", color: "#0f172a", cursor: "pointer"
  },
  tableWrap: { background: "#fff", borderRadius: 10, border: "1px solid #e2e8f0", overflow: "hidden" },
  table: { width: "100%", borderCollapse: "collapse", fontSize: 13 },
  th: {
    padding: "12px 14px", background: "#f8fafc",
    borderBottom: "1px solid #e2e8f0",
    fontSize: 10.5, fontWeight: 700, color: "#64748b",
    textTransform: "uppercase", letterSpacing: "0.05em"
  },
  td: { padding: "12px 14px", borderBottom: "1px solid #f1f5f9", color: "#0f172a", verticalAlign: "middle" },
  tr: { cursor: "pointer", transition: "background 0.1s" },
  number: { fontFamily: "'Fragment Mono', ui-monospace, monospace", fontSize: 12.5, fontWeight: 700, color: "#1a6fc4" },
  draftTag: { fontFamily: "inherit", fontStyle: "italic", color: "#94a3b8", fontWeight: 500 },
  statusBadge: {
    display: "inline-block", padding: "3px 8px", borderRadius: 4,
    fontSize: 10.5, fontWeight: 700, letterSpacing: "0.02em"
  },
  clientName: { fontWeight: 600 },
  chip: {
    display: "inline-block", padding: "2px 7px", background: "#f1f5f9",
    color: "#475569", borderRadius: 4, fontSize: 11, fontWeight: 500
  },
  kwhMuted: { color: "#94a3b8", fontWeight: 400 },
  creator: { display: "flex", alignItems: "center", gap: 7 },
  avatar: {
    width: 22, height: 22, borderRadius: "50%",
    display: "inline-flex", alignItems: "center", justifyContent: "center",
    color: "#fff", fontSize: 9.5, fontWeight: 700, letterSpacing: 0
  },
  deleteBtn: {
    background: "transparent", border: "none", color: "#cbd5e1",
    cursor: "pointer", padding: 6, borderRadius: 4
  },
  empty: { padding: 60, textAlign: "center", color: "#94a3b8", fontSize: 14 },
  emptyState: { padding: "60px 20px", textAlign: "center" },
  emptyIcon: {
    width: 64, height: 64, borderRadius: "50%", margin: "0 auto 16px",
    background: "#e0e7ff", color: "#4f46e5",
    display: "flex", alignItems: "center", justifyContent: "center"
  },
  emptyTitle: { margin: 0, fontSize: 17, fontWeight: 700, color: "#0f172a" },
  emptySub: { margin: "6px 0 18px", color: "#64748b", fontSize: 13 }
};

Object.assign(window, { Repository });
