import axiosInstance, { fetcher } from '@/utils/axios';
const endpointPrefix = '/api/hr/candidates';

export const candidatesEndpoints = {
  base: endpointPrefix,
  byId: (id: string) => `${endpointPrefix}/${id}`,
  byType: (type: string) => `${endpointPrefix}/type/${type}`,
  status: (id: string) => `${endpointPrefix}/${id}/status`,
  scheduleRdv: (id: string) => `${endpointPrefix}/${id}/schedule-rdv`,
  markAbsent: (id: string) => `${endpointPrefix}/${id}/mark-absent`,
  replanifyRdv: (id: string) => `${endpointPrefix}/${id}/replanify-rdv`,
  search: `${endpointPrefix}/search`,
  searchAdvanced: `${endpointPrefix}/search-advanced`,
  statusList: (status: string) => `${endpointPrefix}/status/${status}`,
  rdvSemaine: `${endpointPrefix}/rdv-semaine`,
  rdvPeriod: `${endpointPrefix}/rdv-period`,
  absent: `${endpointPrefix}/absent`,
  refusedBlacklisted: `${endpointPrefix}/refused-blacklisted`,
  followUp: `${endpointPrefix}/follow-up`,
  sendEmail: `${endpointPrefix}/send-email`,
  sendTemplateEmail: `${endpointPrefix}/send-template-email`,
  sendForm: `${endpointPrefix}/send-form`,
  statistics: `${endpointPrefix}/statistics`,
  statuses: `${endpointPrefix}/statuses`,
  types: `${endpointPrefix}/types`,
  bulkUpdateStatus: `${endpointPrefix}/bulk-update-status`,
  bulkSendEmail: `${endpointPrefix}/bulk-send-email`,
  exportStart: `${endpointPrefix}/export`,
  exportDownload: `${endpointPrefix}/export/download`,
  departments: `/api/hr/departments`,
};

export type CandidateStatus = 'TO_PROCESS' | 'IN_PROGRESS' | 'RETAINED' | 'VALIDATED' | 'REFUSED' | 'BLACKLISTED' | 'ABSENT';
export enum AppointmentStatus {
  NO_APPOINTMENT = 'NO_APPOINTMENT',
  SCHEDULED = 'SCHEDULED',
  ATTENDED = 'ATTENDED',
  MISSED = 'MISSED',
  CANCELLED = 'CANCELLED',
  RESCHEDULED = 'RESCHEDULED'
}
export type SourceCandidat = 
  | 'WELCOME_TO_THE_JUNGLE'
  | 'AUTRE'
  | 'POLE_EMPLOI'
  | 'RECOMMENDATION'
  | 'SITE_WEB'
  | 'APEC'
  | 'LINKEDIN'
  | 'SPONTANEE'
  | 'INDEED';

export interface CandidateDTO {
  id: string;
  lastName: string;
  firstName: string;
  email: string;
  professionalEmail?: string;
  phone: string;
  age: number;
  address?: string;
  postalCode: string;
  city: string;
  department: string;
  type: 'DRIVER' | 'SEDENTARY';
  status: CandidateStatus;
  appointmentStatus : AppointmentStatus;
  sourceCandidate?: SourceCandidat;
  drivingLicenseDuration?: string;
  circuitProximity?: string;
  availability?: string;
  callFollowUp?: string;
  callBackDate?: string;
  agencyAppointmentDateTime?: string;
  refusalReason?: string;
  document?: string;
  contractDocument?: string;
  contractStatus?: string;
  applicationDate: string;
  createdDate: string;
  lastModifiedDate: string;
  totalFormSubmissions: number;
  completedFormSubmissions: number;
  totalEmails: number;
  deliveredEmails: number;
  fullName: string;
  sedentary: boolean;
  typeLabel: string;
  contractLabel: string;
  driver: boolean;
}

export interface CreateCandidateRequest {
  firstName: string;
  lastName: string;
  email: string;
  emailPro?: string;
  phone: string;
  age: number;
  address: string;
  postalCode: string;
  city: string;
  department: string;
  type: 'DRIVER' | 'SEDENTARY';
  sourceCandidat: SourceCandidat;
  licenseDuration?: number;
  circuitProximity?: string;
  availability?: string;
  applicationDate: string;
  callFollow?: string;
  callOrCallbackDate?: string;
}

export interface SendEmailRequest {
  candidateId: string;
  subject: string;
  message: string;
}

export interface SendFormRequest {
  candidateId: string;
  formId: string;
  observation?: string;
}

export interface PageResponse<T> {
  content: T[];
  totalElements: number;
  totalPages: number;
  size: number;
  number: number;
  first: boolean;
  last: boolean;
}

export interface ExportCandidateRequest {
  candidateIds?: string[];
  statuses?: string[];
  types?: string[];
  sourceCandidates?: string[];
  startDate?: string;
  endDate?: string;
  userId?: number;
}

export interface ExportCandidateResponse {
  exportPath: string;
}

export interface Department {
  id: number;
  name: string;
}

export const candidatesApi = {
  createCandidate: async (data: CreateCandidateRequest): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.base, {}], 'post', data);
  },

  getCandidateById: async (id: string): Promise<CandidateDTO> => {
    return fetcher(candidatesEndpoints.byId(id), 'get');
  },

  getAllCandidates: async (
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher([candidatesEndpoints.base, { params: { page, size } }], 'get');
  },

  updateCandidate: async (
    id: string,
    data: Partial<CandidateDTO>
  ): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.byId(id), {}], 'put', data);
  },

  deleteCandidate: async (id: string): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.byId(id), {}], 'delete');
  },

  updateCandidateStatus: async (
    id: string,
    status: string,
    reason?: string
  ): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.status(id), { params: { status, reason } }], 'put');
  },

  scheduleRdv: async (id: string, rdvDateTime: string): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.scheduleRdv(id), { params: { rdvDateTime } }], 'post');
  },

  markAsAbsent: async (id: string): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.markAbsent(id), {}], 'post');
  },

  replanifyRdv: async (id: string, rdvDateTime: string): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.replanifyRdv(id), { params: { rdvDateTime } }], 'post');
  },

  searchCandidatesAdvanced: async (
    filters: Record<string, any>,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    const cleanFilters = Object.entries(filters).reduce(
      (acc, [key, value]) => {
        if (value !== null && value !== undefined && value !== '') acc[key] = value;
        return acc;
      },
      {} as Record<string, any>
    );
    const params = { ...cleanFilters, page, size };
    return fetcher([candidatesEndpoints.searchAdvanced, { params }], 'get');
  },
  checkEmailExists: async (email: string): Promise<boolean> => {
    if (!email) return false;
    const params = { email, page: 0, size: 1 } as Record<string, any>;
    try {
      const result = await fetcher([candidatesEndpoints.searchAdvanced, { params }], 'get');
      return (result?.totalElements || 0) > 0;
    } catch {
      return false;
    }
  },

  getCandidatesByStatus: async (
    status: string,
    type?: string,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher(
      [candidatesEndpoints.statusList(status), { params: { type, page, size } }],
      'get'
    );
  },

  getCandidatesByType: async (type: string, page: number = 0, size: number = 20): Promise<PageResponse<CandidateDTO>> => {
    return fetcher([candidatesEndpoints.byType(type), { params: { type, page, size } }], 'get');
  },

  getRdvSemaineCandidates: async (type?: string, page: number = 0, size: number = 20): Promise<PageResponse<CandidateDTO>> => {
    return fetcher([candidatesEndpoints.rdvSemaine, { params: { type, page, size } }], 'get');
  },

  getCandidatesWithRdvInPeriod: async (
    startDate: string,
    endDate: string,
    type?: string,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher(
      [candidatesEndpoints.rdvPeriod, { params: { startDate, endDate, type, page, size } }],
      'get'
    );
  },

  getAbsentCandidates: async (
    type?: string,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher([candidatesEndpoints.absent, { params: { type, page, size } }], 'get');
  },

  getRefusedAndBlacklistedCandidates: async (
    type?: string,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher(
      [candidatesEndpoints.refusedBlacklisted, { params: { type, page, size } }],
      'get'
    );
  },

  searchCandidates: async (
    query: string,
    page: number = 0,
    size: number = 20
  ): Promise<PageResponse<CandidateDTO>> => {
    return fetcher([candidatesEndpoints.search, { params: { q: query, page, size } }], 'get');
  },

  getCandidatesNeedingFollowUp: async (): Promise<CandidateDTO[]> => {
    return fetcher(candidatesEndpoints.followUp, 'get');
  },

  sendEmailToCandidate: async (data: SendEmailRequest): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.sendEmail, {}], 'post', data);
  },

  sendTemplateEmail: async (
    candidateId: string,
    templateName: string,
    templateData?: Record<string, any>
  ): Promise<{ message: string }> => {
    return fetcher(
      [candidatesEndpoints.sendTemplateEmail, { params: { candidateId, templateName } }],
      'post',
      templateData || {}
    );
  },

  sendFormToCandidate: async (data: SendFormRequest): Promise<{ message: string }> => {
    return fetcher([candidatesEndpoints.sendForm, {}], 'post', data);
  },

  getCandidateStatistics: async (): Promise<Record<string, number>> => {
    return fetcher(candidatesEndpoints.statistics, 'get');
  },

  getAllStatuses: async (): Promise<string[]> => {
    return fetcher(candidatesEndpoints.statuses, 'get');
  },

  getAllTypes: async (): Promise<string[]> => {
    return fetcher(candidatesEndpoints.types, 'get');
  },

  bulkUpdateStatus: async (
    candidateIds: string[],
    status: string,
    reason?: string
  ): Promise<{ message: string }> => {
    return fetcher(
      [
        candidatesEndpoints.bulkUpdateStatus,
        { params: { candidateIds: candidateIds.join(','), status, reason } },
      ],
      'post'
    );
  },

  bulkSendEmail: async (
    candidateIds: string[],
    subject: string,
    message: string
  ): Promise<{ message: string }> => {
    return fetcher(
      [
        candidatesEndpoints.bulkSendEmail,
        { params: { candidateIds: candidateIds.join(','), subject, message } },
      ],
      'post'
    );
  },

  exportCandidates: async (
    exportData: ExportCandidateRequest
  ): Promise<ExportCandidateResponse> => {
    const params: Record<string, any> = {};
    if (exportData.userId !== undefined) params.userId = exportData.userId;
    if (exportData.startDate) params.startDate = exportData.startDate;
    if (exportData.endDate) params.endDate = exportData.endDate;
    if (exportData.candidateIds?.length) params.candidateIds = exportData.candidateIds.join(',');
    if (exportData.statuses?.length) params.statuses = exportData.statuses.join(',');
    if (exportData.types?.length) params.types = exportData.types.join(',');
    if (exportData.sourceCandidates?.length)
      params.sourceCandidates = exportData.sourceCandidates.join(',');
    return fetcher([candidatesEndpoints.exportStart, { params }], 'post');
  },

  downloadExportFile: async (filePath: string): Promise<Blob> => {
    const response = await axiosInstance.get(candidatesEndpoints.exportDownload, {
      params: { filePath },
      responseType: 'blob',
    });
    return response.data;
  },

  getDepartments: async (): Promise<Department[]> => {
    return fetcher([candidatesEndpoints.departments, {}], 'get');
  },
};
