// PortfolioPage — Route #/portefeuille
// Mon portefeuille investisseur (Vague 3 PR 3A) : biens reels, KPIs consolides,
// alertes refi via cron mensuel.
// Gating UI : FREE -> CTA upgrade ; PRO (Investisseur 24$) -> max 2 biens ; PRO+ illimite.

(function () {
  'use strict';

  const { useState, useEffect, useCallback } = React;

  const API_BASE = (window.VESTORA_CONFIG?.apiBase || '') + '/api/v1';

  async function _getAuthToken() {
    if (window.vestora && window.vestora.auth && typeof window.vestora.auth.getToken === 'function') {
      return window.vestora.auth.getToken();
    }
    return sessionStorage.getItem('vestora_token') || localStorage.getItem('vestora_token') || null;
  }

  async function _apiCall(method, path, body) {
    const token = await _getAuthToken();
    const headers = { 'Content-Type': 'application/json' };
    if (token) headers['Authorization'] = 'Bearer ' + token;
    const opts = { method, headers };
    if (body !== undefined) opts.body = JSON.stringify(body);
    const resp = await fetch(API_BASE + path, opts);
    let data = {};
    try { data = await resp.json(); } catch {}
    if (!resp.ok) {
      const err = new Error(data.detail || data.message || 'Erreur ' + resp.status);
      err.status = resp.status;
      throw err;
    }
    return data;
  }

  // ---- Helpers formatage ----
  function fmtMoney(value) {
    if (value === null || value === undefined) return '—';
    const num = typeof value === 'string' ? parseFloat(value) : value;
    if (isNaN(num)) return '—';
    return new Intl.NumberFormat('fr-CA', {
      style: 'currency', currency: 'CAD', maximumFractionDigits: 0,
    }).format(num);
  }
  function fmtPct(value) {
    if (value === null || value === undefined || isNaN(value)) return '—';
    return (value * 100).toFixed(1) + ' %';
  }
  function fmtDate(d) {
    if (!d) return '—';
    try {
      return new Date(d).toLocaleDateString('fr-CA', { day: 'numeric', month: 'short', year: 'numeric' });
    } catch { return d; }
  }

  // ---- KPI Card ----
  function KpiCard({ label, value, color, sub }) {
    return (
      <div style={{
        background: 'var(--bg-elev, #fff)',
        border: '1px solid var(--line, #e8e8e0)',
        borderRadius: 'var(--radius-lg, 12px)',
        padding: '18px 20px',
        flex: '1 1 180px',
        minWidth: 180,
      }}>
        <div style={{ fontSize: 12, color: 'var(--ink-3, #64748b)', textTransform: 'uppercase', letterSpacing: 0.5 }}>{label}</div>
        <div style={{ fontSize: 22, fontWeight: 700, color: color || 'var(--ink-1, #0f172a)', marginTop: 6 }}>{value}</div>
        {sub ? <div style={{ fontSize: 12, color: 'var(--ink-3, #64748b)', marginTop: 4 }}>{sub}</div> : null}
      </div>
    );
  }

  // ---- Property Card ----
  function PropertyCard({ prop, onEdit, onDelete, onAnalyze }) {
    const cashflow = computeCashflow(prop);
    const equity = computeEquity(prop);
    return (
      <div style={{
        background: 'var(--bg-elev, #fff)',
        border: '1px solid var(--line, #e8e8e0)',
        borderRadius: 'var(--radius-lg, 12px)',
        padding: '18px 22px',
        display: 'flex', flexDirection: 'column', gap: 10,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 12, color: 'var(--ink-3)', textTransform: 'uppercase' }}>{prop.property_type}</div>
            <div style={{ fontSize: 16, fontWeight: 600, marginTop: 2 }}>{prop.address}</div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 4 }}>
              Achete {fmtDate(prop.purchase_date)} · {fmtMoney(prop.purchase_price)}
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
            {prop.listing_id ? (
              <button onClick={() => onAnalyze(prop)} style={btnSecondary}>Analyser</button>
            ) : null}
            <button onClick={() => onEdit(prop)} style={btnSecondary}>Editer</button>
            <button onClick={() => onDelete(prop)} style={btnDanger}>Supprimer</button>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 10, marginTop: 6 }}>
          <Mini label="Valeur" value={fmtMoney(prop.current_value_estimate || prop.purchase_price)} />
          <Mini label="Solde hypo." value={fmtMoney(prop.mortgage_balance)} />
          <Mini label="Taux" value={prop.mortgage_rate != null ? prop.mortgage_rate + ' %' : '—'} />
          <Mini label="Echeance" value={fmtDate(prop.mortgage_term_end)} />
          <Mini label="Loyer/mois" value={fmtMoney(prop.monthly_rent)} />
          <Mini label="OpEx/mois" value={fmtMoney(prop.monthly_opex)} />
          <Mini label="Equite" value={fmtMoney(equity)} highlight={equity >= 0 ? 'pos' : 'neg'} />
          <Mini label="Cash flow/mois" value={fmtMoney(cashflow)} highlight={cashflow >= 0 ? 'pos' : 'neg'} />
        </div>
      </div>
    );
  }

  function Mini({ label, value, highlight }) {
    const color = highlight === 'pos' ? '#16a34a' : highlight === 'neg' ? '#b91c1c' : 'var(--ink-1)';
    return (
      <div>
        <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase' }}>{label}</div>
        <div style={{ fontSize: 14, fontWeight: 600, color, marginTop: 2 }}>{value}</div>
      </div>
    );
  }

  function computeCashflow(prop) {
    const rent = parseFloat(prop.monthly_rent || 0);
    const opex = parseFloat(prop.monthly_opex || 0);
    const balance = parseFloat(prop.mortgage_balance || 0);
    const rate = parseFloat(prop.mortgage_rate || 0);
    const interest = (balance * rate / 100) / 12;
    return rent - opex - interest;
  }

  function computeEquity(prop) {
    const value = parseFloat(prop.current_value_estimate || prop.purchase_price || 0);
    const debt = parseFloat(prop.mortgage_balance || 0);
    return value - debt;
  }

  // ---- Modal ajout / edition ----
  function PropertyFormModal({ open, initial, onClose, onSave, lang }) {
    const [form, setForm] = useState(initial || {});
    const [submitting, setSubmitting] = useState(false);
    const [error, setError] = useState(null);

    useEffect(() => {
      if (open) {
        setForm(initial || { property_type: 'multilog' });
        setError(null);
      }
    }, [open, initial]);

    if (!open) return null;

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

    const submit = async (e) => {
      e.preventDefault();
      setError(null);
      setSubmitting(true);
      try {
        // Nettoie : conserve uniquement les champs renseignes (string vide -> null).
        const payload = {};
        ['listing_id','address','property_type','purchase_price','purchase_date',
         'mortgage_balance','mortgage_rate','mortgage_term_end',
         'monthly_rent','monthly_opex','current_value_estimate','notes'].forEach(k => {
          const v = form[k];
          if (v === '' || v === undefined || v === null) return;
          payload[k] = v;
        });
        await onSave(payload);
      } catch (err) {
        setError(err.message || 'Erreur');
      } finally {
        setSubmitting(false);
      }
    };

    return (
      <div style={modalBackdrop} onClick={onClose}>
        <div style={modalCard} onClick={e => e.stopPropagation()}>
          <h3 style={{ margin: '0 0 12px' }}>{initial && initial.id ? 'Editer le bien' : 'Ajouter un bien'}</h3>
          <form onSubmit={submit} style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }}>
            <Field label="Adresse *" full>
              <input required type="text" value={form.address || ''} onChange={e => set('address', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Type">
              <select value={form.property_type || 'multilog'} onChange={e => set('property_type', e.target.value)} style={inputStyle}>
                <option value="multilog">Multilogement</option>
                <option value="condo">Condo</option>
                <option value="plex">Plex</option>
                <option value="mixte">Mixte</option>
                <option value="unifamilial">Unifamilial</option>
              </select>
            </Field>
            <Field label="Prix d'achat *">
              <input required type="number" min="0" value={form.purchase_price || ''} onChange={e => set('purchase_price', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Date d'achat *">
              <input required type="date" value={form.purchase_date || ''} onChange={e => set('purchase_date', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Solde hypothecaire">
              <input type="number" min="0" value={form.mortgage_balance || ''} onChange={e => set('mortgage_balance', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Taux (%)">
              <input type="number" min="0" max="30" step="0.01" value={form.mortgage_rate || ''} onChange={e => set('mortgage_rate', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Echeance hypo.">
              <input type="date" value={form.mortgage_term_end || ''} onChange={e => set('mortgage_term_end', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Valeur actuelle estimee">
              <input type="number" min="0" value={form.current_value_estimate || ''} onChange={e => set('current_value_estimate', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Loyer mensuel (total)">
              <input type="number" min="0" value={form.monthly_rent || ''} onChange={e => set('monthly_rent', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="OpEx mensuelles">
              <input type="number" min="0" value={form.monthly_opex || ''} onChange={e => set('monthly_opex', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="ID listing Centris (optionnel)" full>
              <input type="text" value={form.listing_id || ''} onChange={e => set('listing_id', e.target.value)} style={inputStyle} />
            </Field>
            <Field label="Notes" full>
              <textarea rows="2" value={form.notes || ''} onChange={e => set('notes', e.target.value)} style={{ ...inputStyle, resize: 'vertical' }} />
            </Field>
            {error ? (
              <div style={{ gridColumn: '1 / -1', padding: 10, background: '#fef2f2', color: '#b91c1c', borderRadius: 6, fontSize: 13 }}>
                {error}
              </div>
            ) : null}
            <div style={{ gridColumn: '1 / -1', display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 8 }}>
              <button type="button" onClick={onClose} style={btnSecondary}>Annuler</button>
              <button type="submit" disabled={submitting} style={btnPrimary}>
                {submitting ? 'Enregistrement…' : 'Enregistrer'}
              </button>
            </div>
          </form>
        </div>
      </div>
    );
  }

  function Field({ label, full, children }) {
    return (
      <label style={{ display: 'block', gridColumn: full ? '1 / -1' : undefined }}>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', marginBottom: 4 }}>{label}</div>
        {children}
      </label>
    );
  }

  // ---- Styles partages ----
  const inputStyle = {
    width: '100%', padding: '8px 10px', border: '1px solid var(--line, #d1d5db)',
    borderRadius: 6, fontSize: 14, background: '#fff', fontFamily: 'inherit',
  };
  const btnPrimary = {
    padding: '8px 16px', background: 'var(--accent, #0f172a)', color: '#fff',
    border: 'none', borderRadius: 6, fontWeight: 600, cursor: 'pointer', fontSize: 14,
  };
  const btnSecondary = {
    padding: '6px 12px', background: '#fff', color: 'var(--ink-1)',
    border: '1px solid var(--line, #d1d5db)', borderRadius: 6, fontSize: 13,
    cursor: 'pointer', fontWeight: 500,
  };
  const btnDanger = {
    padding: '6px 12px', background: '#fff', color: '#b91c1c',
    border: '1px solid #fecaca', borderRadius: 6, fontSize: 13, cursor: 'pointer',
  };
  const modalBackdrop = {
    position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.45)',
    display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9000, padding: 20,
  };
  const modalCard = {
    background: '#fff', borderRadius: 12, padding: 24, maxWidth: 720, width: '100%',
    maxHeight: '90vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,0.3)',
  };

  // ---- Page principale ----
  function PortfolioPage({ user, lang }) {
    const [data, setData] = useState({ items: [], summary: null });
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [modalOpen, setModalOpen] = useState(false);
    const [editing, setEditing] = useState(null);

    const userPlan = (user && user.plan) || 'free';
    const isFree = userPlan === 'free';

    const load = useCallback(async () => {
      setLoading(true);
      setError(null);
      try {
        const r = await _apiCall('GET', '/portfolio/properties');
        setData(r);
      } catch (e) {
        if (e.status === 401) {
          setError('Connectez-vous pour voir votre portefeuille.');
        } else {
          setError(e.message);
        }
      } finally {
        setLoading(false);
      }
    }, []);

    useEffect(() => {
      if (!user) {
        setLoading(false);
        return;
      }
      load();
    }, [user, load]);

    const openAdd = () => { setEditing(null); setModalOpen(true); };
    const openEdit = (prop) => { setEditing(prop); setModalOpen(true); };

    const handleSave = async (payload) => {
      if (editing && editing.id) {
        await _apiCall('PUT', `/portfolio/properties/${editing.id}`, payload);
      } else {
        await _apiCall('POST', '/portfolio/properties', payload);
      }
      setModalOpen(false);
      load();
    };

    const handleDelete = async (prop) => {
      if (!confirm(`Supprimer le bien "${prop.address}" du portefeuille ?`)) return;
      try {
        await _apiCall('DELETE', `/portfolio/properties/${prop.id}`);
        load();
      } catch (e) {
        alert(e.message);
      }
    };

    const handleAnalyze = (prop) => {
      if (prop.listing_id) {
        window.navigateTo('#/analyze/' + encodeURIComponent(prop.listing_id));
      }
    };

    // ---- Render: non connecte ----
    if (!user) {
      return (
        <div style={{ maxWidth: 700, margin: '60px auto', padding: 30, textAlign: 'center' }}>
          <h2>Mon portefeuille investisseur</h2>
          <p style={{ color: 'var(--ink-3)' }}>Connectez-vous pour suivre vos biens.</p>
          <button onClick={() => window.vestora?.auth?.openModal?.()} style={btnPrimary}>Se connecter</button>
        </div>
      );
    }

    // ---- Render: free ----
    if (isFree) {
      return (
        <div style={{ maxWidth: 720, margin: '60px auto', padding: 30, textAlign: 'center', background: '#fff', borderRadius: 12, border: '1px solid var(--line)' }}>
          <div style={{ fontSize: 32 }}>📂</div>
          <h2 style={{ marginTop: 12 }}>Suivez vos biens reels</h2>
          <p style={{ color: 'var(--ink-3)', maxWidth: 480, margin: '12px auto 24px' }}>
            Le portefeuille investisseur sauvegarde vos biens, calcule votre equite totale, votre cash flow consolide,
            et vous alerte 6 mois avant chaque renouvellement hypothecaire. Reserve aux abonnes Investisseur (24$/mo).
          </p>
          <button onClick={() => window.navigateTo('#/tarifs')} style={{ ...btnPrimary, padding: '12px 24px' }}>
            Voir les plans
          </button>
        </div>
      );
    }

    const summary = data.summary || { properties_count: 0 };
    const quota = userPlan === 'pro' ? 2 : null; // null = illimite cote PRO_PLUS+
    const atQuota = quota !== null && summary.properties_count >= quota;

    return (
      <div style={{ maxWidth: 1100, margin: '32px auto', padding: '0 20px', fontFamily: 'Inter, system-ui, sans-serif' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24, flexWrap: 'wrap', gap: 12 }}>
          <div>
            <h1 style={{ margin: 0, fontSize: 26 }}>Mon portefeuille</h1>
            <div style={{ fontSize: 13, color: 'var(--ink-3)', marginTop: 4 }}>
              {summary.properties_count} bien{summary.properties_count > 1 ? 's' : ''} suivi{summary.properties_count > 1 ? 's' : ''}
              {quota !== null ? ` (plan Investisseur : ${quota} max)` : ' (illimite)'}
            </div>
          </div>
          <button onClick={openAdd} disabled={atQuota} style={{ ...btnPrimary, opacity: atQuota ? 0.5 : 1 }}>
            + Ajouter un bien
          </button>
        </div>

        {atQuota ? (
          <div style={{ padding: 14, background: '#fef9c3', border: '1px solid #fde047', borderRadius: 8, marginBottom: 20, fontSize: 14 }}>
            Quota Investisseur atteint ({quota} biens). <a href="#/tarifs" style={{ fontWeight: 600 }}>Passez Investisseur Pro (49$)</a> pour suivre un portefeuille illimite.
          </div>
        ) : null}

        {error ? (
          <div style={{ padding: 14, background: '#fef2f2', color: '#b91c1c', borderRadius: 8, marginBottom: 20 }}>
            {error}
          </div>
        ) : null}

        {/* KPIs */}
        {summary.properties_count > 0 ? (
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 24 }}>
            <KpiCard label="Biens" value={summary.properties_count} />
            <KpiCard label="Valeur portefeuille" value={fmtMoney(summary.total_value)} />
            <KpiCard label="Dette totale" value={fmtMoney(summary.total_debt)} />
            <KpiCard label="Equite totale" value={fmtMoney(summary.total_equity)} color="#16a34a" />
            <KpiCard label="LTV moyen" value={fmtPct(summary.avg_ltv)} sub="dette / valeur" />
            <KpiCard
              label="Cash flow mensuel"
              value={fmtMoney(summary.monthly_cashflow)}
              color={parseFloat(summary.monthly_cashflow || 0) >= 0 ? '#16a34a' : '#b91c1c'}
              sub="loyers - opex - interets"
            />
          </div>
        ) : null}

        {/* Liste */}
        {loading ? (
          <div style={{ textAlign: 'center', padding: 40, color: 'var(--ink-3)' }}>Chargement…</div>
        ) : data.items.length === 0 ? (
          <div style={{ textAlign: 'center', padding: 60, background: '#fff', borderRadius: 12, border: '1px dashed var(--line)' }}>
            <div style={{ fontSize: 36 }}>🏠</div>
            <h3 style={{ marginTop: 12 }}>Aucun bien dans votre portefeuille</h3>
            <p style={{ color: 'var(--ink-3)', maxWidth: 400, margin: '8px auto 18px' }}>
              Ajoutez votre premier bien pour commencer a suivre cash flow, equite et echeances hypothecaires.
            </p>
            <button onClick={openAdd} style={btnPrimary}>+ Ajouter mon premier bien</button>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {data.items.map(prop => (
              <PropertyCard
                key={prop.id}
                prop={prop}
                onEdit={openEdit}
                onDelete={handleDelete}
                onAnalyze={handleAnalyze}
              />
            ))}
          </div>
        )}

        <PropertyFormModal
          open={modalOpen}
          initial={editing}
          onClose={() => setModalOpen(false)}
          onSave={handleSave}
          lang={lang}
        />

        <div style={{ marginTop: 40, fontSize: 12, color: 'var(--ink-3)', textAlign: 'center' }}>
          TODO v2 : scenario "vendre vs garder 5 ans", carte des biens, integration Plaid/Flinks.
        </div>
      </div>
    );
  }

  window.PortfolioPage = PortfolioPage;
})();
