import { Router } from 'express';
import multer from 'multer';
import db from '../db/index.js';
import { createZip, readZip } from '../utils/zip.js';

const router = Router();

const zipStorage = multer.memoryStorage();
const zipUpload  = multer({ storage: zipStorage, limits: { fileSize: 5 * 1024 * 1024 } });

/* GET /api/pfu */
router.get('/', (req, res) => {
  const rows = db.prepare('SELECT * FROM taux_pfu ORDER BY annee ASC').all();
  res.json(rows);
});

/* GET /api/pfu/export-zip — export ZIP fiscal (PFU + crédit d'impôt) */
router.get('/export-zip', (req, res, next) => {
  try {
    const pfu = db.prepare('SELECT * FROM taux_pfu ORDER BY annee ASC').all();
    const tci = db.prepare('SELECT * FROM taux_credit_impot ORDER BY nom_pays ASC').all();

    const manifest = {
      version: '1.0',
      app: 'crowdlending',
      exported_at: new Date().toISOString(),
      type: 'fiscal-referentiel',
    };

    const pfuData = pfu.map(r => ({
      annee: r.annee,
      impot_revenu: r.impot_revenu,
      csg: r.csg,
      crds: r.crds,
      solidarite: r.solidarite,
    }));

    const tciData = tci.map(r => ({
      nom_pays: r.nom_pays,
      code_pays: r.code_pays,
      div_taux: r.div_taux,
      div_taux_alt: r.div_taux_alt,
      div_taux_alt_label: r.div_taux_alt_label,
      div_exclusif_residence: r.div_exclusif_residence,
      int_taux: r.int_taux,
      int_taux_alt: r.int_taux_alt,
      int_taux_alt_label: r.int_taux_alt_label,
      int_exclusif_residence: r.int_exclusif_residence,
      notice: r.notice,
      statut_convention: r.statut_convention,
      date_suspension: r.date_suspension,
      ref_boi: r.ref_boi,
    }));

    const entries = [
      { name: 'manifest.json',          data: JSON.stringify(manifest, null, 2) },
      { name: 'pfu.json',               data: JSON.stringify(pfuData,  null, 2) },
      { name: 'taux_credit_impot.json', data: JSON.stringify(tciData,  null, 2) },
    ];

    const zipBuf = createZip(entries);
    const slug   = 'fiscal-referentiel-' + new Date().toISOString().slice(0, 10);
    res.setHeader('Content-Type', 'application/zip');
    res.setHeader('Content-Disposition', `attachment; filename="${slug}.zip"`);
    res.send(zipBuf);
  } catch (e) { next(e); }
});

/* POST /api/pfu/import-zip — import ZIP fiscal (PFU + crédit d'impôt) */
router.post('/import-zip', zipUpload.single('file'), (req, res, next) => {
  try {
    if (!req.file) return res.status(400).json({ error: 'Fichier ZIP manquant' });
    const zipEntries = readZip(req.file.buffer);

    const pfuEntry = zipEntries.find(e => e.name === 'pfu.json');
    const tciEntry = zipEntries.find(e => e.name === 'taux_credit_impot.json');
    if (!pfuEntry && !tciEntry) {
      return res.status(400).json({ error: 'ZIP invalide : aucun fichier reconnu' });
    }

    let pfuCreated = 0, pfuUpdated = 0;
    let tciCreated = 0, tciUpdated = 0;

    const tx = db.transaction(() => {
      if (pfuEntry) {
        const rows = JSON.parse(pfuEntry.data.toString('utf8'));
        for (const r of rows) {
          if (!r.annee) continue;
          const ps    = Number(r.csg || 0) + Number(r.crds || 0) + Number(r.solidarite || 0);
          const total = Number(r.impot_revenu || 0) + ps;
          const ex = db.prepare('SELECT id FROM taux_pfu WHERE annee = ?').get(Number(r.annee));
          if (ex) {
            db.prepare(
              `UPDATE taux_pfu SET pfu_total=?, impot_revenu=?, prelev_sociaux=?, csg=?, crds=?, solidarite=?, updated_at=datetime('now') WHERE id=?`
            ).run(total, Number(r.impot_revenu), ps, Number(r.csg), Number(r.crds), Number(r.solidarite), ex.id);
            pfuUpdated++;
          } else {
            db.prepare(
              'INSERT INTO taux_pfu (annee, pfu_total, impot_revenu, prelev_sociaux, csg, crds, solidarite) VALUES (?,?,?,?,?,?,?)'
            ).run(Number(r.annee), total, Number(r.impot_revenu), ps, Number(r.csg), Number(r.crds), Number(r.solidarite));
            pfuCreated++;
          }
        }
      }

      if (tciEntry) {
        const rows = JSON.parse(tciEntry.data.toString('utf8'));
        for (const r of rows) {
          if (!r.nom_pays) continue;
          const ex = db.prepare(
            'SELECT id FROM taux_credit_impot WHERE LOWER(nom_pays) = LOWER(?) OR (code_pays IS NOT NULL AND code_pays = ?)'
          ).get(r.nom_pays, r.code_pays || '');
          const vals = [
            r.nom_pays, r.code_pays || null,
            r.div_taux ?? null, r.div_taux_alt ?? null, r.div_taux_alt_label || null,
            r.div_exclusif_residence ? 1 : 0,
            r.int_taux ?? null, r.int_taux_alt ?? null, r.int_taux_alt_label || null,
            r.int_exclusif_residence ? 1 : 0,
            r.notice || null, r.statut_convention || 'active',
            r.date_suspension || null, r.ref_boi || null,
          ];
          if (ex) {
            db.prepare(
              `UPDATE taux_credit_impot SET
                nom_pays=?, code_pays=?,
                div_taux=?, div_taux_alt=?, div_taux_alt_label=?, div_exclusif_residence=?,
                int_taux=?, int_taux_alt=?, int_taux_alt_label=?, int_exclusif_residence=?,
                notice=?, statut_convention=?, date_suspension=?, ref_boi=?,
                updated_at=datetime('now') WHERE id=?`
            ).run(...vals, ex.id);
            tciUpdated++;
          } else {
            db.prepare(
              `INSERT INTO taux_credit_impot
                (nom_pays, code_pays, div_taux, div_taux_alt, div_taux_alt_label, div_exclusif_residence,
                 int_taux, int_taux_alt, int_taux_alt_label, int_exclusif_residence,
                 notice, statut_convention, date_suspension, ref_boi)
                VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
            ).run(...vals);
            tciCreated++;
          }
        }
      }
    });
    tx();

    res.json({
      ok: true,
      pfu: { created: pfuCreated, updated: pfuUpdated },
      tci: { created: tciCreated, updated: tciUpdated },
    });
  } catch (e) { next(e); }
});

/* POST /api/pfu */
router.post('/', (req, res) => {
  const { annee, impot_revenu, csg, crds, solidarite } = req.body;
  if (!annee || impot_revenu == null || csg == null || crds == null || solidarite == null) {
    return res.status(400).json({ error: 'Champs requis : annee, impot_revenu, csg, crds, solidarite' });
  }
  const prelev_sociaux = Number(csg) + Number(crds) + Number(solidarite);
  const pfu_total      = Number(impot_revenu) + prelev_sociaux;
  try {
    const result = db.prepare(
      'INSERT INTO taux_pfu (annee, pfu_total, impot_revenu, prelev_sociaux, csg, crds, solidarite) VALUES (?, ?, ?, ?, ?, ?, ?)'
    ).run(Number(annee), pfu_total, Number(impot_revenu), prelev_sociaux, Number(csg), Number(crds), Number(solidarite));
    res.status(201).json(db.prepare('SELECT * FROM taux_pfu WHERE id = ?').get(result.lastInsertRowid));
  } catch (e) {
    if (e.message?.includes('UNIQUE')) return res.status(409).json({ error: `L'année ${annee} existe déjà.` });
    throw e;
  }
});

/* PUT /api/pfu/:id */
router.put('/:id', (req, res) => {
  const { annee, impot_revenu, csg, crds, solidarite } = req.body;
  if (!annee || impot_revenu == null || csg == null || crds == null || solidarite == null) {
    return res.status(400).json({ error: 'Champs requis : annee, impot_revenu, csg, crds, solidarite' });
  }
  const prelev_sociaux = Number(csg) + Number(crds) + Number(solidarite);
  const pfu_total      = Number(impot_revenu) + prelev_sociaux;
  try {
    db.prepare(
      `UPDATE taux_pfu SET annee=?, pfu_total=?, impot_revenu=?, prelev_sociaux=?,
       csg=?, crds=?, solidarite=?, updated_at=datetime('now') WHERE id=?`
    ).run(Number(annee), pfu_total, Number(impot_revenu), prelev_sociaux,
          Number(csg), Number(crds), Number(solidarite), Number(req.params.id));
    const row = db.prepare('SELECT * FROM taux_pfu WHERE id = ?').get(Number(req.params.id));
    if (!row) return res.status(404).json({ error: 'Introuvable' });
    res.json(row);
  } catch (e) {
    if (e.message?.includes('UNIQUE')) return res.status(409).json({ error: `L'année ${annee} existe déjà.` });
    throw e;
  }
});

/* DELETE /api/pfu/:id */
router.delete('/:id', (req, res) => {
  db.prepare('DELETE FROM taux_pfu WHERE id = ?').run(Number(req.params.id));
  res.status(204).end();
});

export default router;
