import apiClient from './client'

export interface ProcessFacesRequest {
  batch_size?: number
  detector_backend: string
  model_name: string
}

export interface ProcessFacesResponse {
  job_id: string
  message: string
  batch_size?: number
  detector_backend: string
  model_name: string
}

export interface FaceItem {
  id: number
  photo_id: number
  quality_score: number
  face_confidence: number
  location: string
  pose_mode?: string
  excluded?: boolean
}

export interface UnidentifiedFacesResponse {
  items: FaceItem[]
  page: number
  page_size: number
  total: number
}

export interface SimilarFaceItem {
  id: number
  photo_id: number
  similarity: number
  location: string
  quality_score: number
  filename: string
  pose_mode?: string
}

export interface SimilarFacesResponse {
  base_face_id: number
  items: SimilarFaceItem[]
}

export interface FaceSimilarityPair {
  face_id_1: number
  face_id_2: number
  similarity: number  // 0-1 range
  confidence_pct: number  // 0-100 range
}

export interface BatchSimilarityRequest {
  face_ids: number[]
  min_confidence?: number  // 0-100, default 60
}

export interface BatchSimilarityResponse {
  pairs: FaceSimilarityPair[]
}

export interface IdentifyFaceRequest {
  person_id?: number
  first_name?: string
  last_name?: string
  middle_name?: string
  maiden_name?: string
  date_of_birth?: string
  additional_face_ids?: number[]
}

export interface IdentifyFaceResponse {
  identified_face_ids: number[]
  person_id: number
  created_person: boolean
}

export interface FaceUnmatchResponse {
  face_id: number
  message: string
}

export interface BatchUnmatchRequest {
  face_ids: number[]
}

export interface BatchUnmatchResponse {
  unmatched_face_ids: number[]
  count: number
  message: string
}

export interface AutoMatchRequest {
  tolerance: number
  auto_accept?: boolean
  auto_accept_threshold?: number
}

export interface AutoMatchFaceItem {
  id: number
  photo_id: number
  photo_filename: string
  location: string
  quality_score: number
  similarity: number  // Confidence percentage (0-100)
  distance: number
  pose_mode?: string
}

export interface AutoMatchPersonItem {
  person_id: number
  person_name: string
  reference_face_id: number
  reference_photo_id: number
  reference_photo_filename: string
  reference_location: string
  reference_pose_mode?: string
  face_count: number
  matches: AutoMatchFaceItem[]
  total_matches: number
}

export interface AutoMatchPersonSummary {
  person_id: number
  person_name: string
  reference_face_id: number
  reference_photo_id: number
  reference_photo_filename: string
  reference_location: string
  reference_pose_mode?: string
  face_count: number
  total_matches: number
}

export interface AutoMatchPeopleResponse {
  people: AutoMatchPersonSummary[]
  total_people: number
}

export interface AutoMatchPersonMatchesResponse {
  person_id: number
  matches: AutoMatchFaceItem[]
  total_matches: number
}

export interface AutoMatchResponse {
  people: AutoMatchPersonItem[]
  total_people: number
  total_matches: number
  auto_accepted?: boolean
  auto_accepted_faces?: number
  skipped_persons?: number
  skipped_matches?: number
}

export interface AcceptMatchesRequest {
  face_ids: number[]
}

export interface MaintenanceFaceItem {
  id: number
  photo_id: number
  photo_path: string
  photo_filename: string
  quality_score: number
  person_id: number | null
  person_name: string | null
  excluded: boolean
}

export interface MaintenanceFacesResponse {
  items: MaintenanceFaceItem[]
  total: number
}

export interface DeleteFacesRequest {
  face_ids: number[]
}

export interface DeleteFacesResponse {
  deleted_face_ids: number[]
  count: number
  message: string
}

export const facesApi = {
  /**
   * Start face processing job
   */
  processFaces: async (request: ProcessFacesRequest): Promise<ProcessFacesResponse> => {
    const response = await apiClient.post<ProcessFacesResponse>('/api/v1/faces/process', request)
    return response.data
  },
  getUnidentified: async (params: {
    page?: number
    page_size?: number
    min_quality?: number
    date_from?: string
    date_to?: string
    date_taken_from?: string
    date_taken_to?: string
    date_processed?: string
    date_processed_from?: string
    date_processed_to?: string
    sort_by?: 'quality' | 'date_taken' | 'date_added'
    sort_dir?: 'asc' | 'desc'
    tag_names?: string
    match_all?: boolean
    photo_ids?: string
    include_excluded?: boolean
  }): Promise<UnidentifiedFacesResponse> => {
    const response = await apiClient.get<UnidentifiedFacesResponse>('/api/v1/faces/unidentified', {
      params,
    })
    return response.data
  },
  getSimilar: async (faceId: number, includeExcluded?: boolean): Promise<SimilarFacesResponse> => {
    const response = await apiClient.get<SimilarFacesResponse>(`/api/v1/faces/${faceId}/similar`, {
      params: { include_excluded: includeExcluded || false },
    })
    return response.data
  },
  batchSimilarity: async (request: BatchSimilarityRequest): Promise<BatchSimilarityResponse> => {
    const response = await apiClient.post<BatchSimilarityResponse>('/api/v1/faces/batch-similarity', request)
    return response.data
  },
  identify: async (faceId: number, payload: IdentifyFaceRequest): Promise<IdentifyFaceResponse> => {
    const response = await apiClient.post<IdentifyFaceResponse>(`/api/v1/faces/${faceId}/identify`, payload)
    return response.data
  },
  setExcluded: async (faceId: number, excluded: boolean): Promise<{ face_id: number; excluded: boolean; message: string }> => {
    const response = await apiClient.put<{ face_id: number; excluded: boolean; message: string }>(
      `/api/v1/faces/${faceId}/excluded?excluded=${excluded}`
    )
    return response.data
  },
  unmatch: async (faceId: number): Promise<FaceUnmatchResponse> => {
    const response = await apiClient.post<FaceUnmatchResponse>(`/api/v1/faces/${faceId}/unmatch`)
    return response.data
  },
  batchUnmatch: async (payload: BatchUnmatchRequest): Promise<BatchUnmatchResponse> => {
    const response = await apiClient.post<BatchUnmatchResponse>('/api/v1/faces/batch-unmatch', payload)
    return response.data
  },
  autoMatch: async (request: AutoMatchRequest): Promise<AutoMatchResponse> => {
    const response = await apiClient.post<AutoMatchResponse>('/api/v1/faces/auto-match', request)
    return response.data
  },
  getAutoMatchPeople: async (params?: {
    filter_frontal_only?: boolean
  }): Promise<AutoMatchPeopleResponse> => {
    const response = await apiClient.get<AutoMatchPeopleResponse>('/api/v1/faces/auto-match/people', {
      params,
    })
    return response.data
  },
  getAutoMatchPersonMatches: async (
    personId: number,
    params?: {
      tolerance?: number
      filter_frontal_only?: boolean
    }
  ): Promise<AutoMatchPersonMatchesResponse> => {
    const response = await apiClient.get<AutoMatchPersonMatchesResponse>(
      `/api/v1/faces/auto-match/people/${personId}/matches`,
      { params }
    )
    return response.data
  },
  getMaintenanceFaces: async (params: {
    page?: number
    page_size?: number
    min_quality?: number
    max_quality?: number
    excluded_filter?: 'all' | 'excluded' | 'included'
    identified_filter?: 'all' | 'identified' | 'unidentified'
  }): Promise<MaintenanceFacesResponse> => {
    const response = await apiClient.get<MaintenanceFacesResponse>('/api/v1/faces/maintenance', {
      params,
    })
    return response.data
  },
  deleteFaces: async (request: DeleteFacesRequest): Promise<DeleteFacesResponse> => {
    const response = await apiClient.post<DeleteFacesResponse>('/api/v1/faces/delete', request)
    return response.data
  },
}

export default facesApi

