const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const User = require('./user');
const multer = require('multer');
const path = require('path');

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/music');
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
    cb(null, uniqueSuffix + path.extname(file.originalname));
  }
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 10 * 1024 * 1024 },
  fileFilter: function (req, file, cb) {
    if (!file.originalname.match(/\.(mp3)$/)) {
      return cb(new Error('Solo se permiten archivos .mp3'));
    }
    cb(null, true);
  }
});

const routineSchema = new mongoose.Schema({
  title: String,
  createdBy: { type: String, default: "coach-id-ejemplo" },
  duration: Number,
  musicUrl: { type: String, default: "" },
  nombreCompetencia: String,
  tipoCompetencia: { type: String, enum: ['libre', 'técnica'], default: 'libre' },
  modalidad: { type: String, enum: ['solo', 'duo', 'equipo'], default: 'solo' },
  tipoPiscina: { type: String, enum: ['olimpica', 'semiolimpica', 'fosa'], default: 'olimpica' },
  participantes: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
  elements: [],
  formaciones: [
    {
      nombreColoquial: String,
      notasTacticas: String,
      duracion: Number,
      atletas: [
        {
          atletaId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
          idPersonalizado: String,
          x: Number,
          y: Number,
          rol: String,
          grupo: String,
          direccion: {
            x1: Number,
            y1: Number,
            x2: Number,
            y2: Number
          },
          figura: String,
          tipoElemento: { type: String, enum: ['TRE', 'híbrido', 'transición'], default: 'transición' },
          codigoElemento: String
        }
      ]
    }
  ],
  createdAt: { type: Date, default: Date.now }
});

const Routine = mongoose.model('Routine', routineSchema);

// GET todas las rutinas
router.get('/', async (req, res) => {
  try {
    const routines = await Routine.find()
      .populate('participantes', 'name')
      .populate('formaciones.atletas.atletaId', 'name');
    res.json(routines);
  } catch (error) {
    res.status(500).json({ message: 'Error al obtener rutinas', error });
  }
});

// POST nueva rutina
router.post('/', async (req, res) => {
  try {
    const newRoutine = new Routine(req.body);
    await newRoutine.save();
    res.status(201).json({ message: 'Rutina guardada exitosamente', routine: newRoutine });
  } catch (error) {
    res.status(500).json({ message: 'Error al guardar la rutina', error });
  }
});

// GET rutina por ID
router.get('/:id', async (req, res) => {
  try {
    const routine = await Routine.findById(req.params.id)
      .populate('participantes', 'name')
      .populate('formaciones.atletas.atletaId', 'name');
    if (!routine) return res.status(404).json({ error: 'Rutina no encontrada' });
    res.json(routine);
  } catch (error) {
    res.status(500).json({ error: 'Error al cargar rutina', details: error });
  }
});

// POST agregar formación (corregido y robusto)
router.post('/:id/formations', async (req, res) => {
  const { id } = req.params;
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).json({ error: 'ID inválido para rutina' });
  }

  try {
    const rutina = await Routine.findById(id);
    if (!rutina) return res.status(404).json({ error: 'Rutina no encontrada' });

    const formacionLimpia = {
      ...req.body,
      atletas: req.body.atletas.map(a => {
        const rawId = typeof a.atletaId === 'object' && a.atletaId?.id ? a.atletaId.id : a.atletaId;

        return {
          ...a,
          atletaId: mongoose.Types.ObjectId.isValid(rawId)
            ? new mongoose.Types.ObjectId(rawId)
            : undefined
        };
      }).filter(a => a.atletaId !== undefined)
    };

    rutina.formaciones.push(formacionLimpia);

    formacionLimpia.atletas.forEach(({ atletaId }) => {
      if (
        atletaId &&
        mongoose.Types.ObjectId.isValid(atletaId) &&
        !rutina.participantes.map(p => p.toString()).includes(atletaId.toString())
      ) {
        rutina.participantes.push(atletaId);
      }
    });

    await rutina.save();
    res.status(200).json({ message: 'Formación agregada exitosamente' });
  } catch (error) {
    console.error('Error al guardar formación:', error);
    res.status(500).json({ error: 'Error al guardar formación', details: error });
  }
});

// GET formaciones de rutina
router.get('/:id/formations', async (req, res) => {
  try {
    const rutina = await Routine.findById(req.params.id)
      .populate('formaciones.atletas.atletaId', 'name');
    if (!rutina) return res.status(404).json({ error: 'Rutina no encontrada' });

    res.status(200).json(rutina.formaciones);
  } catch (error) {
    res.status(500).json({ error: 'Error al obtener formaciones', details: error });
  }
});

// PUT editar formación por índice
router.put('/:id/formations/:index', async (req, res) => {
  const { id, index } = req.params;

  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).json({ error: 'ID inválido' });
  }

  const i = parseInt(index);
  if (isNaN(i) || i < 0) {
    return res.status(400).json({ error: 'Índice de formación inválido' });
  }

  try {
    const rutina = await Routine.findById(id);
    if (!rutina) return res.status(404).json({ error: 'Rutina no encontrada' });

    rutina.formaciones[i] = req.body;
    await rutina.save();
    res.status(200).json({ message: 'Formación actualizada correctamente' });
  } catch (error) {
    res.status(500).json({ error: 'Error al actualizar formación', details: error });
  }
});

// POST para actualizar tamaño de piscina
router.post('/:id/piscina', async (req, res) => {
  const { width, height } = req.body;
  try {
    const updated = await Routine.findByIdAndUpdate(
      req.params.id,
      { $set: { 'piscina.width': width, 'piscina.height': height } },
      { new: true }
    );
    if (!updated) return res.status(404).json({ message: 'Rutina no encontrada' });
    res.json({ message: 'Piscina actualizada', rutina: updated });
  } catch (error) {
    res.status(500).json({ message: 'Error al actualizar piscina', error });
  }
});

// PUT actualizar todas las formaciones (reordenamiento)
router.put('/:id', async (req, res) => {
  const { id } = req.params;
  const { formaciones } = req.body;

  try {
    const rutina = await Routine.findById(id);
    if (!rutina) return res.status(404).json({ error: 'Rutina no encontrada' });

    rutina.formaciones = formaciones;
    await rutina.save();

    res.status(200).json({ message: 'Formaciones reordenadas correctamente' });
  } catch (error) {
    res.status(500).json({ message: 'Error al actualizar orden', error });
  }
});

// POST subir música MP3
router.post('/upload/music', upload.single('music'), (req, res) => {
  if (!req.file) {
    return res.status(400).json({ error: 'No se subió ningún archivo' });
  }

  const fileUrl = `/uploads/music/${req.file.filename}`;
  res.status(200).json({ url: fileUrl });
});

router.delete('/:id', async (req, res) => {
  const { id } = req.params;

  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).json({ error: 'ID inválido' });
  }

  try {
    const deleted = await Routine.findByIdAndDelete(id);
    if (!deleted) {
      return res.status(404).json({ error: 'Rutina no encontrada' });
    }

    res.status(200).json({ message: 'Rutina eliminada exitosamente' });
  } catch (error) {
    console.error('Error al eliminar rutina:', error);
    res.status(500).json({ error: 'Error al eliminar rutina', details: error });
  }
});

// GET rutinas asignadas a un atleta
router.get('/atleta/:id', async (req, res) => {
  const atletaId = req.params.id;
  try {
    const rutinas = await Routine.find({ participantes: atletaId })
      .populate('participantes', 'name')
      .populate('formaciones.atletas.atletaId', 'name');

    // Filtrar solo rutinas donde realmente aparece en alguna formación
    const filtradas = rutinas.filter(rutina =>
      rutina.formaciones.some(f =>
        f.atletas.some(a => a.atletaId?.toString() === atletaId)
      )
    );

    res.json(filtradas);
  } catch (err) {
    console.error(err);
    res.status(500).json({ mensaje: "Error al obtener rutinas del atleta" });
  }
});

// DELETE eliminar una formación específica por índice
router.delete('/:id/formations/:index', async (req, res) => {
  const { id, index } = req.params;

  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).json({ message: 'ID de rutina inválido' });
  }

  const i = parseInt(index);
  if (isNaN(i) || i < 0) {
    return res.status(400).json({ message: 'Índice de formación inválido' });
  }

  try {
    const rutina = await Routine.findById(id);
    if (!rutina) {
      return res.status(404).json({ message: 'Rutina no encontrada' });
    }

    if (i >= rutina.formaciones.length) {
      return res.status(400).json({ message: 'Índice fuera de rango' });
    }

    rutina.formaciones.splice(i, 1);
    await rutina.save();

    const nuevosParticipantes = new Set();
    rutina.formaciones.forEach(f => {
    f.atletas.forEach(a => {
    if (a.atletaId) nuevosParticipantes.add(a.atletaId.toString());
   });
  });
rutina.participantes = [...nuevosParticipantes];

    res.status(200).json({ message: 'Formación eliminada exitosamente' });
  } catch (error) {
    console.error('❌ Error al eliminar formación:', error);
    res.status(500).json({ message: 'Error del servidor', error });
  }
});
router.get('/atleta/:id/formaciones', async (req, res) => {
  const atletaId = req.params.id;
  try {
    const rutinas = await Routine.find({ participantes: atletaId });

    const resultado = [];

    for (const rutina of rutinas) {
      const formacionesAtleta = rutina.formaciones
        .map((f, i) => {
          const match = f.atletas.find(a => a.atletaId?.toString() === atletaId);
          return match
            ? {
                rutinaId: rutina._id,
                rutinaNombre: rutina.title || rutina.nombreCompetencia,
                index: i,
                nombreColoquial: f.nombreColoquial,
                notasTacticas: f.notasTacticas,
                duracion: f.duracion,
                atleta: match
              }
            : null;
        })
        .filter(Boolean);

      if (formacionesAtleta.length > 0) {
        resultado.push(...formacionesAtleta);
      }
    }

    res.json(resultado);
  } catch (err) {
    console.error(err);
    res.status(500).json({ mensaje: "Error al obtener formaciones del atleta" });
  }
});


module.exports = router;
