import { Request, Response } from 'express';
import { z } from 'zod';

import { NotFoundError, BadRequestError } from '../../../errors/http-error';
import { getErrorMessage } from '../../../utils/error-utils';
import { GenerateComplianceReportDto, ReportFiltersDto } from '../governance.dto';

import { complianceService } from './compliance.service';

/**
 * EN: Compliance Controller
 * VI: Controller tuân thủ
 */
export class ComplianceController {
  /**
   * EN: List reports
   * VI: Liệt kê các báo cáo
   */
  async list(req: Request, res: Response): Promise<void> {
    try {
      const filters = ReportFiltersDto.parse({
        type: req.query.type as any,
        status: req.query.status as any,
        startDate: req.query.startDate as string,
        endDate: req.query.endDate as string,
        skip: parseInt(req.query.skip as string) || 0,
        take: parseInt(req.query.take as string) || 20,
      });

      const result = await complianceService.getReports(filters);

      res.json({
        success: true,
        data: {
          reports: result.reports,
          pagination: {
            total: result.total,
            skip: filters.skip,
            take: filters.take,
          },
        },
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid filters',
            details: error.issues,
          },
        });
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'LIST_REPORTS_FAILED',
          message: getErrorMessage(error) || 'Failed to list reports',
        },
      });
    }
  }

  /**
   * EN: Generate report
   * VI: Tạo báo cáo
   */
  async generate(req: Request, res: Response): Promise<void> {
    try {
      const generatedBy = (req as any).user?.id;
      if (!generatedBy) {
        res.status(401).json({
          success: false,
          error: {
            code: 'UNAUTHORIZED',
            message: 'Authentication required / Yêu cầu xác thực',
          },
        });
        return;
      }

      const data = GenerateComplianceReportDto.parse(req.body);
      const periodStart = new Date(data.periodStart);
      const periodEnd = new Date(data.periodEnd);

      const report = await complianceService.generateReport(
        data.type,
        periodStart,
        periodEnd,
        generatedBy,
        req
      );

      res.status(201).json({
        success: true,
        data: report,
        message: 'Compliance report generated successfully / Báo cáo tuân thủ đã được tạo thành công',
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid input',
            details: error.issues,
          },
        });
        return;
      }

      if (error instanceof BadRequestError) {
        res.status(400).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'GENERATE_REPORT_FAILED',
          message: getErrorMessage(error) || 'Failed to generate report',
        },
      });
    }
  }

  /**
   * EN: Get report
   * VI: Lấy báo cáo
   */
  async get(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const report = await complianceService.getReport(id);

      res.json({
        success: true,
        data: report,
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'GET_REPORT_FAILED',
          message: getErrorMessage(error) || 'Failed to get report',
        },
      });
    }
  }

  /**
   * EN: Export report
   * VI: Export báo cáo
   */
  async export(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const format = (req.query.format as 'json' | 'csv' | 'pdf') || 'json';

      const report = await complianceService.getReport(id);

      if (format === 'json') {
        res.setHeader('Content-Type', 'application/json');
        res.setHeader('Content-Disposition', `attachment; filename="compliance-report-${id}.json"`);
        res.json({
          success: true,
          data: report,
        });
      } else {
        // For CSV and PDF, you would need additional libraries
        res.status(400).json({
          success: false,
          error: {
            code: 'FORMAT_NOT_SUPPORTED',
            message: `Format ${format} not yet supported / Định dạng ${format} chưa được hỗ trợ`,
          },
        });
      }
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'EXPORT_REPORT_FAILED',
          message: getErrorMessage(error) || 'Failed to export report',
        },
      });
    }
  }

  /**
   * EN: Publish report
   * VI: Xuất bản báo cáo
   */
  async publish(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const report = await complianceService.publishReport(id, req);

      res.json({
        success: true,
        data: report,
        message: 'Report published successfully / Báo cáo đã được xuất bản thành công',
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'PUBLISH_REPORT_FAILED',
          message: getErrorMessage(error) || 'Failed to publish report',
        },
      });
    }
  }
}

export const complianceController = new ComplianceController();
