import express from "express";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
import bcrypt from "bcryptjs";
import db from "./db.js";
import { signToken, requireAuth } from "./auth.js";

const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.json());

// Serve Vue build in production
const distPath = join(__dirname, "../dist");
app.use(express.static(distPath));

// ── Auth ──────────────────────────────────────────────────────────────────

app.post("/api/auth/login", (req, res) => {
  const { username, password } = req.body;
  if (!username || !password)
    return res.status(400).json({ error: "Faltan credenciales" });

  const user = db
    .prepare("SELECT * FROM users WHERE username = ?")
    .get(username.toLowerCase());

  if (!user || !bcrypt.compareSync(password, user.passwordHash))
    return res.status(401).json({ error: "Usuario o contraseña incorrectos" });

  const token = signToken({
    id: user.id,
    username: user.username,
    role: user.role,
  });
  res.json({
    token,
    user: { id: user.id, username: user.username, role: user.role },
  });
});

app.get("/api/auth/me", requireAuth, (req, res) => {
  res.json({ user: req.user });
});

// ── Users (admin only) ────────────────────────────────────────────────────

app.get("/api/users", requireAuth, (_req, res) => {
  const users = db
    .prepare(
      "SELECT id, username, role, createdAt FROM users ORDER BY createdAt",
    )
    .all();
  res.json(users);
});

app.post("/api/users", requireAuth, (req, res) => {
  const { username, password, role = "admin" } = req.body;
  if (!username || !password)
    return res.status(400).json({ error: "Faltan campos obligatorios" });

  const existing = db
    .prepare("SELECT id FROM users WHERE username = ?")
    .get(username.toLowerCase());
  if (existing) return res.status(409).json({ error: "El usuario ya existe" });

  const passwordHash = bcrypt.hashSync(password, 10);
  const info = db
    .prepare(
      "INSERT INTO users (username, passwordHash, role) VALUES (?, ?, ?)",
    )
    .run(username.toLowerCase(), passwordHash, role);
  res.status(201).json({ id: info.lastInsertRowid, username, role });
});

app.put("/api/users/:id/password", requireAuth, (req, res) => {
  const { password } = req.body;
  if (!password) return res.status(400).json({ error: "Falta la contraseña" });

  const passwordHash = bcrypt.hashSync(password, 10);
  const info = db
    .prepare("UPDATE users SET passwordHash = ? WHERE id = ?")
    .run(passwordHash, req.params.id);
  if (info.changes === 0) return res.status(404).json({ error: "Not found" });
  res.json({ ok: true });
});

app.delete("/api/users/:id", requireAuth, (req, res) => {
  const remaining = db.prepare("SELECT COUNT(*) as n FROM users").get().n;
  if (remaining <= 1)
    return res
      .status(400)
      .json({ error: "No se puede eliminar el último usuario" });
  db.prepare("DELETE FROM users WHERE id = ?").run(req.params.id);
  res.json({ ok: true });
});

// ── Students ──────────────────────────────────────────────────────────────

app.get("/api/students", requireAuth, (_req, res) => {
  res.json(
    db.prepare("SELECT * FROM students ORDER BY lastName, firstName").all(),
  );
});

app.post("/api/students", requireAuth, (req, res) => {
  const { id, firstName, lastName, age, sex, weight, height, imc } = req.body;
  db.prepare(
    `
    INSERT INTO students (id, firstName, lastName, age, sex, weight, height, imc)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  `,
  ).run(id, firstName, lastName, age, sex, weight, height, imc);
  res.status(201).json({ id });
});

app.put("/api/students/:id", requireAuth, (req, res) => {
  const { firstName, lastName, age, sex, weight, height, imc } = req.body;
  const info = db
    .prepare(
      `
    UPDATE students SET firstName=?, lastName=?, age=?, sex=?, weight=?, height=?, imc=?
    WHERE id=?
  `,
    )
    .run(firstName, lastName, age, sex, weight, height, imc, req.params.id);
  if (info.changes === 0) return res.status(404).json({ error: "Not found" });
  res.json({ ok: true });
});

app.delete("/api/students/:id", requireAuth, (req, res) => {
  // CASCADE deletes linked activities automatically (FK ON DELETE CASCADE)
  db.prepare("DELETE FROM students WHERE id=?").run(req.params.id);
  res.json({ ok: true });
});

// ── Activities ────────────────────────────────────────────────────────────

app.get("/api/activities", requireAuth, (_req, res) => {
  res.json(
    db.prepare("SELECT * FROM activities ORDER BY createdAt DESC").all(),
  );
});

app.post("/api/activities", requireAuth, (req, res) => {
  const {
    id,
    studentId,
    type,
    durationInput,
    durationUnit,
    duration,
    displayDuration,
    intensity,
    lifestyle,
    anxiety,
    grade,
    date,
  } = req.body;
  db.prepare(
    `
    INSERT INTO activities
      (id, studentId, type, durationInput, durationUnit, duration, displayDuration, intensity, lifestyle, anxiety, grade, date)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  `,
  ).run(
    id,
    studentId,
    type,
    durationInput,
    durationUnit,
    duration,
    displayDuration,
    intensity,
    lifestyle,
    anxiety ?? 0,
    grade,
    date,
  );
  res.status(201).json({ id });
});

app.put("/api/activities/:id", requireAuth, (req, res) => {
  const {
    type,
    durationInput,
    durationUnit,
    duration,
    displayDuration,
    intensity,
    lifestyle,
    anxiety,
    grade,
    date,
  } = req.body;
  const info = db
    .prepare(
      `
    UPDATE activities
    SET type=?, durationInput=?, durationUnit=?, duration=?, displayDuration=?,
        intensity=?, lifestyle=?, anxiety=?, grade=?, date=?
    WHERE id=?
  `,
    )
    .run(
      type,
      durationInput,
      durationUnit,
      duration,
      displayDuration,
      intensity,
      lifestyle,
      anxiety ?? 0,
      grade,
      date,
      req.params.id,
    );
  if (info.changes === 0) return res.status(404).json({ error: "Not found" });
  res.json({ ok: true });
});

app.delete("/api/activities/:id", requireAuth, (req, res) => {
  db.prepare("DELETE FROM activities WHERE id=?").run(req.params.id);
  res.json({ ok: true });
});

// ── SPA fallback ──────────────────────────────────────────────────────────
app.get("*", (_req, res) => {
  res.sendFile(join(distPath, "index.html"));
});

app.listen(PORT, () => console.log(`SB Sports API running on :${PORT}`));
