import { AxiosResponse } from 'axios';
import axiosInstance from '@/utils/axios';
import { IRHAbsence, DriverShort, CollaboratorShort } from '@/shared/types/absence-rh';
import { Pageable } from '@/shared/types/client';

const BASE_URL = '/api/absence/rh-absences';
const EXPORT_BASE_URL = '/api/absence/export/rh-absence';

export type AbsenceFilters = {
  page: number;
  size: number;
  sort?: string;
  state?: string | string[];
  states?: string | string[];
  id?: string | number;
  firstName?: string;
  lastName?: string;
  absenceType?: string;
  absenceTypeString?: string;
  startDateFrom?: string;
  startDateTo?: string;
  endDateTo?: string;
  minHours?: number;
  maxHours?: number;
  functionType?: string;
  affectedToTrip?: boolean;
  absenceNumber?: string;
  authorizedBy?: string;
  validatedBy?: string;
  department?: string;
  receivingMethod?: string;
  requestType?: string;
};

export interface CreateAbsenceDto {
  userId: number;
  absenceType: string;
  startDate: string;
  endDate: string;
  numberOfDays: number;
  justificationFileUrl?: string | null;
  authorizedBy?: string | null;
  validatedBy?: string | null;
  hoursCount?: number | null;
  receivingMethod: string;
  state: string;
}

export interface ExportResponseDto {
  exportPath: string;
}

export const absenceEndpoints = {
  getAllDrivers: (): Promise<AxiosResponse<DriverShort[]>> => {
    return axiosInstance.get('/api/user/driver/allDrivers');
  },

  getAllCollaborators: (): Promise<AxiosResponse<CollaboratorShort[]>> => {
    return axiosInstance.get('/api/user/collaborators/allCollaborators');
  },

  createAbsence: (
    data: CreateAbsenceDto,
    file?: File | null
  ): Promise<AxiosResponse<IRHAbsence>> => {
    const formData = new FormData();
    formData.append('dto', JSON.stringify(data));

    if (file) {
      formData.append('file', file);
    }

    return axiosInstance.post(`/api/absence/createAgentAbsence`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
  },

  updateAbsence: (
    id: string | number,
    data: CreateAbsenceDto
  ): Promise<AxiosResponse<IRHAbsence>> => {
    return axiosInstance.put(`${BASE_URL}/${id}`, data);
  },

  getAbsenceById: (id: string | number): Promise<AxiosResponse<IRHAbsence>> => {
    return axiosInstance.get(`${BASE_URL}/${id}`);
  },

  getTraitedAbsences: (filters: AbsenceFilters): Promise<AxiosResponse<Pageable<IRHAbsence>>> => {
    const params: Record<string, any> = {
      id: filters.id,
      absenceNumber: filters.absenceNumber,
      firstName: filters.firstName,
      lastName: filters.lastName,
      absenceType: filters.absenceType,
      startDateFrom: filters.startDateFrom,
      startDateTo: filters.startDateTo,
      endDateTo: filters.endDateTo,
      minHours: filters.minHours,
      maxHours: filters.maxHours,
      authorizedBy: filters.authorizedBy,
      validatedBy: filters.validatedBy,
      department: filters.department,
      states: filters.states || filters.state,
      receivingMethod: filters.receivingMethod,
      affectedToTrip: filters.affectedToTrip,
      requestType: filters.requestType,
    };

    if (
      filters.functionType &&
      (filters.functionType === 'DRIVER' || filters.functionType === 'SEDENTARY')
    ) {
      params.functionType = filters.functionType;
    }

    if (filters.page !== undefined) {
      params.page = filters.page.toString();
    }
    if (filters.size !== undefined) {
      params.size = filters.size.toString();
    }

    return axiosInstance.get(`${BASE_URL}/traitees`, { params });
  },

  getNonTraitedAbsences: (
    filters: AbsenceFilters
  ): Promise<AxiosResponse<Pageable<IRHAbsence>>> => {
    const params: Record<string, any> = {
      id: filters.id,
      absenceNumber: filters.absenceNumber,
      firstName: filters.firstName,
      lastName: filters.lastName,
      absenceType: filters.absenceType,
      startDateFrom: filters.startDateFrom,
      startDateTo: filters.startDateTo,
      endDateTo: filters.endDateTo,
      minHours: filters.minHours,
      maxHours: filters.maxHours,
      authorizedBy: filters.authorizedBy,
      validatedBy: filters.validatedBy,
      department: filters.department,
      states: filters.states || filters.state,
      receivingMethod: filters.receivingMethod,
      affectedToTrip: filters.affectedToTrip,
      requestType: filters.requestType,
    };

    if (
      filters.functionType &&
      (filters.functionType === 'DRIVER' || filters.functionType === 'SEDENTARY')
    ) {
      params.functionType = filters.functionType;
    }

    if (filters.page !== undefined) {
      params.page = filters.page.toString();
    }
    if (filters.size !== undefined) {
      params.size = filters.size.toString();
    }

    // Remove any undefined or null values from params
    Object.keys(params).forEach(key => {
      if (params[key] === undefined || params[key] === null) {
        delete params[key];
      }
    });

    return axiosInstance.get(`${BASE_URL}/non-traitees`, { params });
  },

  updateAbsenceStatus: (
    id: string | number,
    state: string,
    comment?: string
  ): Promise<AxiosResponse<IRHAbsence>> => {
  
    const params: { state: string; comment?: string } = { state };
    if (comment) {
      params.comment = comment;
    }
    return axiosInstance.put(`${BASE_URL}/${id}/status`, null, { params });
  },

  // Export endpoints
  startExport: async (
    filters: Partial<AbsenceFilters> = {}
  ): Promise<AxiosResponse<ExportResponseDto>> => {
    const params = new URLSearchParams();

    if (filters.firstName) params.append('firstName', filters.firstName);
    if (filters.lastName) params.append('lastName', filters.lastName);
    if (filters.absenceType) params.append('absenceType', filters.absenceType);
    if (filters.startDateFrom) params.append('startDate', filters.startDateFrom);
    if (filters.startDateTo) params.append('endDate', filters.startDateTo);
    if (filters.authorizedBy) params.append('reportedBy', filters.authorizedBy);
    if (filters.department) params.append('department', filters.department);
    if (filters.state && Array.isArray(filters.state)) {
      filters.state.forEach((state) => params.append('states', state));
    }

    // Use POST as defined in your controller
    return axiosInstance.post(`${EXPORT_BASE_URL}`, null, { params });
  },

  downloadExport: async (filePath: string): Promise<AxiosResponse<Blob>> => {
    return axiosInstance.get(`${EXPORT_BASE_URL}/download`, {
      params: { filePath },
      responseType: 'blob', // Important for file downloads
    });
  },
};
