import { Request, Response } from 'express';
import type { AuthenticatedRequest } from '../types/express';
import { TemplateService } from '../services/template.service';
import { ResponseHandler } from '../utils/responseHandler';
import logger from '../utils/logger';

export class TemplateController {
  private templateService = new TemplateService();

  /**
   * Create a new template
   * POST /api/v1/templates
   */
  async createTemplate(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const userId = req.user?.userId;
      if (!userId) {
        return ResponseHandler.error(res, 'Unauthorized', 401);
      }

      const {
        // New fields
        templateName,
        templateCode,
        templateDescription,
        templateCategory,
        workflowType,
        approvalLevelsConfig,
        defaultTatHours,
        formStepsConfig,
        userFieldMappings,
        dynamicApproverConfig,
        isActive,

        // Legacy fields (from frontend)
        name,
        description,
        category,
        approvers,
        suggestedSLA
      } = req.body;

      // Map legacy to new
      const finalTemplateName = templateName || name;
      const finalTemplateDescription = templateDescription || description;
      const finalTemplateCategory = templateCategory || category;
      const finalApprovalLevelsConfig = approvalLevelsConfig || approvers;
      const finalDefaultTatHours = defaultTatHours || suggestedSLA;

      if (!finalTemplateName) {
        return ResponseHandler.error(res, 'Template name is required', 400);
      }

      const template = await this.templateService.createTemplate(userId, {
        templateName: finalTemplateName,
        templateCode,
        templateDescription: finalTemplateDescription,
        templateCategory: finalTemplateCategory,
        workflowType,
        approvalLevelsConfig: finalApprovalLevelsConfig,
        defaultTatHours: finalDefaultTatHours ? parseFloat(finalDefaultTatHours) : undefined,
        formStepsConfig,
        userFieldMappings,
        dynamicApproverConfig,
        isActive,
      });

      return ResponseHandler.success(res, template, 'Template created successfully', 201);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error creating template:', error);
      return ResponseHandler.error(res, 'Failed to create template', 500, errorMessage);
    }
  }

  /**
   * Get template by ID
   * GET /api/v1/templates/:templateId
   */
  async getTemplate(req: Request, res: Response): Promise<void> {
    try {
      const { templateId } = req.params;

      const template = await this.templateService.getTemplate(templateId);

      if (!template) {
        return ResponseHandler.error(res, 'Template not found', 404);
      }

      return ResponseHandler.success(res, template, 'Template fetched');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error getting template:', error);
      return ResponseHandler.error(res, 'Failed to fetch template', 500, errorMessage);
    }
  }

  /**
   * List templates
   * GET /api/v1/templates
   */
  async listTemplates(req: Request, res: Response): Promise<void> {
    try {
      const {
        category,
        workflowType,
        isActive,
        isSystemTemplate,
        search,
      } = req.query;

      const filters: any = {};
      if (category) filters.category = category as string;
      if (workflowType) filters.workflowType = workflowType as string;
      if (isActive !== undefined) filters.isActive = isActive === 'true';
      if (isSystemTemplate !== undefined) filters.isSystemTemplate = isSystemTemplate === 'true';
      if (search) filters.search = search as string;

      const templates = await this.templateService.listTemplates(filters);

      return ResponseHandler.success(res, templates, 'Templates fetched');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error listing templates:', error);
      return ResponseHandler.error(res, 'Failed to fetch templates', 500, errorMessage);
    }
  }

  /**
   * Get active templates (for workflow creation)
   * GET /api/v1/templates/active
   */
  async getActiveTemplates(req: Request, res: Response): Promise<void> {
    try {
      const templates = await this.templateService.getActiveTemplates();

      return ResponseHandler.success(res, templates, 'Active templates fetched');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error getting active templates:', error);
      return ResponseHandler.error(res, 'Failed to fetch active templates', 500, errorMessage);
    }
  }

  /**
   * Update template
   * PUT /api/v1/templates/:templateId
   */
  async updateTemplate(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const { templateId } = req.params;
      const userId = req.user?.userId;
      if (!userId) {
        return ResponseHandler.error(res, 'Unauthorized', 401);
      }

      const {
        templateName,
        templateDescription,
        templateCategory,
        approvalLevelsConfig,
        defaultTatHours,
        formStepsConfig,
        userFieldMappings,
        dynamicApproverConfig,
        isActive,

        // Legacy
        name,
        description,
        category,
        approvers,
        suggestedSLA
      } = req.body;

      const template = await this.templateService.updateTemplate(templateId, userId, {
        templateName: templateName || name,
        templateDescription: templateDescription || description,
        templateCategory: templateCategory || category,
        approvalLevelsConfig: approvalLevelsConfig || approvers,
        defaultTatHours: (defaultTatHours || suggestedSLA) ? parseFloat(defaultTatHours || suggestedSLA) : undefined,
        formStepsConfig,
        userFieldMappings,
        dynamicApproverConfig,
        isActive,
      });

      return ResponseHandler.success(res, template, 'Template updated successfully');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error updating template:', error);
      return ResponseHandler.error(res, 'Failed to update template', 500, errorMessage);
    }
  }

  /**
   * Delete template
   * DELETE /api/v1/templates/:templateId
   */
  async deleteTemplate(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const { templateId } = req.params;

      await this.templateService.deleteTemplate(templateId);

      return ResponseHandler.success(res, { message: 'Template deleted successfully' }, 'Template deleted');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('[TemplateController] Error deleting template:', error);
      return ResponseHandler.error(res, 'Failed to delete template', 500, errorMessage);
    }
  }
}

