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

const router = Router();

const TYPES_VALIDES = ['etoiles', 'lettres', 'score', 'custom'];

/** Valide et normalise un critère entrant */
function parseBody(body) {
  const { plateforme_id, nom, type = 'etoiles', valeurs, min_val, max_val, description, ordre } = body;
  if (!plateforme_id) throw new HttpError(400, 'plateforme_id est requis');
  if (!nom?.trim())   throw new HttpError(400, 'nom est requis');
  if (!TYPES_VALIDES.includes(type)) throw new HttpError(400, `type invalide — attendu : ${TYPES_VALIDES.join(', ')}`);

  // Validation selon le type
  if (type === 'score') {
    if (min_val === undefined || max_val === undefined) throw new HttpError(400, 'min_val et max_val requis pour le type score');
    if (Number(min_val) >= Number(max_val)) throw new HttpError(400, 'min_val doit être inférieur à max_val');
  }
  if ((type === 'lettres' || type === 'custom') && (!valeurs || !valeurs.length)) {
    throw new HttpError(400, `valeurs est requis pour le type ${type}`);
  }

  return {
    plateforme_id: Number(plateforme_id),
    nom:          nom.trim(),
    type,
    valeurs:      (type === 'lettres' || type === 'custom')
                    ? JSON.stringify(Array.isArray(valeurs) ? valeurs : valeurs.split(',').map(v => v.trim()).filter(Boolean))
                    : null,
    min_val:      type === 'score' ? Number(min_val) : null,
    max_val:      type === 'score' ? Number(max_val) : null,
    description:  description?.trim() || null,
    ordre:        Number(ordre ?? 0),
  };
}

/** Enrichit les lignes DB (parse valeurs JSON) */
function enrich(row) {
  return {
    ...row,
    valeurs: row.valeurs ? JSON.parse(row.valeurs) : null,
  };
}

/* ── GET /api/notation?plateforme_id=X ───────────────────────── */
router.get('/', (req, res) => {
  const { plateforme_id } = req.query;
  if (plateforme_id) {
    const rows = db.prepare(`
      SELECT nc.* FROM notation_criteres nc
      JOIN plateformes p ON p.id = nc.plateforme_id
      WHERE nc.plateforme_id = ? AND p.user_id = ?
      ORDER BY nc.ordre, nc.id
    `).all(Number(plateforme_id), req.user.id);
    return res.json(rows.map(enrich));
  }
  // Tous les critères de l'utilisateur (toutes plateformes)
  const rows = db.prepare(`
    SELECT nc.*, p.nom AS plateforme_nom FROM notation_criteres nc
    JOIN plateformes p ON p.id = nc.plateforme_id
    WHERE p.user_id = ?
    ORDER BY p.nom, nc.ordre, nc.id
  `).all(req.user.id);
  res.json(rows.map(enrich));
});

/* ── POST /api/notation ──────────────────────────────────────── */
router.post('/', (req, res, next) => {
  try {
    const data = parseBody(req.body);
    // Vérifie que la plateforme appartient à l'utilisateur
    const plat = db.prepare('SELECT id FROM plateformes WHERE id = ? AND user_id = ?')
      .get(data.plateforme_id, req.user.id);
    if (!plat) throw new HttpError(404, 'Plateforme introuvable');

    const r = db.prepare(`
      INSERT INTO notation_criteres (plateforme_id, nom, type, valeurs, min_val, max_val, description, ordre)
      VALUES (?,?,?,?,?,?,?,?)
    `).run(data.plateforme_id, data.nom, data.type, data.valeurs, data.min_val, data.max_val, data.description, data.ordre);

    const created = enrich(db.prepare('SELECT * FROM notation_criteres WHERE id = ?').get(r.lastInsertRowid));
    res.status(201).json(created);
  } catch (e) { next(e); }
});

/* ── PUT /api/notation/:id ───────────────────────────────────── */
router.put('/:id', (req, res, next) => {
  try {
    const existing = db.prepare(`
      SELECT nc.* FROM notation_criteres nc
      JOIN plateformes p ON p.id = nc.plateforme_id
      WHERE nc.id = ? AND p.user_id = ?
    `).get(req.params.id, req.user.id);
    if (!existing) throw new HttpError(404, 'Critère introuvable');

    const data = parseBody({ ...req.body, plateforme_id: existing.plateforme_id });
    db.prepare(`
      UPDATE notation_criteres
      SET nom=?, type=?, valeurs=?, min_val=?, max_val=?, description=?, ordre=?
      WHERE id=?
    `).run(data.nom, data.type, data.valeurs, data.min_val, data.max_val, data.description, data.ordre, req.params.id);

    res.json(enrich(db.prepare('SELECT * FROM notation_criteres WHERE id = ?').get(req.params.id)));
  } catch (e) { next(e); }
});

/* ── DELETE /api/notation/:id ────────────────────────────────── */
router.delete('/:id', (req, res, next) => {
  try {
    const existing = db.prepare(`
      SELECT nc.id FROM notation_criteres nc
      JOIN plateformes p ON p.id = nc.plateforme_id
      WHERE nc.id = ? AND p.user_id = ?
    `).get(req.params.id, req.user.id);
    if (!existing) throw new HttpError(404, 'Critère introuvable');
    db.prepare('DELETE FROM notation_criteres WHERE id = ?').run(req.params.id);
    res.json({ deleted: true });
  } catch (e) { next(e); }
});

/* ── PUT /api/notation/reorder ───────────────────────────────── */
router.put('/reorder', (req, res, next) => {
  try {
    const { ids } = req.body; // tableau d'ids dans le nouvel ordre
    if (!Array.isArray(ids)) throw new HttpError(400, 'ids[] requis');
    const upd = db.prepare('UPDATE notation_criteres SET ordre = ? WHERE id = ?');
    const tx  = db.transaction(() => ids.forEach((id, i) => upd.run(i, id)));
    tx();
    res.json({ reordered: true });
  } catch (e) { next(e); }
});

export default router;
