/**
 * WhatsApp Template Controller
 * API endpoints for WhatsApp template management
 *
 * @module WhatsApp
 * @prefix /api/v1/whatsapp/templates
 */

import { Router, Request, Response, NextFunction } from 'express';
import {
  WhatsAppTemplateService,
  CreateTemplateDto,
  UpdateTemplateDto,
  ServiceContext,
} from '../services';

const router = Router();
const templateService = new WhatsAppTemplateService();

function getServiceContext(req: Request): ServiceContext {
  const tenantId = req.headers['x-tenant-id'] as string;
  const userId = (req as any).user?.id;
  return { tenantId, userId };
}

/**
 * GET /api/v1/whatsapp/templates
 * List all templates
 */
router.get('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { accountId, category, metaStatus, isActive, language } = req.query;

    const templates = await templateService.findAll(ctx, {
      accountId: accountId as string,
      category: category as any,
      metaStatus: metaStatus as any,
      isActive: isActive === 'true' ? true : isActive === 'false' ? false : undefined,
      language: language as string,
    });

    return res.json({
      success: true,
      data: templates,
      count: templates.length,
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/templates/approved
 * Get approved templates
 */
router.get('/approved', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { accountId } = req.query;
    const templates = await templateService.findApproved(ctx, accountId as string);
    return res.json({ success: true, data: templates, count: templates.length });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/templates/by-category/:category
 * Get templates by category
 */
router.get('/by-category/:category', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const templates = await templateService.findByCategory(ctx, req.params.category as any);
    return res.json({ success: true, data: templates, count: templates.length });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/templates/statistics
 * Get template statistics
 */
router.get('/statistics', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { accountId } = req.query;
    const stats = await templateService.getStatistics(ctx, accountId as string);
    return res.json({ success: true, data: stats });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/templates/:id
 * Get template by ID
 */
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const template = await templateService.findById(ctx, req.params.id);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/templates/:id/render
 * Render template with variables
 */
router.get('/:id/render', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { variables } = req.query;
    const varsArray = variables ? (variables as string).split(',') : [];

    const rendered = await templateService.renderTemplate(ctx, req.params.id, varsArray);
    if (!rendered) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: rendered });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/templates
 * Create a new template
 */
router.post('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const data: CreateTemplateDto = req.body;

    if (!data.accountId || !data.name || !data.displayName || !data.category || !data.bodyText) {
      return res.status(400).json({
        error: 'accountId, name, displayName, category, and bodyText are required',
      });
    }

    const existing = await templateService.findByName(ctx, data.accountId, data.name, data.language);
    if (existing) {
      return res.status(409).json({ error: 'Template with this name already exists' });
    }

    const template = await templateService.create(ctx, data);
    return res.status(201).json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * PATCH /api/v1/whatsapp/templates/:id
 * Update template
 */
router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const data: UpdateTemplateDto = req.body;
    const template = await templateService.update(ctx, req.params.id, data);

    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/templates/:id/submit
 * Submit template to Meta for approval
 */
router.post('/:id/submit', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { metaTemplateId } = req.body;

    if (!metaTemplateId) {
      return res.status(400).json({ error: 'metaTemplateId is required' });
    }

    const template = await templateService.submit(ctx, req.params.id, metaTemplateId);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * PATCH /api/v1/whatsapp/templates/:id/meta-status
 * Update Meta status (for webhooks)
 */
router.patch('/:id/meta-status', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { status, rejectionReason } = req.body;

    if (!status) {
      return res.status(400).json({ error: 'status is required' });
    }

    const template = await templateService.updateMetaStatus(ctx, req.params.id, status, rejectionReason);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/templates/:id/activate
 * Activate template
 */
router.post('/:id/activate', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const template = await templateService.activate(ctx, req.params.id);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/templates/:id/deactivate
 * Deactivate template
 */
router.post('/:id/deactivate', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const template = await templateService.deactivate(ctx, req.params.id);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/templates/:id/duplicate
 * Duplicate template
 */
router.post('/:id/duplicate', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { name, displayName } = req.body;

    if (!name || !displayName) {
      return res.status(400).json({ error: 'name and displayName are required' });
    }

    const template = await templateService.duplicate(ctx, req.params.id, name, displayName);
    if (!template) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.status(201).json({ success: true, data: template });
  } catch (error) {
    return next(error);
  }
});

/**
 * DELETE /api/v1/whatsapp/templates/:id
 * Delete template
 */
router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const ctx = getServiceContext(req);
    if (!ctx.tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const deleted = await templateService.delete(ctx, req.params.id);
    if (!deleted) {
      return res.status(404).json({ error: 'Template not found' });
    }

    return res.json({ success: true, message: 'Template deleted' });
  } catch (error) {
    return next(error);
  }
});

export default router;
