/**
 * Audio Content Routes
 * CRUD operations for the audio content module
 */

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';
import { getModels } from '../models';
import { authenticateJwtOrApiToken } from '../middleware/dualAuth';

const router = express.Router();
router.use(authenticateJwtOrApiToken);

// ============================================
// AUDIO CONTENT CRUD
// ============================================

// GET all audio content for a company
router.get('/audio-contents/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    const { AudioContent } = getModels();

    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    const filter: Record<string, any> = { companyId };

    if (req.query.status) filter.status = req.query.status;
    if (req.query.genre) filter.genre = req.query.genre;
    if (req.query.mood) filter.mood = req.query.mood;
    if (req.query.aiGenerated) filter.aiGenerated = req.query.aiGenerated === 'true';
    if (req.query.isFavorite) filter.isFavorite = req.query.isFavorite === 'true';

    if (req.query.search) {
      const searchRegex = new RegExp(req.query.search as string, 'i');
      filter.$or = [
        { songTitle: searchRegex },
        { prompt: searchRegex },
        { generatedLyrics: searchRegex },
      ];
    }

    const audioContents = await AudioContent.find(filter).sort({ createdAt: -1 });
    res.json({ data: audioContents });
  } catch (error: any) {
    console.error('Error fetching audio content:', error);
    res.status(500).json({ error: 'Failed to fetch audio content', details: error.message });
  }
});

// GET single audio content by ID
router.get('/audio-contents/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { AudioContent } = getModels();
    const audioContent = await AudioContent.findById(id);

    if (!audioContent) {
      res.status(404).json({ error: 'Audio content not found' });
      return;
    }

    if (!req.user!.companyIds.includes(audioContent.companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    res.json({ data: audioContent });
  } catch (error: any) {
    console.error('Error fetching audio content:', error);
    res.status(500).json({ error: 'Failed to fetch audio content', details: error.message });
  }
});

// POST create audio content
router.post('/audio-contents', [
  body('companyId').notEmpty().withMessage('Company ID is required'),
  body('songTitle').notEmpty().withMessage('Song title is required'),
  body('prompt').notEmpty().withMessage('Prompt is required'),
], async (req: Request, res: Response) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    res.status(400).json({ error: 'Validation failed', details: errors.array() });
    return;
  }

  try {
    const { AudioContent } = getModels();
    // Strip client-generated id/_id so MongoDB generates the canonical _id
    delete req.body.id;
    delete req.body._id;
    const audioContent = new AudioContent(req.body);
    await audioContent.save();
    res.status(201).json({ data: audioContent });
  } catch (error: any) {
    console.error('Error creating audio content:', error);
    res.status(500).json({ error: 'Failed to create audio content', details: error.message });
  }
});

// PUT update audio content
router.put('/audio-contents/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { AudioContent } = getModels();
    // Prevent overwriting the document _id or id
    delete req.body._id;
    delete req.body.id;
    const audioContent = await AudioContent.findByIdAndUpdate(id, req.body, { new: true, runValidators: true });

    if (!audioContent) {
      res.status(404).json({ error: 'Audio content not found' });
      return;
    }

    res.json({ data: audioContent });
  } catch (error: any) {
    console.error('Error updating audio content:', error);
    res.status(500).json({ error: 'Failed to update audio content', details: error.message });
  }
});

// DELETE audio content
router.delete('/audio-contents/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { AudioContent } = getModels();
    const audioContent = await AudioContent.findByIdAndDelete(id);

    if (!audioContent) {
      res.status(404).json({ error: 'Audio content not found' });
      return;
    }

    res.json({ data: audioContent });
  } catch (error: any) {
    console.error('Error deleting audio content:', error);
    res.status(500).json({ error: 'Failed to delete audio content', details: error.message });
  }
});

// POST bulk import
router.post('/audio-contents/bulk-import', async (req: Request, res: Response) => {
  try {
    const { items } = req.body;
    if (!Array.isArray(items) || items.length === 0) {
      res.status(400).json({ error: 'Items array is required' });
      return;
    }

    const { AudioContent } = getModels();
    // Strip client-generated id/_id from each item so MongoDB generates canonical _id
    const cleaned = items.map((item: any) => {
      const { id, _id, ...rest } = item;
      return rest;
    });
    const created = await AudioContent.insertMany(cleaned);
    res.status(201).json({ data: created });
  } catch (error: any) {
    console.error('Error bulk importing audio content:', error);
    res.status(500).json({ error: 'Failed to bulk import audio content', details: error.message });
  }
});

export default router;