/**
 * Filtering utilities for requests
 */

import dayjs from 'dayjs';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import type { RequestFilters } from '../types/requests.types';

dayjs.extend(isSameOrAfter);
dayjs.extend(isSameOrBefore);

/**
 * Apply filters excluding status filter (for stats calculation)
 */
export function applyFiltersWithoutStatus(data: any[], filters: RequestFilters): any[] {
  const filtersWithoutStatus = { ...filters, status: undefined };
  return applyFilters(data, filtersWithoutStatus);
}

export function applyFilters(data: any[], filters: RequestFilters): any[] {
  let filteredData = [...data];

  // Search filter
  if (filters.search) {
    const searchLower = filters.search.toLowerCase();
    filteredData = filteredData.filter((req: any) =>
      req.title?.toLowerCase().includes(searchLower) ||
      req.description?.toLowerCase().includes(searchLower) ||
      req.requestNumber?.toLowerCase().includes(searchLower) ||
      req.request_number?.toLowerCase().includes(searchLower)
    );
  }

  // Status filter
  if (filters.status && filters.status !== 'all') {
    if (filters.status.toLowerCase() === 'pending') {
      filteredData = filteredData.filter((req: any) => {
        const reqStatus = (req.status || '').toString().toUpperCase();
        const isPaused = req.pauseInfo?.isPaused || req.isPaused || false;
        // IN_PROGRESS is treated as PENDING (legacy support during migration)
        return (reqStatus === 'PENDING' || reqStatus === 'IN_PROGRESS') && !isPaused;
      });
    } else if (filters.status.toLowerCase() === 'paused') {
      filteredData = filteredData.filter((req: any) => {
        const reqStatus = (req.status || '').toString().toUpperCase();
        const isPaused = req.pauseInfo?.isPaused || req.isPaused || false;
        // Check both status enum and isPaused flag for compatibility
        return reqStatus === 'PAUSED' || isPaused;
      });
    } else {
      const statusUpper = filters.status.toUpperCase().replace('-', '_');
      filteredData = filteredData.filter((req: any) => {
        const reqStatus = (req.status || '').toString().toUpperCase();
        const isPaused = req.pauseInfo?.isPaused || req.isPaused || false;
        if (statusUpper === 'IN_PROGRESS' || statusUpper === 'IN-PROGRESS') {
          return reqStatus === 'IN_PROGRESS' && !isPaused;
        }
        return reqStatus === statusUpper && !isPaused; // Exclude paused from other statuses
      });
    }
  }

  // Priority filter
  if (filters.priority && filters.priority !== 'all') {
    filteredData = filteredData.filter((req: any) =>
      (req.priority || '').toString().toLowerCase() === filters.priority?.toLowerCase()
    );
  }

  // Department filter
  if (filters.department && filters.department !== 'all') {
    filteredData = filteredData.filter((req: any) => {
      const reqDepartment = req.department || req.initiator?.department || '';
      return reqDepartment === filters.department;
    });
  }

  // Initiator filter
  if (filters.initiator && filters.initiator !== 'all') {
    filteredData = filteredData.filter((req: any) => {
      const initiatorId = req.initiatorId ||
        req.initiator_id ||
        req.initiator?.userId ||
        req.initiator?.user_id ||
        (req.initiator && typeof req.initiator === 'object' && 'userId' in req.initiator ? req.initiator.userId : null);
      return initiatorId === filters.initiator;
    });
  }

  // Approver filter
  if (filters.approver && filters.approver !== 'all') {
    const approverType = filters.approverType || 'current';

    if (approverType === 'current') {
      filteredData = filteredData.filter((req: any) => {
        const approverId = req.currentApprover?.userId ||
          req.currentApprover?.user_id ||
          req.approvals?.find((a: any) => {
            const status = (a.status || '').toString().toUpperCase();
            return status === 'IN_PROGRESS' || status === 'PENDING';
          })?.approverId ||
          req.approvals?.find((a: any) => {
            const status = (a.status || '').toString().toUpperCase();
            return status === 'IN_PROGRESS' || status === 'PENDING';
          })?.approver_id ||
          req.currentApproverId ||
          req.current_approver_id;
        return approverId === filters.approver;
      });
    } else {
      filteredData = filteredData.filter((req: any) => {
        const allApproverIds: string[] = [];
        if (req.currentApprover?.userId) allApproverIds.push(req.currentApprover.userId);
        if (req.currentApprover?.user_id) allApproverIds.push(req.currentApprover.user_id);
        if (Array.isArray(req.approvals)) {
          req.approvals.forEach((a: any) => {
            if (a.approverId) allApproverIds.push(a.approverId);
            if (a.approver_id) allApproverIds.push(a.approver_id);
          });
        }
        return allApproverIds.includes(filters.approver || '');
      });
    }
  }

  // SLA compliance filter
  if (filters.slaCompliance && filters.slaCompliance !== 'all') {
    filteredData = filteredData.filter((req: any) => {
      const slaCompliance = filters.slaCompliance || '';
      if (slaCompliance.toLowerCase() === 'compliant') {
        const reqStatus = (req.status || '').toString().toUpperCase();
        const isCompleted = reqStatus === 'APPROVED' || reqStatus === 'REJECTED' || reqStatus === 'CLOSED';
        if (!isCompleted) return false;
        const slaStatus = req.currentLevelSLA?.status ||
          req.currentApprover?.sla?.status ||
          req.sla?.status ||
          req.summary?.sla?.status;
        if (!slaStatus) return true;
        return slaStatus !== 'breached' && slaStatus.toLowerCase() !== 'breached';
      }

      const slaStatus = req.currentLevelSLA?.status ||
        req.currentApprover?.sla?.status ||
        req.sla?.status ||
        req.summary?.sla?.status;

      if (!slaStatus) {
        return slaCompliance === 'on-track' || slaCompliance === 'on_track';
      }

      const statusMap: Record<string, string> = {
        'on-track': 'on_track',
        'on_track': 'on_track',
        'approaching': 'approaching',
        'critical': 'critical',
        'breached': 'breached'
      };

      const filterStatus = statusMap[slaCompliance.toLowerCase()] || slaCompliance.toLowerCase();
      return slaStatus === filterStatus || slaStatus.toLowerCase() === filterStatus;
    });
  }

  // Date range filter
  if (filters.dateRange) {
    let dateStart: Date | null = null;
    let dateEnd: Date | null = null;

    if (filters.dateRange === 'custom' && filters.startDate && filters.endDate) {
      dateStart = dayjs(filters.startDate).startOf('day').toDate();
      dateEnd = dayjs(filters.endDate).endOf('day').toDate();
    } else {
      const now = dayjs();
      switch (filters.dateRange) {
        case 'today':
          dateStart = now.startOf('day').toDate();
          dateEnd = now.endOf('day').toDate();
          break;
        case 'week':
          dateStart = now.startOf('week').toDate();
          dateEnd = now.endOf('week').toDate();
          break;
        case 'month':
          dateStart = now.startOf('month').toDate();
          dateEnd = now.endOf('month').toDate();
          break;
        default:
          break;
      }
    }

    if (dateStart && dateEnd) {
      filteredData = filteredData.filter((req: any) => {
        const submissionDate = req.submittedAt || req.submission_date || req.submitted_at;
        if (!submissionDate) {
          const createdDate = req.createdAt || req.created_at || req.created_date;
          if (!createdDate) return false;
          const reqDate = dayjs(createdDate).startOf('day').toDate();
          const dateStartOnly = dayjs(dateStart).startOf('day').toDate();
          const dateEndOnly = dayjs(dateEnd).endOf('day').toDate();
          return reqDate >= dateStartOnly && reqDate <= dateEndOnly;
        }
        const reqDate = dayjs(submissionDate).startOf('day').toDate();
        const dateStartOnly = dayjs(dateStart).startOf('day').toDate();
        const dateEndOnly = dayjs(dateEnd).endOf('day').toDate();
        return reqDate >= dateStartOnly && reqDate <= dateEndOnly;
      });
    }
  }

  return filteredData;
}

