import { Request, Response } from 'express';
import { DashboardService } from '../services/dashboard.service';
import logger from '@utils/logger';

export class DashboardController {
  private dashboardService: DashboardService;

  constructor() {
    this.dashboardService = new DashboardService();
  }

  /**
   * Get all KPI metrics for dashboard
   */
  async getKPIs(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user
      
      const kpis = await this.dashboardService.getKPIs(userId, dateRange, startDate, endDate, viewAsUser);
      
      res.json({
        success: true,
        data: kpis
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching KPIs:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch dashboard KPIs'
      });
    }
  }

  /**
   * Get request volume and status statistics
   */
  async getRequestStats(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const status = req.query.status as string | undefined; // Status filter (not used in stats - stats show all statuses)
      const priority = req.query.priority as string | undefined;
      const templateType = req.query.templateType as string | undefined;
      const department = req.query.department as string | undefined;
      const initiator = req.query.initiator as string | undefined;
      const approver = req.query.approver as string | undefined;
      const approverType = req.query.approverType as 'current' | 'any' | undefined;
      const search = req.query.search as string | undefined;
      const slaCompliance = req.query.slaCompliance as string | undefined;
      const viewAsUser = req.query.viewAsUser === 'true'; // When true, treat admin as normal user
      
      const stats = await this.dashboardService.getRequestStats(
        userId, 
        dateRange, 
        startDate, 
        endDate, 
        status,
        priority,
        templateType,
        department,
        initiator,
        approver,
        approverType,
        search,
        slaCompliance,
        viewAsUser
      );
      
      res.json({
        success: true,
        data: stats
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching request stats:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch request statistics'
      });
    }
  }

  /**
   * Get TAT efficiency metrics
   */
  async getTATEfficiency(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const efficiency = await this.dashboardService.getTATEfficiency(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: efficiency
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching TAT efficiency:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch TAT efficiency metrics'
      });
    }
  }

  /**
   * Get approver load statistics
   */
  async getApproverLoad(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const load = await this.dashboardService.getApproverLoad(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: load
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching approver load:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch approver load statistics'
      });
    }
  }

  /**
   * Get engagement and quality metrics
   */
  async getEngagementStats(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const engagement = await this.dashboardService.getEngagementStats(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: engagement
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching engagement stats:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch engagement statistics'
      });
    }
  }

  /**
   * Get AI insights and closure metrics
   */
  async getAIInsights(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const insights = await this.dashboardService.getAIInsights(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: insights
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching AI insights:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch AI insights'
      });
    }
  }

  /**
   * Get AI Remark Utilization metrics with monthly trends
   */
  async getAIRemarkUtilization(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const utilization = await this.dashboardService.getAIRemarkUtilization(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: utilization
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching AI remark utilization:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch AI remark utilization'
      });
    }
  }

  /**
   * Get Approver Performance metrics with pagination
   */
  async getApproverPerformance(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 10);
      const priority = req.query.priority as string | undefined;
      const slaCompliance = req.query.slaCompliance as string | undefined;
      
      const result = await this.dashboardService.getApproverPerformance(userId, dateRange, page, limit, startDate, endDate, priority, slaCompliance);
      
      res.json({
        success: true,
        data: result.performance,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching approver performance:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch approver performance metrics'
      });
    }
  }

  /**
   * Get recent activity feed
   */
  async getRecentActivity(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 10);
      const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user
      
      const result = await this.dashboardService.getRecentActivity(userId, page, limit, viewAsUser);
      
      res.json({
        success: true,
        data: result.activities,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching recent activity:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch recent activity'
      });
    }
  }

  /**
   * Get critical/high priority requests with pagination
   */
  async getCriticalRequests(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 10);
      const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user
      
      const result = await this.dashboardService.getCriticalRequests(userId, page, limit, viewAsUser);
      
      res.json({
        success: true,
        data: result.criticalRequests,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching critical requests:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch critical requests'
      });
    }
  }

  /**
   * Get upcoming deadlines with pagination
   */
  async getUpcomingDeadlines(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 10);
      const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user
      
      const result = await this.dashboardService.getUpcomingDeadlines(userId, page, limit, viewAsUser);
      
      res.json({
        success: true,
        data: result.deadlines,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching upcoming deadlines:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch upcoming deadlines'
      });
    }
  }

  /**
   * Get department-wise statistics
   */
  async getDepartmentStats(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const stats = await this.dashboardService.getDepartmentStats(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: stats
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching department stats:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch department statistics'
      });
    }
  }

  /**
   * Get priority distribution statistics
   */
  async getPriorityDistribution(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const distribution = await this.dashboardService.getPriorityDistribution(userId, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: distribution
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching priority distribution:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch priority distribution'
      });
    }
  }

  /**
   * Get Request Lifecycle Report
   */
  async getLifecycleReport(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 50);
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const result = await this.dashboardService.getLifecycleReport(userId, page, limit, dateRange, startDate, endDate);
      
      res.json({
        success: true,
        data: result.lifecycleData,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching lifecycle report:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch lifecycle report'
      });
    }
  }

  /**
   * Get enhanced User Activity Log Report
   */
  async getActivityLogReport(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 50);
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const filterUserId = req.query.filterUserId as string | undefined;
      const filterType = req.query.filterType as string | undefined;
      const filterCategory = req.query.filterCategory as string | undefined;
      const filterSeverity = req.query.filterSeverity as string | undefined;
      
      const result = await this.dashboardService.getActivityLogReport(
        userId, 
        page, 
        limit, 
        dateRange,
        filterUserId,
        filterType,
        filterCategory,
        filterSeverity,
        startDate,
        endDate
      );
      
      res.json({
        success: true,
        data: result.activities,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching activity log report:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch activity log report'
      });
    }
  }

  /**
   * Get list of departments (metadata for filtering)
   * GET /api/v1/dashboard/metadata/departments
   */
  async getDepartments(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      if (!userId) {
        res.status(401).json({
          success: false,
          message: 'Unauthorized',
          timestamp: new Date()
        });
        return;
      }

      const departments = await this.dashboardService.getDepartments(userId);

      res.status(200).json({
        success: true,
        message: 'Departments retrieved successfully',
        data: {
          departments
        },
        timestamp: new Date()
      });
    } catch (error) {
      logger.error('[Dashboard] Get Departments failed:', error);
      res.status(500).json({
        success: false,
        message: 'Internal server error',
        timestamp: new Date()
      });
    }
  }

  async getWorkflowAgingReport(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const threshold = Number(req.query.threshold || 7);
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 50);
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      
      const result = await this.dashboardService.getWorkflowAgingReport(
        userId,
        threshold,
        page,
        limit,
        dateRange,
        startDate,
        endDate
      );
      
      res.json({
        success: true,
        data: result.agingData,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching workflow aging report:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch workflow aging report'
      });
    }
  }

  /**
   * Get single approver stats only (separate API for performance)
   */
  async getSingleApproverStats(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const approverId = req.query.approverId as string;
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const priority = req.query.priority as string | undefined;
      const slaCompliance = req.query.slaCompliance as string | undefined;
      
      if (!approverId) {
        res.status(400).json({
          success: false,
          error: 'Approver ID is required'
        });
        return;
      }
      
      const stats = await this.dashboardService.getSingleApproverStats(
        userId,
        approverId,
        dateRange,
        startDate,
        endDate,
        priority,
        slaCompliance
      );
      
      res.json({
        success: true,
        data: stats
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching single approver stats:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch approver stats'
      });
    }
  }

  /**
   * Get requests filtered by approver ID for detailed performance analysis
   */
  async getRequestsByApprover(req: Request, res: Response): Promise<void> {
    try {
      const userId = (req as any).user?.userId;
      const approverId = req.query.approverId as string;
      const page = Number(req.query.page || 1);
      const limit = Number(req.query.limit || 50);
      const dateRange = req.query.dateRange as string | undefined;
      const startDate = req.query.startDate as string | undefined;
      const endDate = req.query.endDate as string | undefined;
      const status = req.query.status as string | undefined;
      const priority = req.query.priority as string | undefined;
      const slaCompliance = req.query.slaCompliance as string | undefined;
      const search = req.query.search as string | undefined;
      
      if (!approverId) {
        res.status(400).json({
          success: false,
          error: 'Approver ID is required'
        });
        return;
      }
      
      const result = await this.dashboardService.getRequestsByApprover(
        userId,
        approverId,
        page,
        limit,
        dateRange,
        startDate,
        endDate,
        status,
        priority,
        slaCompliance,
        search
      );
      
      res.json({
        success: true,
        data: result.requests,
        pagination: {
          currentPage: result.currentPage,
          totalPages: result.totalPages,
          totalRecords: result.totalRecords,
          limit: result.limit
        }
      });
    } catch (error) {
      logger.error('[Dashboard] Error fetching requests by approver:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch requests by approver'
      });
    }
  }
}

