/**
 * WhatsApp Automation Controller
 * API endpoints for automation rule management
 *
 * @module WhatsApp
 * @prefix /api/v1/whatsapp/automations
 */

import { Router, Request, Response, NextFunction } from 'express';
import {
  WhatsAppAutomationService,
  CreateAutomationDto,
  UpdateAutomationDto,
  ServiceContext,
} from '../services';

const router = Router();
const automationService = new WhatsAppAutomationService();

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/automations
 * List all automations
 */
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, triggerType, actionType, isActive } = req.query;

    const automations = await automationService.findAll(ctx, {
      accountId: accountId as string,
      triggerType: triggerType as any,
      actionType: actionType as any,
      isActive: isActive === 'true' ? true : isActive === 'false' ? false : undefined,
    });

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

/**
 * GET /api/v1/whatsapp/automations/active
 * Get active automations
 */
router.get('/active', 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 automations = await automationService.findActive(ctx, accountId as string);
    return res.json({ success: true, data: automations, count: automations.length });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/automations/by-trigger/:triggerType
 * Get automations by trigger type
 */
router.get('/by-trigger/:triggerType', 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 automations = await automationService.findByTriggerType(
      ctx,
      req.params.triggerType as any,
      accountId as string
    );
    return res.json({ success: true, data: automations, count: automations.length });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/automations/statistics
 * Get automation 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 automationService.getStatistics(ctx, accountId as string);
    return res.json({ success: true, data: stats });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/whatsapp/automations/:id
 * Get automation 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 automation = await automationService.findById(ctx, req.params.id);
    if (!automation) {
      return res.status(404).json({ error: 'Automation not found' });
    }

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

/**
 * POST /api/v1/whatsapp/automations
 * Create a new automation
 */
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: CreateAutomationDto = req.body;

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

    const validTriggerTypes = ['keyword', 'first_message', 'after_hours', 'no_response', 'webhook'];
    if (!validTriggerTypes.includes(data.triggerType)) {
      return res.status(400).json({
        error: `triggerType must be one of: ${validTriggerTypes.join(', ')}`,
      });
    }

    const validActionTypes = ['send_message', 'send_template', 'assign_agent', 'add_tag', 'create_ticket'];
    if (!validActionTypes.includes(data.actionType)) {
      return res.status(400).json({
        error: `actionType must be one of: ${validActionTypes.join(', ')}`,
      });
    }

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

/**
 * PATCH /api/v1/whatsapp/automations/:id
 * Update automation
 */
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: UpdateAutomationDto = req.body;
    const automation = await automationService.update(ctx, req.params.id, data);

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

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

/**
 * POST /api/v1/whatsapp/automations/:id/activate
 * Activate automation
 */
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 automation = await automationService.activate(ctx, req.params.id);
    if (!automation) {
      return res.status(404).json({ error: 'Automation not found' });
    }

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

/**
 * POST /api/v1/whatsapp/automations/:id/deactivate
 * Deactivate automation
 */
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 automation = await automationService.deactivate(ctx, req.params.id);
    if (!automation) {
      return res.status(404).json({ error: 'Automation not found' });
    }

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

/**
 * POST /api/v1/whatsapp/automations/:id/duplicate
 * Duplicate automation
 */
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 } = req.body;

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

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

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

/**
 * POST /api/v1/whatsapp/automations/reorder
 * Reorder automations by priority
 */
router.post('/reorder', 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 { automationIds } = req.body;

    if (!automationIds || !Array.isArray(automationIds)) {
      return res.status(400).json({ error: 'automationIds array is required' });
    }

    await automationService.reorder(ctx, automationIds);
    return res.json({ success: true, message: 'Automations reordered' });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/whatsapp/automations/match
 * Find matching automations for a context (for testing)
 */
router.post('/match', 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 context = req.body;

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

    const automations = await automationService.findMatchingAutomations(ctx, context);
    return res.json({
      success: true,
      data: automations,
      count: automations.length,
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * DELETE /api/v1/whatsapp/automations/:id
 * Delete automation
 */
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 automationService.delete(ctx, req.params.id);
    if (!deleted) {
      return res.status(404).json({ error: 'Automation not found' });
    }

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

export default router;
