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

import { getErrorMessage } from '../../../utils/error-utils';
import { DateRangeDto, RiskFiltersDto } from '../access.dto';

import { accessAnalyticsService } from './analytics.service';

/**
 * EN: Access Analytics Controller
 * VI: Controller phân tích truy cập
 */
export class AccessAnalyticsController {
  /**
   * EN: Get usage statistics
   * VI: Lấy thống kê sử dụng
   */
  async usage(req: Request, res: Response): Promise<void> {
    try {
      const period = DateRangeDto.parse({
        startDate: req.query.startDate as string || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
        endDate: req.query.endDate as string || new Date().toISOString(),
      });

      const stats = await accessAnalyticsService.getUsageStats(period);

      res.json({
        success: true,
        data: stats,
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid date range',
            details: error.issues,
          },
        });
        return;
      }

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

  /**
   * EN: Get permission distribution
   * VI: Lấy phân bố quyền
   */
  async permissions(_req: Request, res: Response): Promise<void> {
    try {
      const distribution = await accessAnalyticsService.getPermissionDistribution();

      res.json({
        success: true,
        data: distribution,
      });
    } catch (error: unknown) {
      res.status(500).json({
        success: false,
        error: {
          code: 'GET_PERMISSION_DISTRIBUTION_FAILED',
          message: getErrorMessage(error) || 'Failed to get permission distribution',
        },
      });
    }
  }

  /**
   * EN: Get user access summary
   * VI: Lấy tổng quan truy cập của user
   */
  async userSummary(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const summary = await accessAnalyticsService.getUserAccessSummary(id);

      res.json({
        success: true,
        data: summary,
      });
    } catch (error: unknown) {
      res.status(500).json({
        success: false,
        error: {
          code: 'GET_USER_SUMMARY_FAILED',
          message: getErrorMessage(error) || 'Failed to get user access summary',
        },
      });
    }
  }

  /**
   * EN: Get access trends
   * VI: Lấy xu hướng truy cập
   */
  async trends(req: Request, res: Response): Promise<void> {
    try {
      const period = DateRangeDto.parse({
        startDate: req.query.startDate as string || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
        endDate: req.query.endDate as string || new Date().toISOString(),
      });

      const trends = await accessAnalyticsService.getAccessTrends(period);

      res.json({
        success: true,
        data: trends,
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid date range',
            details: error.issues,
          },
        });
        return;
      }

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

  /**
   * EN: Get risk analysis
   * VI: Lấy phân tích rủi ro
   */
  async risks(req: Request, res: Response): Promise<void> {
    try {
      const filters = RiskFiltersDto.parse({
        minScore: req.query.minScore ? parseInt(req.query.minScore as string) : undefined,
        maxScore: req.query.maxScore ? parseInt(req.query.maxScore as string) : undefined,
        level: req.query.level as any,
        userId: req.query.userId as string,
      });

      const analysis = await accessAnalyticsService.getRiskAnalysis(filters);

      res.json({
        success: true,
        data: analysis,
      });
    } 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: 'GET_RISK_ANALYSIS_FAILED',
          message: getErrorMessage(error) || 'Failed to get risk analysis',
        },
      });
    }
  }
}

export const accessAnalyticsController = new AccessAnalyticsController();
