/**
 * Newsletter Content OS Routes
 *
 * Unified route for all newsletter content operating system entities.
 */

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';
import { NewsletterContentOS } from '../models/NewsletterContentOS';
import { authenticateJwtOrApiToken } from '../middleware/dualAuth';
import { requirePermission } from '../middleware/permissions';

const router = express.Router();
router.use(authenticateJwtOrApiToken);

/**
 * Character limits for Newsletter Campaign free-text inputs. Mirror of the
 * frontend NEWSLETTER_FIELD_LIMITS
 * (src/frontend/src/modules/content/newsletter-content-os/config/fieldLimits.ts) —
 * kept in sync manually since the two packages don't share code. Enforced here
 * so non-UI callers (direct API / imports) cannot bypass the client-side limits.
 */
const NEWSLETTER_CAMPAIGN_LIMITS = {
  name: 100,
  description: 1000,
  primaryCTA: 50,
  secondaryCTA: 50,
  externalSourceLabel: 100,
  externalSourceUrl: 2048,
  externalSourceContent: 10000,
  contentBlockTitle: 100,
  contentBlockContent: 10000,
  assetUrl: 2048,
  reviewNotes: 1000,
};

/** Throws when any entry in a URL list exceeds the asset URL ceiling. */
const assertUrlList = (urls: any[], label: string) => {
  for (const url of urls) {
    if (typeof url === 'string' && url.length > NEWSLETTER_CAMPAIGN_LIMITS.assetUrl) {
      throw new Error(`${label} must be ${NEWSLETTER_CAMPAIGN_LIMITS.assetUrl} characters or fewer`);
    }
  }
  return true;
};

/**
 * Validation chain shared by campaign create and update. Every field is
 * optional so partial updates keep working; only the ceiling is enforced.
 */
const campaignValidators = [
  body('name').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.name })
    .withMessage(`Campaign name must be ${NEWSLETTER_CAMPAIGN_LIMITS.name} characters or fewer`),
  body('description').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.description })
    .withMessage(`Campaign description must be ${NEWSLETTER_CAMPAIGN_LIMITS.description} characters or fewer`),
  body('primaryCTA').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.primaryCTA })
    .withMessage(`Primary CTA must be ${NEWSLETTER_CAMPAIGN_LIMITS.primaryCTA} characters or fewer`),
  body('secondaryCTA').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.secondaryCTA })
    .withMessage(`Secondary CTA must be ${NEWSLETTER_CAMPAIGN_LIMITS.secondaryCTA} characters or fewer`),
  body('reviewNotes').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.reviewNotes })
    .withMessage(`Review notes must be ${NEWSLETTER_CAMPAIGN_LIMITS.reviewNotes} characters or fewer`),
  body('bannerImage').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.assetUrl })
    .withMessage(`Banner image URL must be ${NEWSLETTER_CAMPAIGN_LIMITS.assetUrl} characters or fewer`),
  body('headerImage').optional().isString().isLength({ max: NEWSLETTER_CAMPAIGN_LIMITS.assetUrl })
    .withMessage(`Header image URL must be ${NEWSLETTER_CAMPAIGN_LIMITS.assetUrl} characters or fewer`),
  body('ctaGraphics').optional().isArray()
    .custom((urls: any[]) => assertUrlList(urls, 'CTA graphic URL')),
  body('socialCreatives').optional().isArray()
    .custom((urls: any[]) => assertUrlList(urls, 'Social creative URL')),
  body('externalSources').optional().isArray()
    .custom((sources: any[]) => {
      for (const source of sources) {
        if (typeof source?.label === 'string' && source.label.length > NEWSLETTER_CAMPAIGN_LIMITS.externalSourceLabel) {
          throw new Error(`Source label must be ${NEWSLETTER_CAMPAIGN_LIMITS.externalSourceLabel} characters or fewer`);
        }
        if (typeof source?.url === 'string' && source.url.length > NEWSLETTER_CAMPAIGN_LIMITS.externalSourceUrl) {
          throw new Error(`Source URL must be ${NEWSLETTER_CAMPAIGN_LIMITS.externalSourceUrl} characters or fewer`);
        }
        if (typeof source?.content === 'string' && source.content.length > NEWSLETTER_CAMPAIGN_LIMITS.externalSourceContent) {
          throw new Error(`Source content must be ${NEWSLETTER_CAMPAIGN_LIMITS.externalSourceContent} characters or fewer`);
        }
      }
      return true;
    }),
  body('newsletterContentBlocks').optional().isArray()
    .custom((blocks: any[]) => {
      for (const block of blocks) {
        if (typeof block?.title === 'string' && block.title.length > NEWSLETTER_CAMPAIGN_LIMITS.contentBlockTitle) {
          throw new Error(`Block title must be ${NEWSLETTER_CAMPAIGN_LIMITS.contentBlockTitle} characters or fewer`);
        }
        if (typeof block?.content === 'string' && block.content.length > NEWSLETTER_CAMPAIGN_LIMITS.contentBlockContent) {
          throw new Error(`Block content must be ${NEWSLETTER_CAMPAIGN_LIMITS.contentBlockContent} characters or fewer`);
        }
      }
      return true;
    }),
];

// Helper to get or create company data
const getCompanyData = async (companyId: string) => {
  let data = await NewsletterContentOS.findOne({ companyId });
  if (!data) {
    data = new NewsletterContentOS({ companyId });
    await data.save();
  }
  return data;
};

// ============== STRATEGIES ==============

router.get('/strategies/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.strategies || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get strategies' });
  }
});

router.get('/strategies/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'strategies.id': id });
    if (!data) {
      res.status(404).json({ error: 'Strategy not found' });
      return;
    }
    const strategy = data.strategies.find((s: any) => s.id === id);
    res.json(strategy);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get strategy' });
  }
});

router.post('/strategies', requirePermission('newsletter-content-os', 'create'),
  body('name').trim().isLength({ min: 3, max: 100 }).withMessage('Name must be 3-100 characters')
    .matches(/[a-zA-Z].*[a-zA-Z]/i).withMessage('Name must contain meaningful words'),
  body('audience').optional().trim().isLength({ max: 150 }).withMessage('Audience must be at most 150 characters')
    .matches(/[a-zA-Z].*[a-zA-Z]/i).withMessage('Audience must contain meaningful words'),
  body('industry').optional().trim().isLength({ max: 80 }).withMessage('Industry must be at most 80 characters')
    .matches(/[a-zA-Z].*[a-zA-Z]/i).withMessage('Industry must contain meaningful words'),
  body('communicationTone').optional().trim().isLength({ max: 100 }).withMessage('Tone must be at most 100 characters')
    .matches(/[a-zA-Z].*[a-zA-Z]/i).withMessage('Tone must contain meaningful words'),
  body('ctaGoal').optional().trim().isLength({ max: 100 }).withMessage('CTA Goal must be at most 100 characters')
    .matches(/[a-zA-Z].*[a-zA-Z]/i).withMessage('CTA Goal must contain meaningful words'),
  body('objective').isIn(['education','product-awareness','community-building','brand-awareness','customer-engagement','retention','updates','founder-communication','thought-leadership']),
  body('funnelStage').isIn(['tofu','mofu','bofu']),
  body('contentDepth').isIn(['brief','standard','deep','comprehensive']),
  async (req: Request, res: Response) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const { name, audience, industry, objective, funnelStage, contentDepth, communicationTone, ctaGoal } = req.body;
    const data = await getCompanyData(companyId);
    const strategy = {
      name, audience, industry, objective, funnelStage, contentDepth, communicationTone, ctaGoal,
      companyId, linkedData: {},
      createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
    };
    data.strategies.push(strategy);
    await data.save();
    res.status(201).json(strategy);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create strategy' });
  }
});

router.put('/strategies/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'strategies.id': id });
    if (!data) {
      res.status(404).json({ error: 'Strategy not found' });
      return;
    }
    const index = data.strategies.findIndex((s: any) => s.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Strategy not found' });
      return;
    }
    data.strategies[index] = { ...data.strategies[index], ...req.body, updatedAt: new Date().toISOString() };
    // Mixed arrays: Mongoose cannot detect an in-place index assignment, so
    // without markModified the save() below silently persists nothing.
    data.markModified('strategies');
    await data.save();
    res.json(data.strategies[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update strategy' });
  }
});

router.delete('/strategies/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'strategies.id': id });
    if (!data) {
      res.status(404).json({ error: 'Strategy not found' });
      return;
    }
    data.strategies = data.strategies.filter((s: any) => s.id !== id);
    await data.save();
    res.json({ message: 'Strategy deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete strategy' });
  }
});

// ============== CALENDARS ==============

router.get('/calendars/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.calendars || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get calendars' });
  }
});

router.get('/calendars/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'calendars.id': id });
    if (!data) {
      res.status(404).json({ error: 'Calendar not found' });
      return;
    }
    const calendar = data.calendars.find((c: any) => c.id === id);
    res.json(calendar);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get calendar' });
  }
});

router.post('/calendars', requirePermission('newsletter-content-os', 'create'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    const calendar = { ...req.body, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
    data.calendars.push(calendar);
    await data.save();
    res.status(201).json(calendar);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create calendar' });
  }
});

router.put('/calendars/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'calendars.id': id });
    if (!data) {
      res.status(404).json({ error: 'Calendar not found' });
      return;
    }
    const index = data.calendars.findIndex((c: any) => c.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Calendar not found' });
      return;
    }
    data.calendars[index] = { ...data.calendars[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('calendars');
    await data.save();
    res.json(data.calendars[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update calendar' });
  }
});

router.delete('/calendars/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'calendars.id': id });
    if (!data) {
      res.status(404).json({ error: 'Calendar not found' });
      return;
    }
    data.calendars = data.calendars.filter((c: any) => c.id !== id);
    await data.save();
    res.json({ message: 'Calendar deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete calendar' });
  }
});

// ============== TITLES ==============

router.get('/titles/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.titles || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get titles' });
  }
});

router.get('/titles/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'titles.id': id });
    if (!data) {
      res.status(404).json({ error: 'Title not found' });
      return;
    }
    const title = data.titles.find((t: any) => t.id === id);
    res.json(title);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get title' });
  }
});

router.post('/titles', requirePermission('newsletter-content-os', 'create'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    const title = { ...req.body, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
    data.titles.push(title);
    await data.save();
    res.status(201).json(title);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create title' });
  }
});

router.put('/titles/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'titles.id': id });
    if (!data) {
      res.status(404).json({ error: 'Title not found' });
      return;
    }
    const index = data.titles.findIndex((t: any) => t.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Title not found' });
      return;
    }
    data.titles[index] = { ...data.titles[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('titles');
    await data.save();
    res.json(data.titles[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update title' });
  }
});

router.delete('/titles/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'titles.id': id });
    if (!data) {
      res.status(404).json({ error: 'Title not found' });
      return;
    }
    data.titles = data.titles.filter((t: any) => t.id !== id);
    await data.save();
    res.json({ message: 'Title deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete title' });
  }
});

// ============== POSTS ==============

router.get('/posts/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.posts || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get posts' });
  }
});

router.get('/posts/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'posts.id': id });
    if (!data) {
      res.status(404).json({ error: 'Post not found' });
      return;
    }
    const post = data.posts.find((p: any) => p.id === id);
    res.json(post);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get post' });
  }
});

router.post('/posts', requirePermission('newsletter-content-os', 'create'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    const post = { ...req.body, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
    data.posts.push(post);
    await data.save();
    res.status(201).json(post);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create post' });
  }
});

router.put('/posts/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'posts.id': id });
    if (!data) {
      res.status(404).json({ error: 'Post not found' });
      return;
    }
    const index = data.posts.findIndex((p: any) => p.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Post not found' });
      return;
    }
    data.posts[index] = { ...data.posts[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('posts');
    await data.save();
    res.json(data.posts[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update post' });
  }
});

router.delete('/posts/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'posts.id': id });
    if (!data) {
      res.status(404).json({ error: 'Post not found' });
      return;
    }
    data.posts = data.posts.filter((p: any) => p.id !== id);
    await data.save();
    res.json({ message: 'Post deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete post' });
  }
});

// ============== CHUNKS ==============

router.get('/chunks/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.chunks || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get chunks' });
  }
});

router.get('/chunks/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'chunks.id': id });
    if (!data) {
      res.status(404).json({ error: 'Chunk not found' });
      return;
    }
    const chunk = data.chunks.find((c: any) => c.id === id);
    res.json(chunk);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get chunk' });
  }
});

router.post('/chunks', requirePermission('newsletter-content-os', 'create'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    const chunk = { ...req.body, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
    data.chunks.push(chunk);
    await data.save();
    res.status(201).json(chunk);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create chunk' });
  }
});

router.put('/chunks/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'chunks.id': id });
    if (!data) {
      res.status(404).json({ error: 'Chunk not found' });
      return;
    }
    const index = data.chunks.findIndex((c: any) => c.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Chunk not found' });
      return;
    }
    data.chunks[index] = { ...data.chunks[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('chunks');
    await data.save();
    res.json(data.chunks[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update chunk' });
  }
});

router.delete('/chunks/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'chunks.id': id });
    if (!data) {
      res.status(404).json({ error: 'Chunk not found' });
      return;
    }
    data.chunks = data.chunks.filter((c: any) => c.id !== id);
    await data.save();
    res.json({ message: 'Chunk deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete chunk' });
  }
});

// ============== EXPORTS ==============

router.get('/exports/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    res.json(data.exports || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get exports' });
  }
});

router.get('/exports/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'exports.id': id });
    if (!data) {
      res.status(404).json({ error: 'Export not found' });
      return;
    }
    const exportItem = data.exports.find((e: any) => e.id === id);
    res.json(exportItem);
  } catch (error) {
    res.status(500).json({ error: 'Failed to get export' });
  }
});

router.post('/exports', requirePermission('newsletter-content-os', 'export'), async (req: Request, res: Response) => {
  try {
    const { companyId } = req.body;
    if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
      res.status(403).json({ error: 'Access denied' });
      return;
    }
    const data = await getCompanyData(companyId);
    const exportItem = { ...req.body, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };
    data.exports.push(exportItem);
    await data.save();
    res.status(201).json(exportItem);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create export' });
  }
});

router.put('/exports/:id', requirePermission('newsletter-content-os', 'edit'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'exports.id': id });
    if (!data) {
      res.status(404).json({ error: 'Export not found' });
      return;
    }
    const index = data.exports.findIndex((e: any) => e.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Export not found' });
      return;
    }
    data.exports[index] = { ...data.exports[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('exports');
    await data.save();
    res.json(data.exports[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update export' });
  }
});

router.delete('/exports/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'exports.id': id });
    if (!data) {
      res.status(404).json({ error: 'Export not found' });
      return;
    }
    data.exports = data.exports.filter((e: any) => e.id !== id);
    await data.save();
    res.json({ message: 'Export deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete export' });
  }
});

// ============================================
// CAMPAIGN ROUTES (Newsletter Wizard)
// ============================================

// Get all campaigns for a company
router.get('/campaigns/:companyId', async (req: Request, res: Response) => {
  try {
    const { companyId } = req.params;
    const data = await NewsletterContentOS.findOne({ companyId });
    res.json(data?.campaigns || []);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch campaigns' });
  }
});

// Get a single campaign
router.get('/campaigns/detail/:id', async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'campaigns.id': id });
    if (!data) {
      res.status(404).json({ error: 'Campaign not found' });
      return;
    }
    const campaign = data.campaigns.find((c: any) => c.id === id);
    if (!campaign) {
      res.status(404).json({ error: 'Campaign not found' });
      return;
    }
    res.json(campaign);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch campaign' });
  }
});

// Create a new campaign
router.post('/campaigns', requirePermission('newsletter-content-os', 'create'), campaignValidators, async (req: Request, res: Response) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }
    const { companyId, ...campaignData } = req.body;
    let data = await NewsletterContentOS.findOne({ companyId });
    if (!data) {
      data = new NewsletterContentOS({ companyId });
    }
    const campaign = {
      ...campaignData,
      id: campaignData.id || `nl-${Date.now()}`,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    data.campaigns.push(campaign);
    await data.save();
    res.status(201).json(campaign);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create campaign' });
  }
});

// Update a campaign
router.put('/campaigns/:id', requirePermission('newsletter-content-os', 'edit'), campaignValidators, async (req: Request, res: Response) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'campaigns.id': id });
    if (!data) {
      res.status(404).json({ error: 'Campaign not found' });
      return;
    }
    const index = data.campaigns.findIndex((c: any) => c.id === id);
    if (index === -1) {
      res.status(404).json({ error: 'Campaign not found' });
      return;
    }
    data.campaigns[index] = { ...data.campaigns[index], ...req.body, updatedAt: new Date().toISOString() };
    data.markModified('campaigns');
    await data.save();
    res.json(data.campaigns[index]);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update campaign' });
  }
});

// Delete a campaign
router.delete('/campaigns/:id', requirePermission('newsletter-content-os', 'delete'), async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const data = await NewsletterContentOS.findOne({ 'campaigns.id': id });
    if (!data) {
      res.status(404).json({ error: 'Campaign not found' });
      return;
    }
    data.campaigns = data.campaigns.filter((c: any) => c.id !== id);
    await data.save();
    res.json({ message: 'Campaign deleted successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete campaign' });
  }
});

export default router;
