import { Router } from 'express';
import db from '../db/index.js';
import { requireInvestisseur } from '../middleware/investisseurScope.js';

const router = Router();
router.use(requireInvestisseur);

const round2 = v => Math.round((v ?? 0) * 100) / 100;

router.get('/', (req, res) => {
  const annee    = req.query.annee || String(new Date().getFullYear() - 1);
  const scopeAll = req.query.scope === 'all';
  const invCond  = scopeAll
    ? 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'i.investisseur_id = ?';
  const invArg   = scopeAll ? req.user.id : req.investisseur.id;

  const recap = db.prepare(`
    SELECT
      COALESCE(SUM(r.interets_bruts),0)     AS interets_bruts,
      COALESCE(SUM(r.prelev_sociaux),0)     AS prelev_sociaux,
      COALESCE(SUM(r.prelev_forfaitaire),0) AS prelev_forfaitaire,
      COALESCE(SUM(r.net_recu),0)           AS net_recu,
      COUNT(*)                              AS nb_remboursements
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
  `).get(invArg, annee);

  const pertes = db.prepare(`
    SELECT i.id, i.nom_projet, p.nom AS plateforme_nom,
           i.montant_investi,
           COALESCE((SELECT SUM(r.capital) FROM remboursements r WHERE r.investissement_id = i.id),0) AS capital_rembourse,
           (i.montant_investi -
              COALESCE((SELECT SUM(r.capital) FROM remboursements r WHERE r.investissement_id = i.id),0)
           ) AS perte_capital,
           i.statut, i.updated_at
    FROM investissements i
    JOIN plateformes p ON p.id = i.plateforme_id
    WHERE ${invCond}
      AND i.statut IN ('en_retard','cloture')
      AND substr(i.updated_at,1,4) = ?
  `).all(invArg, annee);

  const pertesTotales = pertes.reduce((s, p) => s + Math.max(0, p.perte_capital), 0);

  const detail = db.prepare(`
    SELECT i.id AS investissement_id, i.nom_projet, p.nom AS plateforme_nom,
           inv.nom AS investisseur_nom,
           SUM(r.interets_bruts)     AS interets_bruts,
           SUM(r.prelev_sociaux)     AS prelev_sociaux,
           SUM(r.prelev_forfaitaire) AS prelev_forfaitaire,
           SUM(r.net_recu)           AS net_recu,
           COUNT(r.id)               AS nb_echeances
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN investisseurs inv ON inv.id = i.investisseur_id
    JOIN plateformes p ON p.id = i.plateforme_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
    GROUP BY i.id
    ORDER BY interets_bruts DESC
  `).all(invArg, annee);

  const corrCond = scopeAll
    ? 'c.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'c.investisseur_id = ?';

  const corrections = db.prepare(`
    SELECT c.id, c.date, c.montant, c.notes,
           p.nom AS plateforme_nom,
           inv.nom AS investisseur_nom
    FROM corrections_solde c
    JOIN plateformes p     ON p.id  = c.plateforme_id
    JOIN investisseurs inv ON inv.id = c.investisseur_id
    WHERE ${corrCond}
      AND substr(c.date,1,4) = ?
    ORDER BY c.date DESC
  `).all(invArg, annee);

  const totalCorrections = corrections.reduce((s, c) => s + c.montant, 0);

  const interetsNets = recap.interets_bruts - recap.prelev_sociaux - recap.prelev_forfaitaire;

  const recapTotal = {
    interets_bruts:          round2(recap.interets_bruts),
    prelev_sociaux:          round2(recap.prelev_sociaux),
    prelev_forfaitaire:      round2(recap.prelev_forfaitaire),
    interets_nets:           round2(interetsNets),
    interets_nets_corriges:  round2(interetsNets + totalCorrections),
    nb_remboursements:       recap.nb_remboursements,
    total_corrections:       round2(totalCorrections),
  };

  const cases = {
    case_2TR: round2(recap.interets_bruts),
    case_2CK: round2(recap.prelev_forfaitaire),
    case_2BH: round2(recap.interets_bruts),
    case_2BH_perte_capital: round2(pertesTotales),
    note: "Les cases sont indicatives. Verifiez avec votre situation fiscale reelle.",
  };

  res.json({ annee, recap: recapTotal, pertes, pertesTotales: round2(pertesTotales), detail, corrections, cases });
});

router.get('/export', (req, res) => {
  const annee    = req.query.annee || String(new Date().getFullYear() - 1);
  const scopeAll = req.query.scope === 'all';
  const invCond  = scopeAll
    ? 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'i.investisseur_id = ?';
  const invArg   = scopeAll ? req.user.id : req.investisseur.id;

  const rows = db.prepare(`
    SELECT i.nom_projet, p.nom AS plateforme,
           r.date_remb, r.capital, r.interets_bruts,
           r.prelev_sociaux, r.prelev_forfaitaire, r.net_recu, r.statut
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p ON p.id = i.plateforme_id
    WHERE ${invCond} AND substr(r.date_remb,1,4) = ?
    ORDER BY r.date_remb
  `).all(invArg, annee);

  const corrCond2 = scopeAll
    ? 'c.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'c.investisseur_id = ?';

  const corrRows = db.prepare(`
    SELECT c.notes AS nom_projet, p.nom AS plateforme, c.date AS date_remb,
           0 AS capital, 0 AS interets_bruts,
           0 AS prelev_sociaux, 0 AS prelev_forfaitaire,
           c.montant AS net_recu, 'correction_solde' AS statut
    FROM corrections_solde c
    JOIN plateformes p ON p.id = c.plateforme_id
    WHERE ${corrCond2} AND substr(c.date,1,4) = ?
    ORDER BY c.date
  `).all(invArg, annee);

  const header = ['Projet','Plateforme','Date','Capital','Interets bruts','Prelev sociaux','Impot revenu','Net recu','Statut'];
  const allRows = [...rows, ...corrRows];
  const csv = [
    header.join(';'),
    ...allRows.map(r => [
      esc(r.nom_projet), esc(r.plateforme), r.date_remb,
      r.capital, r.interets_bruts, r.prelev_sociaux, r.prelev_forfaitaire,
      r.net_recu, r.statut,
    ].join(';')),
  ].join('\n');

  res.setHeader('Content-Type', 'text/csv; charset=utf-8');
  res.setHeader('Content-Disposition', `attachment; filename="2778-SD-${annee}.csv"`);
  res.send('\uFEFF' + csv);
});

/* ── CERFA 2561 — synthèse par plateforme × investisseur ── */
router.get('/cerfa2561', (req, res) => {
  const annee    = req.query.annee || String(new Date().getFullYear() - 1);
  const scopeAll = req.query.scope === 'all';
  const invCond  = scopeAll
    ? 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'i.investisseur_id = ?';
  const invArg = scopeAll ? req.user.id : req.investisseur.id;

  const rows = db.prepare(`
    SELECT
      p.id   AS plateforme_id,
      p.nom  AS plateforme_nom,
      p.domiciliation,
      p.fiscalite,
      p.type_produit_fiscal,
      inv.id    AS investisseur_id,
      inv.nom   AS investisseur_nom,
      inv.prenom AS investisseur_prenom,
      COALESCE(SUM(r.interets_bruts),     0) AS interets_bruts,
      COALESCE(SUM(r.prelev_sociaux),     0) AS prelev_sociaux,
      COALESCE(SUM(r.prelev_forfaitaire), 0) AS prelev_forfaitaire
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p     ON p.id = i.plateforme_id
    JOIN investisseurs inv ON inv.id = i.investisseur_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
      AND r.type = 'normal'
    GROUP BY p.id, inv.id
    ORDER BY p.nom, inv.nom
  `).all(invArg, annee);

  // Pertes en capital par plateforme × investisseur
  const pertesRows = db.prepare(`
    SELECT
      p.id AS plateforme_id,
      i.investisseur_id,
      COALESCE(SUM(
        i.montant_investi -
        COALESCE((SELECT SUM(r2.capital) FROM remboursements r2 WHERE r2.investissement_id = i.id),0)
      ), 0) AS perte_capital
    FROM investissements i
    JOIN plateformes p ON p.id = i.plateforme_id
    WHERE ${invCond}
      AND i.statut IN ('en_retard','cloture')
      AND substr(i.updated_at,1,4) = ?
    GROUP BY p.id, i.investisseur_id
  `).all(invArg, annee);

  const pertesMap = {};
  for (const p of pertesRows) {
    pertesMap[`${p.plateforme_id}_${p.investisseur_id}`] = Math.max(0, p.perte_capital);
  }

  const lignes = rows.map(r => {
    const key          = `${r.plateforme_id}_${r.investisseur_id}`;
    const perteCapital = pertesMap[key] ?? 0;
    const isFlatTax    = r.domiciliation === 'FR' && r.fiscalite === 'flat_tax';
    const use2TR       = r.type_produit_fiscal === '2TR';
    const interetsNets = round2(r.interets_bruts - r.prelev_sociaux - r.prelev_forfaitaire);
    return {
      annee,
      plateforme_id:         r.plateforme_id,
      plateforme_nom:        r.plateforme_nom,
      domiciliation:         r.domiciliation,
      fiscalite:             r.fiscalite,
      type_produit_fiscal:   r.type_produit_fiscal,
      investisseur_id:       r.investisseur_id,
      investisseur_nom:      r.investisseur_nom,
      investisseur_prenom:   r.investisseur_prenom,
      interets_bruts:        round2(r.interets_bruts),
      prelev_sociaux:        round2(r.prelev_sociaux),
      prelev_forfaitaire:    round2(r.prelev_forfaitaire),
      interets_nets:         interetsNets,
      // Cases fiscales — d'après IFU réels :
      // 2TT ou 2TR = intérêts bruts (toutes plateformes)
      // 2BH = intérêts bruts si PS déjà prélevés (prelev_sociaux > 0)
      // 2CK = PFNL déjà versé (flat-tax FR uniquement)
      // 2TY = pertes en capital
      case_2TT: !use2TR ? Math.round(r.interets_bruts) : 0,
      case_2TR:  use2TR ? Math.round(r.interets_bruts) : 0,
      case_2BH:  r.prelev_sociaux > 0 ? Math.round(r.interets_bruts) : 0,
      case_2CK:  isFlatTax            ? Math.round(r.prelev_forfaitaire) : 0,
      case_2TY:  perteCapital > 0     ? Math.round(perteCapital) : 0,
    };
  });


  // Breakdown mensuel par plateforme × investisseur
  const moisRows = db.prepare(`
    SELECT
      p.id AS plateforme_id,
      i.investisseur_id,
      substr(r.date_remb,6,2) AS mois,
      COALESCE(SUM(r.interets_bruts),     0) AS interets_bruts,
      COALESCE(SUM(r.prelev_sociaux),     0) AS prelev_sociaux,
      COALESCE(SUM(r.prelev_forfaitaire), 0) AS prelev_forfaitaire
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p     ON p.id = i.plateforme_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
      AND r.type = 'normal'
    GROUP BY p.id, i.investisseur_id, mois
  `).all(invArg, annee);

  const moisMap = {};
  for (const m of moisRows) {
    const key = `${m.plateforme_id}_${m.investisseur_id}`;
    if (!moisMap[key]) moisMap[key] = {};
    moisMap[key][m.mois] = {
      interets_bruts:     round2(m.interets_bruts),
      prelev_sociaux:     round2(m.prelev_sociaux),
      prelev_forfaitaire: round2(m.prelev_forfaitaire),
    };
  }

  const lignesWithMois = lignes.map(l => ({
    ...l,
    mois: moisMap[`${l.plateforme_id}_${l.investisseur_id}`] ?? {},
  }));

  res.json({ annee, lignes: lignesWithMois });
});

/* ── CERFA 2561 — détail des remboursements par plateforme × investisseur ── */
router.get('/cerfa2561/remboursements', (req, res) => {
  const { annee, plateforme_id, investisseur_id } = req.query;
  if (!annee || !plateforme_id) return res.status(400).json({ error: 'annee et plateforme_id requis' });

  const scopeAll = req.query.scope === 'all';
  const invCond  = scopeAll
    ? 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'i.investisseur_id = ?';
  const invArg = scopeAll ? req.user.id : req.investisseur.id;

  const platCond = investisseur_id
    ? 'AND p.id = ? AND i.investisseur_id = ?'
    : 'AND p.id = ?';
  const platArgs = investisseur_id
    ? [Number(plateforme_id), Number(investisseur_id)]
    : [Number(plateforme_id)];

  const rows = db.prepare(`
    SELECT
      r.id, r.date_remb, r.capital, r.interets_bruts,
      r.prelev_sociaux, r.prelev_forfaitaire, r.interets_nets, r.net_recu,
      r.statut, r.notes,
      i.nom_projet
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p     ON p.id = i.plateforme_id
    WHERE ${invCond} ${platCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
      AND r.type = 'normal'
    ORDER BY r.date_remb
  `).all(invArg, ...platArgs, annee);

  res.json(rows);
});


/* ── Années disponibles ── */
router.get('/years', (req, res) => {
  const scopeAll = req.query.scope === 'all';
  let invWhere, invParams;

  if (scopeAll) {
    invWhere  = 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)';
    invParams = [req.user.id];
  } else {
    const invId = Number(req.header('X-Investisseur-Id'));
    if (!invId) return res.status(400).json({ error: 'Missing investisseur id' });
    invWhere  = 'i.investisseur_id = ?';
    invParams = [invId];
  }

  const rows = db.prepare(`
    SELECT DISTINCT strftime('%Y', r.date_remb) AS annee
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    WHERE ${invWhere}
      AND r.type = 'normal'
    ORDER BY annee DESC
  `).all(...invParams);

  res.json(rows.map(r => r.annee));
});



/* ── 2778-SD — matrice mensuelle par plateforme étrangère ── */
router.get('/2778', (req, res) => {
  const annee    = req.query.annee || String(new Date().getFullYear() - 1);
  const scopeAll = req.query.scope === 'all';
  const invCond  = scopeAll
    ? 'i.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)'
    : 'i.investisseur_id = ?';
  const invArg = scopeAll ? req.user.id : req.investisseur.id;

  // Plateformes étrangères × investisseur avec au moins un remboursement sur l'année
  const platRows = db.prepare(`
    SELECT DISTINCT p.id, p.nom, inv.id AS investisseur_id, inv.nom AS investisseur_nom, inv.prenom AS investisseur_prenom
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p     ON p.id = i.plateforme_id
    JOIN investisseurs inv ON inv.id = i.investisseur_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
      AND r.type = 'normal'
      AND p.domiciliation != 'FR'
    ORDER BY p.nom, inv.nom
  `).all(invArg, annee);

  // Montants mensuels par plateforme × investisseur
  const moisRows = db.prepare(`
    SELECT
      p.id AS plateforme_id,
      i.investisseur_id,
      substr(r.date_remb,6,2) AS mois,
      COALESCE(SUM(
        CASE WHEN r.interets_bruts_avant_local IS NOT NULL AND r.interets_bruts_avant_local > 0
             THEN r.interets_bruts_avant_local
             ELSE r.interets_bruts
        END
      ), 0) AS montant
    FROM remboursements r
    JOIN investissements i ON i.id = r.investissement_id
    JOIN plateformes p     ON p.id = i.plateforme_id
    WHERE ${invCond}
      AND substr(r.date_remb,1,4) = ?
      AND r.statut IN ('paye','partiel')
      AND r.type = 'normal'
      AND p.domiciliation != 'FR'
    GROUP BY p.id, i.investisseur_id, mois
  `).all(invArg, annee);

  const moisMap = {};
  for (const m of moisRows) {
    const key = `${m.plateforme_id}_${m.investisseur_id}`;
    if (!moisMap[key]) moisMap[key] = {};
    moisMap[key][m.mois] = round2(m.montant);
  }

  const plateformes = platRows.map(p => ({
    id:                 `${p.id}_${p.investisseur_id}`,
    plateforme_id:      p.id,
    nom:                p.nom,
    investisseur_id:    p.investisseur_id,
    investisseur_nom:   p.investisseur_nom,
    investisseur_prenom: p.investisseur_prenom,
    mois: moisMap[`${p.id}_${p.investisseur_id}`] ?? {},
  }));

  res.json({ annee, plateformes });
});

export default router;
