// BrokerTab_Mandats.jsx — Onglet "Mandats actifs + KPIs perso" (Vague 4 PR 4.1)
// Conventions : NO import/export, React global, unique hook aliases (suffix M).

function BrokerTabMandats({ lang }) {
  const {
    useState: useSM,
    useEffect: useEM,
    useMemo: useMM,
    useCallback: useCBM,
  } = React;
  const FR = lang !== 'en';

  const api = (window.vestora && window.vestora.brokerApi) || null;
  const TT = window.TermTooltip || (({ children }) => <span>{children}</span>);

  const [mandates, setMandates] = useSM([]);
  const [kpis, setKpis] = useSM(null);
  const [loading, setLoading] = useSM(true);
  const [error, setError] = useSM(null);
  const [modalOpen, setModalOpen] = useSM(false);
  const [editing, setEditing] = useSM(null); // mandate row when editing, else null

  // ── Chargement initial ─────────────────────────────────────────────────
  const reload = useCBM(async () => {
    if (!api) {
      setError(FR ? 'API courtier indisponible.' : 'Broker API unavailable.');
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    const [resM, resK] = await Promise.all([api.listMandates(), api.getKpis()]);
    if (!resM.ok) {
      setError((resM.error && resM.error.message) || 'Erreur chargement mandats.');
    } else {
      setMandates(resM.data || []);
    }
    if (resK.ok) {
      setKpis(resK.data);
    }
    setLoading(false);
  }, [api, FR]);

  useEM(() => { reload(); }, [reload]);

  // ── Helpers format ─────────────────────────────────────────────────────
  const fmtMoney = (v) => {
    if (v == null || Number.isNaN(Number(v))) return '—';
    return new Intl.NumberFormat(FR ? 'fr-CA' : 'en-CA', {
      style: 'currency', currency: 'CAD', maximumFractionDigits: 0,
    }).format(Number(v));
  };
  const fmtPct = (v) => (v == null ? '—' : `${Number(v).toFixed(1)}%`);
  const fmtDate = (v) => {
    if (!v) return '—';
    try { return new Date(v).toLocaleDateString(FR ? 'fr-CA' : 'en-CA'); }
    catch (e) { return String(v); }
  };

  const statusLabel = (s) => {
    if (FR) {
      return { active: 'Actif', sold: 'Vendu', expired: 'Expiré', withdrawn: 'Retiré' }[s] || s;
    }
    return { active: 'Active', sold: 'Sold', expired: 'Expired', withdrawn: 'Withdrawn' }[s] || s;
  };
  const statusColor = (s) => ({
    active: '#10b981', sold: '#3b82f6', expired: '#9ca3af', withdrawn: '#f59e0b',
  }[s] || '#9ca3af');

  // ── Edition inline visits/offers ───────────────────────────────────────
  const patchMandate = async (id, patch) => {
    if (!api) return;
    const res = await api.updateMandate(id, patch);
    if (res.ok) {
      setMandates((prev) => prev.map((m) => (m.id === id ? res.data : m)));
      // Recharge KPIs (peut affecter GCI, ratio, etc.).
      const rk = await api.getKpis();
      if (rk.ok) setKpis(rk.data);
    } else {
      alert((res.error && res.error.message) || 'Erreur mise a jour.');
    }
  };

  const markSold = async (m) => {
    const priceStr = prompt(
      FR ? 'Prix de vente final ($) ?' : 'Final sale price ($)?',
      String(m.listedPrice || ''),
    );
    if (priceStr == null) return;
    const price = Number(priceStr);
    if (!Number.isFinite(price) || price <= 0) {
      alert(FR ? 'Prix invalide.' : 'Invalid price.');
      return;
    }
    const today = new Date().toISOString().slice(0, 10);
    await patchMandate(m.id, { status: 'sold', soldPrice: price, soldAt: today });
  };

  const markExpired = async (m) => {
    if (!confirm(FR ? 'Marquer ce mandat comme expiré ?' : 'Mark as expired?')) return;
    await patchMandate(m.id, { status: 'expired' });
  };

  const deleteMandate = async (m) => {
    if (!confirm(FR ? 'Supprimer ce mandat ?' : 'Delete this mandate?')) return;
    if (!api) return;
    const res = await api.deleteMandate(m.id);
    if (res.ok) {
      setMandates((prev) => prev.filter((x) => x.id !== m.id));
      const rk = await api.getKpis();
      if (rk.ok) setKpis(rk.data);
    } else {
      alert((res.error && res.error.message) || 'Erreur suppression.');
    }
  };

  const inlineNum = (m, field, label) => {
    return (
      <input
        type="number"
        min="0"
        defaultValue={m[field]}
        aria-label={label}
        onBlur={(e) => {
          const v = Number(e.target.value);
          if (Number.isFinite(v) && v !== m[field]) {
            patchMandate(m.id, { [field]: v });
          }
        }}
        style={{
          width: 56, padding: '2px 4px', fontSize: 13,
          border: '1px solid #d1d5db', borderRadius: 4,
          background: '#fff',
        }}
      />
    );
  };

  // ── Mandats actifs (pour le tableau principal) ─────────────────────────
  const activeMandates = useMM(
    () => mandates.filter((m) => m.status === 'active'),
    [mandates],
  );
  const otherMandates = useMM(
    () => mandates.filter((m) => m.status !== 'active'),
    [mandates],
  );

  // ── Rendu ──────────────────────────────────────────────────────────────
  if (loading) {
    return (
      <div style={{ padding: 32, textAlign: 'center', color: '#6b7280' }}>
        {FR ? 'Chargement des mandats…' : 'Loading mandates…'}
      </div>
    );
  }

  if (error) {
    return (
      <div style={{ padding: 16, background: '#fef2f2', border: '1px solid #fecaca', borderRadius: 8, color: '#b91c1c' }}>
        {error}
      </div>
    );
  }

  return (
    <div className="broker-mandates">
      {/* ── KPIs cartes ────────────────────────────────────────────────── */}
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
        gap: 12, marginBottom: 20,
      }}>
        <KpiCard
          label={FR ? 'GCI YTD' : 'GCI YTD'}
          subtitle={FR ? 'Commissions brutes — année en cours' : 'Gross commissions — year-to-date'}
          value={kpis ? fmtMoney(kpis.gciYtd) : '—'}
          accent="#0ea5e9"
        />
        <KpiCard
          label={FR ? 'Mandats actifs' : 'Active mandates'}
          subtitle={kpis ? `${kpis.activeMandatesCount} mandats — ${fmtMoney(kpis.activeMandatesValue)}` : '—'}
          value={kpis ? String(kpis.activeMandatesCount) : '—'}
          accent="#10b981"
        />
        <KpiCard
          label={FR ? 'DOM moyen — mes mandats' : 'My avg DOM'}
          subtitle={kpis && kpis.avgDomMarket != null
            ? (FR ? `vs marché ${Math.round(kpis.avgDomMarket)}j` : `vs market ${Math.round(kpis.avgDomMarket)}d`)
            : ''}
          value={kpis && kpis.avgDomMyMandates != null
            ? (FR ? `${kpis.avgDomMyMandates}j` : `${kpis.avgDomMyMandates}d`)
            : '—'}
          accent="#8b5cf6"
        />
        <KpiCard
          label={FR ? 'Ratio vendu/listé' : 'Sold/listed ratio'}
          subtitle={FR ? '% du prix d\'affichage' : '% of listed price'}
          value={kpis && kpis.ratioSoldVsListed != null ? fmtPct(kpis.ratioSoldVsListed) : '—'}
          accent="#f59e0b"
        />
      </div>

      {/* ── Conversion kanban ─────────────────────────────────────────── */}
      {kpis && kpis.conversionByStage && Object.keys(kpis.conversionByStage).length > 0 && (
        <div style={{
          padding: 12, background: '#f9fafb', borderRadius: 8,
          border: '1px solid #e5e7eb', marginBottom: 20,
        }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: '#374151', marginBottom: 8 }}>
            {FR ? 'Conversion kanban (clients)' : 'Kanban conversion (clients)'}
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>
            {Object.entries(kpis.conversionByStage).map(([k, v]) => (
              <div key={k} style={{ fontSize: 12, color: '#4b5563' }}>
                <code style={{ color: '#111' }}>{k}</code>{' '}
                <strong>{(Number(v) * 100).toFixed(0)}%</strong>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* ── Suggestions baisse de prix ───────────────────────────────── */}
      {kpis && kpis.priceDropSuggestions && kpis.priceDropSuggestions.length > 0 && (
        <div style={{
          padding: 12, background: '#fff7ed', borderRadius: 8,
          border: '1px solid #fed7aa', marginBottom: 20,
        }}>
          <div style={{ fontSize: 12, fontWeight: 700, color: '#9a3412', marginBottom: 6 }}>
            {FR ? '⚠ Suggestions de baisse de prix' : '⚠ Price drop suggestions'}
          </div>
          {kpis.priceDropSuggestions.map((s) => (
            <div key={s.mandate_id} style={{ fontSize: 12, color: '#7c2d12', padding: '2px 0' }}>
              <strong>{s.address}</strong> — {FR ? 'baisse suggérée' : 'suggested drop'}{' '}
              <strong>-{s.suggested_drop_pct}%</strong> — {s.reason}
            </div>
          ))}
        </div>
      )}

      {/* ── Header tableau ────────────────────────────────────────────── */}
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        marginBottom: 12,
      }}>
        <h2 style={{ margin: 0, fontSize: 18, fontWeight: 600 }}>
          {FR ? 'Mes mandats actifs' : 'My active mandates'}
        </h2>
        <button
          onClick={() => { setEditing(null); setModalOpen(true); }}
          style={{
            padding: '8px 14px', background: '#0F172A', color: '#fff',
            border: 'none', borderRadius: 6, cursor: 'pointer',
            fontSize: 13, fontWeight: 600,
          }}
        >
          + {FR ? 'Ajouter un mandat' : 'Add a mandate'}
        </button>
      </div>

      {/* ── Tableau ───────────────────────────────────────────────────── */}
      {activeMandates.length === 0 && otherMandates.length === 0 ? (
        <div style={{ padding: 32, textAlign: 'center', color: '#6b7280', background: '#f9fafb', borderRadius: 8 }}>
          {FR ? 'Aucun mandat encore. Cliquez sur "+ Ajouter un mandat".' : 'No mandates yet.'}
        </div>
      ) : (
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
            <thead>
              <tr style={{ background: '#f3f4f6', textAlign: 'left' }}>
                <th style={thStyle}>{FR ? 'Adresse' : 'Address'}</th>
                <th style={thStyle}>{FR ? 'Prix listé' : 'Listed'}</th>
                <th style={thStyle}>{FR ? 'Début mandat' : 'Start'}</th>
                <th style={thStyle}>DOM</th>
                <th style={thStyle}>{FR ? 'Visites' : 'Visits'}</th>
                <th style={thStyle}>{FR ? 'Offres' : 'Offers'}</th>
                <th style={thStyle}>{FR ? 'Statut' : 'Status'}</th>
                <th style={thStyle}></th>
              </tr>
            </thead>
            <tbody>
              {[...activeMandates, ...otherMandates].map((m) => {
                const sug = m.priceDropSuggestion;
                return (
                  <tr key={m.id} style={{ borderBottom: '1px solid #e5e7eb' }}>
                    <td style={tdStyle}>
                      <div style={{ fontWeight: 500 }}>{m.address}</div>
                      {sug && (
                        <div style={{
                          marginTop: 4, fontSize: 11, color: '#9a3412',
                          background: '#fff7ed', padding: '2px 6px',
                          borderRadius: 4, display: 'inline-block',
                        }}>
                          ⚠ {FR ? 'Suggestion' : 'Suggestion'} -{sug.suggested_drop_pct}%
                        </div>
                      )}
                    </td>
                    <td style={tdStyle}>{fmtMoney(m.listedPrice)}</td>
                    <td style={tdStyle}>{fmtDate(m.mandateStart)}</td>
                    <td style={tdStyle}>
                      {m.domDays != null
                        ? (FR ? `${m.domDays}j` : `${m.domDays}d`)
                        : '—'}
                    </td>
                    <td style={tdStyle}>
                      {m.status === 'active'
                        ? inlineNum(m, 'visitsCount', FR ? 'Visites' : 'Visits')
                        : m.visitsCount}
                    </td>
                    <td style={tdStyle}>
                      {m.status === 'active'
                        ? inlineNum(m, 'offersCount', FR ? 'Offres' : 'Offers')
                        : m.offersCount}
                    </td>
                    <td style={tdStyle}>
                      <span style={{
                        background: statusColor(m.status), color: '#fff',
                        padding: '2px 8px', borderRadius: 4, fontSize: 11,
                        fontWeight: 600,
                      }}>
                        {statusLabel(m.status)}
                      </span>
                      {m.status === 'sold' && m.soldPrice != null && (
                        <div style={{ fontSize: 11, color: '#6b7280', marginTop: 2 }}>
                          {fmtMoney(m.soldPrice)} — {fmtDate(m.soldAt)}
                        </div>
                      )}
                    </td>
                    <td style={tdStyle}>
                      {m.status === 'active' && (
                        <>
                          <button onClick={() => markSold(m)} style={actionBtn('#10b981')}>
                            {FR ? 'Vendu' : 'Sold'}
                          </button>
                          <button onClick={() => markExpired(m)} style={actionBtn('#f59e0b')}>
                            {FR ? 'Expiré' : 'Expired'}
                          </button>
                        </>
                      )}
                      <button onClick={() => deleteMandate(m)} style={actionBtn('#ef4444')}>
                        {FR ? 'Suppr.' : 'Del.'}
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {modalOpen && (
        <MandateModal
          lang={lang}
          initial={editing}
          onClose={() => { setModalOpen(false); setEditing(null); }}
          onSaved={async (newRow) => {
            setModalOpen(false);
            setEditing(null);
            // Recharge (plus simple que merger localement, peu de mandats).
            await reload();
          }}
        />
      )}
    </div>
  );
}

// ── Sous-composants ────────────────────────────────────────────────────

function KpiCard({ label, subtitle, value, accent }) {
  return (
    <div style={{
      padding: 14, borderRadius: 8, background: '#fff',
      border: '1px solid #e5e7eb',
      borderLeft: `3px solid ${accent || '#0F172A'}`,
    }}>
      <div style={{ fontSize: 11, color: '#6b7280', textTransform: 'uppercase', letterSpacing: 0.5, fontWeight: 600 }}>
        {label}
      </div>
      <div style={{ fontSize: 24, fontWeight: 700, color: '#0F172A', margin: '4px 0' }}>
        {value}
      </div>
      {subtitle && (
        <div style={{ fontSize: 11, color: '#6b7280' }}>{subtitle}</div>
      )}
    </div>
  );
}

function MandateModal({ lang, initial, onClose, onSaved }) {
  const { useState: useSMM } = React;
  const FR = lang !== 'en';
  const api = (window.vestora && window.vestora.brokerApi) || null;

  const isEdit = !!initial;
  const [form, setForm] = useSMM(initial || {
    address: '',
    propertyType: 'multilog',
    listedPrice: '',
    mandateStart: new Date().toISOString().slice(0, 10),
    mandateEnd: new Date(Date.now() + 180 * 86400000).toISOString().slice(0, 10),
    visitsCount: 0,
    offersCount: 0,
    commissionPct: 0.04,
    listingId: '',
    notes: '',
  });
  const [saving, setSaving] = useSMM(false);
  const [err, setErr] = useSMM(null);

  const update = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  const save = async () => {
    setSaving(true);
    setErr(null);
    if (!api) {
      setErr('API indisponible.');
      setSaving(false);
      return;
    }
    const payload = {
      ...form,
      listedPrice: Number(form.listedPrice),
      visitsCount: Number(form.visitsCount || 0),
      offersCount: Number(form.offersCount || 0),
      commissionPct: form.commissionPct === '' || form.commissionPct == null
        ? null : Number(form.commissionPct),
    };
    const res = isEdit
      ? await api.updateMandate(initial.id, payload)
      : await api.createMandate(payload);
    setSaving(false);
    if (!res.ok) {
      setErr((res.error && res.error.message) || 'Erreur sauvegarde.');
      return;
    }
    onSaved(res.data);
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 1000,
    }}>
      <div style={{
        background: '#fff', padding: 24, borderRadius: 12,
        width: 'min(560px, 92vw)', maxHeight: '92vh', overflowY: 'auto',
      }}>
        <h3 style={{ margin: '0 0 16px 0' }}>
          {isEdit
            ? (FR ? 'Modifier le mandat' : 'Edit mandate')
            : (FR ? 'Nouveau mandat' : 'New mandate')}
        </h3>

        <Field label={FR ? 'Adresse *' : 'Address *'}>
          <input value={form.address || ''} onChange={(e) => update('address', e.target.value)}
                 style={inputStyle} placeholder="123 rue Saint-Denis, Montréal" />
        </Field>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <Field label={FR ? 'Prix listé ($) *' : 'Listed price ($) *'}>
            <input type="number" min="0" value={form.listedPrice}
                   onChange={(e) => update('listedPrice', e.target.value)}
                   style={inputStyle} />
          </Field>
          <Field label={FR ? 'Type' : 'Type'}>
            <select value={form.propertyType} onChange={(e) => update('propertyType', e.target.value)}
                    style={inputStyle}>
              <option value="multilog">Multilog</option>
              <option value="plex">Plex</option>
              <option value="condo">Condo</option>
              <option value="unifamilial">Unifamilial</option>
              <option value="mixte">Mixte</option>
            </select>
          </Field>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <Field label={FR ? 'Début mandat *' : 'Start *'}>
            <input type="date" value={form.mandateStart}
                   onChange={(e) => update('mandateStart', e.target.value)} style={inputStyle} />
          </Field>
          <Field label={FR ? 'Fin mandat *' : 'End *'}>
            <input type="date" value={form.mandateEnd}
                   onChange={(e) => update('mandateEnd', e.target.value)} style={inputStyle} />
          </Field>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <Field label={FR ? 'Commission (ex: 0.04 = 4%)' : 'Commission (e.g. 0.04 = 4%)'}>
            <input type="number" step="0.001" min="0" max="1"
                   value={form.commissionPct == null ? '' : form.commissionPct}
                   onChange={(e) => update('commissionPct', e.target.value)} style={inputStyle} />
          </Field>
          <Field label={FR ? 'ID listing (Centris ou custom)' : 'Listing ID (Centris or custom)'}>
            <input value={form.listingId || ''} onChange={(e) => update('listingId', e.target.value)}
                   style={inputStyle} placeholder="optionnel" />
          </Field>
        </div>

        <Field label={FR ? 'Notes' : 'Notes'}>
          <textarea value={form.notes || ''} onChange={(e) => update('notes', e.target.value)}
                    style={{ ...inputStyle, minHeight: 60, resize: 'vertical' }} />
        </Field>

        {err && (
          <div style={{ color: '#b91c1c', fontSize: 13, marginTop: 8 }}>{err}</div>
        )}

        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16 }}>
          <button onClick={onClose} style={{
            padding: '8px 14px', background: '#f3f4f6', border: '1px solid #d1d5db',
            borderRadius: 6, cursor: 'pointer', fontSize: 13,
          }}>
            {FR ? 'Annuler' : 'Cancel'}
          </button>
          <button onClick={save} disabled={saving || !form.address || !form.listedPrice} style={{
            padding: '8px 14px', background: '#0F172A', color: '#fff',
            border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: 13, fontWeight: 600,
            opacity: saving ? 0.6 : 1,
          }}>
            {saving ? (FR ? 'Sauvegarde…' : 'Saving…') : (FR ? 'Sauvegarder' : 'Save')}
          </button>
        </div>
      </div>
    </div>
  );
}

function Field({ label, children }) {
  return (
    <label style={{ display: 'block', marginBottom: 10, fontSize: 12, color: '#374151' }}>
      <div style={{ marginBottom: 4, fontWeight: 500 }}>{label}</div>
      {children}
    </label>
  );
}

// ── Styles partagés ──────────────────────────────────────────────────
const thStyle = { padding: '8px 10px', fontWeight: 600, color: '#374151', borderBottom: '2px solid #e5e7eb', fontSize: 12 };
const tdStyle = { padding: '8px 10px', verticalAlign: 'top' };
const inputStyle = {
  width: '100%', padding: '6px 8px', fontSize: 13,
  border: '1px solid #d1d5db', borderRadius: 4, background: '#fff',
  boxSizing: 'border-box',
};
function actionBtn(color) {
  return {
    marginRight: 4, padding: '4px 8px', fontSize: 11, fontWeight: 600,
    background: '#fff', color, border: `1px solid ${color}`,
    borderRadius: 4, cursor: 'pointer',
  };
}

window.BrokerTabMandats = BrokerTabMandats;
