/**
 * Intro Script Routes
 * CRUD operations for intro scripts with filtering, validation, and role-based access
 */

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';
import { getModels } from '../models';
import { authenticateJwtOrApiToken } from '../middleware/dualAuth';
import { requirePermission } from '../middleware/permissions';

const router = express.Router();

router.use(authenticateJwtOrApiToken);

// ============================================
// GET ALL INTRO SCRIPTS FOR A COMPANY
// ============================================

router.get('/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    const { IntroScript } = getModels();

    // Authorization check
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    // Build filter query
    const filter: Record<string, any> = { companyId };

    // Optional filters
    if (req.query.introductionType) {
      filter.introductionType = req.query.introductionType;
    }
    if (req.query.status) {
      filter.status = req.query.status;
    }
    if (req.query.language) {
      filter.language = req.query.language;
    }
    if (req.query.tone) {
      filter.tone = req.query.tone;
    }
    if (req.query.eventType) {
      filter.eventType = req.query.eventType;
    }
    if (req.query.context) {
      filter.context = req.query.context;
    }
    if (req.query.source) {
      filter.source = req.query.source;
    }

    // Search functionality
    if (req.query.search) {
      const searchRegex = new RegExp(req.query.search as string, 'i');
      filter.$or = [
        { name: searchRegex },
        { content: searchRegex },
        { personalizationNotes: searchRegex },
      ];
    }

    const scripts = await IntroScript.find(filter).sort({ createdAt: -1 });
    res.json(scripts);
  } catch (error) {
    console.error('Error fetching intro scripts:', error);
    res.status(500).json({ error: 'Failed to get intro scripts' });
  }
});

// ============================================
// GET SINGLE INTRO SCRIPT
// ============================================

router.get('/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { IntroScript } = getModels();

    const script = await IntroScript.findById(id);
    if (!script) {
      res.status(404).json({ error: 'Intro script not found' });
      return;
    }

    // Authorization check
    if (!req.user!.companyIds.includes(script.companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    res.json(script);
  } catch (error) {
    console.error('Error fetching intro script:', error);
    res.status(500).json({ error: 'Failed to get intro script' });
  }
});

// ============================================
// CREATE INTRO SCRIPT
// ============================================

router.post(
  '/',
  requirePermission('intro-scripts', 'create'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
    body('name').trim().notEmpty().withMessage('Script name is required'),
    body('introductionType').isIn(['company', 'founder', 'employee', 'team', 'speaker', 'guest', 'event-host']).withMessage('Invalid introduction type'),
    body('eventType').isIn([
      'corporate-meeting', 'conference', 'webinar', 'workshop', 'product-launch',
      'investor-pitch', 'networking-event', 'award-ceremony', 'employee-onboarding',
      'annual-function', 'training-session', 'social-media-video', 'youtube-video',
      'podcast', 'college-seminar', 'public-event',
    ]).withMessage('Invalid event type'),
    body('content').trim().notEmpty().withMessage('Script content is required'),
    body('language').optional().isIn(['en', 'hi', 'mr', 'bilingual', 'multilingual']),
    body('duration').optional().isIn(['30s', '1min', '2min', '3min', '5min']),
    body('tone').optional().isIn(['professional', 'corporate', 'inspirational', 'friendly', 'motivational', 'formal', 'luxury', 'premium', 'startup', 'humorous']),
    body('context').optional().isIn(['stage', 'self', 'video', 'networking', 'investor', 'conference-speaker', 'award-ceremony']),
    body('source').optional().isIn(['ai-generation', 'manual']),
    body('status').optional().isIn(['draft', 'review', 'approved', 'published']),
  ],
  async (req: Request, res: Response) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        res.status(400).json({ errors: errors.array() });
        return;
      }

      // Authorization check
      if (!req.user!.companyIds.includes(req.body.companyId) && req.user!.role !== 'admin') {
        res.status(403).json({ error: 'Access denied' });
        return;
      }

      const { IntroScript } = getModels();

      const scriptData = {
        ...req.body,
        status: req.body.status || 'draft',
        source: req.body.source || 'manual',
        language: req.body.language || 'en',
        duration: req.body.duration || '1min',
        tone: req.body.tone || 'professional',
      };

      const script = new IntroScript(scriptData);
      await script.save();

      res.status(201).json(script);
    } catch (error) {
      console.error('Error creating intro script:', error);
      res.status(500).json({ error: 'Failed to create intro script' });
    }
  }
);

// ============================================
// UPDATE INTRO SCRIPT
// ============================================

router.put('/:id', requirePermission('intro-scripts', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { IntroScript } = getModels();

    const script = await IntroScript.findById(id);
    if (!script) {
      res.status(404).json({ error: 'Intro script not found' });
      return;
    }

    // Authorization check
    if (!req.user!.companyIds.includes(script.companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    Object.assign(script, req.body, { updatedAt: new Date().toISOString() });
    await script.save();

    res.json(script);
  } catch (error) {
    console.error('Error updating intro script:', error);
    res.status(500).json({ error: 'Failed to update intro script' });
  }
});

// ============================================
// DELETE INTRO SCRIPT
// ============================================

router.delete('/:id', requirePermission('intro-scripts', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { IntroScript } = getModels();

    const script = await IntroScript.findById(id);
    if (!script) {
      res.status(404).json({ error: 'Intro script not found' });
      return;
    }

    // Authorization check
    if (!req.user!.companyIds.includes(script.companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    await IntroScript.findByIdAndDelete(id);
    res.json({ message: 'Intro script deleted successfully' });
  } catch (error) {
    console.error('Error deleting intro script:', error);
    res.status(500).json({ error: 'Failed to delete intro script' });
  }
});

// ============================================
// CLEAR ALL INTRO SCRIPTS FOR A COMPANY
// ============================================

router.delete('/clear/:companyId', requirePermission('intro-scripts', 'delete'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    const { IntroScript } = getModels();

    // Authorization check
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }

    const result = await IntroScript.deleteMany({ companyId });
    res.json({ message: `Deleted ${result.deletedCount} intro scripts`, deletedCount: result.deletedCount });
  } catch (error) {
    console.error('Error clearing intro scripts:', error);
    res.status(500).json({ error: 'Failed to clear intro scripts' });
  }
});

export default router;