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

const router = Router();

const Schema = z.object({
  investisseur_id: z.number().int().positive().optional(),
  plateforme_id: z.number().int().positive(),
  date_operation: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  type: z.enum(['depot', 'retrait']),
  montant: z.number().nonnegative(),
  libelle: z.string().optional(),
  reference: z.string().optional(),
  notes: z.string().optional(),
});

/** Résout l'investisseur_id : body en priorité (validé), sinon header */
function resolveInvestisseurId(req, bodyInvestisseurId) {
  if (!bodyInvestisseurId) return req.investisseur.id;
  const row = db.prepare('SELECT id FROM investisseurs WHERE id = ? AND user_id = ?')
    .get(bodyInvestisseurId, req.user.id);
  if (!row) throw new HttpError(403, 'Investisseur non autorisé');
  return bodyInvestisseurId;
}

/**
 * GET /api/depots-retraits
 *
 * ?scope=all  → agrège tous les investisseurs de l'utilisateur (vue "Famille")
 * (défaut)    → filtre sur l'investisseur donné par X-Investisseur-Id
 */
router.get('/', (req, res) => {
  const scopeAll = req.query.scope === 'all';
  const userId = req.user.id;

  let invCond, args;
  if (scopeAll) {
    invCond = 'dr.investisseur_id IN (SELECT id FROM investisseurs WHERE user_id = ?)';
    args = [userId];
  } else {
    const raw = req.header('X-Investisseur-Id');
    const id = Number(raw);
    if (!id) return res.status(400).json({ error: 'Missing investisseur id (header X-Investisseur-Id)' });
    const row = db.prepare('SELECT id FROM investisseurs WHERE id = ? AND user_id = ?').get(id, userId);
    if (!row) return res.status(403).json({ error: 'Investisseur not found or not owned by user' });
    invCond = 'dr.investisseur_id = ?';
    args = [id];
  }

  const { from, to, type, plateforme_id } = req.query;
  const conds = [invCond];
  if (from) { conds.push('dr.date_operation >= ?'); args.push(from); }
  if (to)   { conds.push('dr.date_operation <= ?'); args.push(to); }
  if (type) { conds.push('dr.type = ?');           args.push(type); }
  if (plateforme_id) { conds.push('dr.plateforme_id = ?'); args.push(Number(plateforme_id)); }

  const rows = db.prepare(`
    SELECT dr.*, p.nom AS plateforme_nom,
           plat_inv.nom AS plateforme_detenteur_nom
    FROM depots_retraits dr
    JOIN plateformes p ON p.id = dr.plateforme_id
    LEFT JOIN investisseurs plat_inv ON plat_inv.id = p.investisseur_id
    WHERE ${conds.join(' AND ')}
    ORDER BY dr.date_operation DESC, dr.id DESC
  `).all(...args);
  res.json(rows);
});

router.post('/', requireInvestisseur, (req, res, next) => {
  try {
    const body = Schema.parse(req.body);
    const investisseurId = resolveInvestisseurId(req, body.investisseur_id);
    const r = db.prepare(`
      INSERT INTO depots_retraits
        (investisseur_id, plateforme_id, date_operation, type, montant, libelle, reference, source, notes)
      VALUES (?,?,?,?,?,?,?, 'manuel', ?)
    `).run(
      investisseurId, body.plateforme_id, body.date_operation, body.type,
      body.montant, body.libelle || null, body.reference || null, body.notes || null,
    );
    res.status(201).json({ id: r.lastInsertRowid, ...body });
  } catch (e) { next(e); }
});

router.put('/:id', requireInvestisseur, (req, res, next) => {
  try {
    const body = Schema.parse(req.body);
    const investisseurId = resolveInvestisseurId(req, body.investisseur_id);
    const r = db.prepare(`
      UPDATE depots_retraits
      SET investisseur_id=?, plateforme_id=?, date_operation=?, type=?, montant=?,
          libelle=?, reference=?, notes=?, updated_at=datetime('now')
      WHERE id=? AND investisseur_id IN (SELECT id FROM investisseurs WHERE user_id=?)
    `).run(
      investisseurId, body.plateforme_id, body.date_operation, body.type, body.montant,
      body.libelle || null, body.reference || null, body.notes || null,
      req.params.id, req.user.id,
    );
    if (r.changes === 0) throw new HttpError(404, 'Not found');
    res.json({ id: Number(req.params.id), ...body });
  } catch (e) { next(e); }
});

router.delete('/:id', requireInvestisseur, (req, res, next) => {
  try {
    const r = db.prepare(`
      DELETE FROM depots_retraits
      WHERE id=? AND investisseur_id IN (SELECT id FROM investisseurs WHERE user_id=?)
    `).run(req.params.id, req.user.id);
    if (r.changes === 0) throw new HttpError(404, 'Not found');
    res.status(204).end();
  } catch (e) { next(e); }
});

export default router;
