// Employee (staff) endpoints, incl. the Employee<->User cross-link, bank details,
// documents, salary structure, loans, and leave balances (docs/13-BACKEND-HRM-API.md §3).
import { apiRequest, apiRequestWithETag, buildQuery } from "@/lib/api-client"
import { ApiResult, PagedResponse } from "@/types/common"
import {
  CreateEmployeeRequest,
  EmployeeBankDetail,
  EmployeeDetail,
  EmployeeDocument,
  EmployeeListItem,
  EmployeeLoan,
  EmployeeMatch,
  EmployeeSalaryStructure,
  EmployeeStatus,
  LeaveBalance,
  UpdateEmployeeRequest,
  UserMatch,
} from "@/types/hrm"

export interface ListEmployeesParams {
  page?: number
  pageSize?: number
  q?: string
  status?: EmployeeStatus
  departmentId?: number
  designationId?: number
  branchId?: number
}

export interface CreateSalaryStructureRequest {
  effectiveFrom: string
  basicSalary: number
  lines: { salaryComponentId: number; amount: number }[]
}

export interface CreateEmployeeLoanRequest {
  loanKind: "Loan" | "Advance"
  principalAmount: number
  interestRate: number
  installmentAmount: number
  numberOfInstallments: number
  startYear: number
  startMonth: number
}

export const employeesApi = {
  list(params: ListEmployeesParams = {}): Promise<PagedResponse<EmployeeListItem>> {
    return apiRequest<PagedResponse<EmployeeListItem>>(`/employees${buildQuery(params)}`)
  },
  get(employeeId: number): Promise<ApiResult<EmployeeDetail>> {
    return apiRequestWithETag<EmployeeDetail>(`/employees/${employeeId}`)
  },
  create(request: CreateEmployeeRequest): Promise<ApiResult<EmployeeDetail>> {
    return apiRequestWithETag<EmployeeDetail>("/employees", { method: "POST", body: request })
  },
  update(employeeId: number, request: UpdateEmployeeRequest, ifMatch: string): Promise<ApiResult<EmployeeDetail>> {
    return apiRequestWithETag<EmployeeDetail>(`/employees/${employeeId}`, { method: "PUT", body: request, ifMatch })
  },
  updateStatus(employeeId: number, status: EmployeeStatus): Promise<void> {
    return apiRequest<void>(`/employees/${employeeId}/status`, { method: "PATCH", body: { status } })
  },

  /** Advisory: does a System User already exist with this email? */
  emailLookup(email: string): Promise<{ match: UserMatch | null }> {
    return apiRequest<{ match: UserMatch | null }>(`/employees/email-lookup${buildQuery({ email })}`)
  },
  linkUser(employeeId: number, userId: number): Promise<void> {
    return apiRequest<void>(`/employees/${employeeId}/link-user`, { method: "POST", body: { userId } })
  },
  unlinkUser(employeeId: number): Promise<void> {
    return apiRequest<void>(`/employees/${employeeId}/link-user`, { method: "DELETE" })
  },

  listBankDetails(employeeId: number): Promise<EmployeeBankDetail[]> {
    return apiRequest<EmployeeBankDetail[]>(`/employees/${employeeId}/bank-details`)
  },
  replaceBankDetails(employeeId: number, items: EmployeeBankDetail[]): Promise<EmployeeBankDetail[]> {
    return apiRequest<EmployeeBankDetail[]>(`/employees/${employeeId}/bank-details`, { method: "PUT", body: { items } })
  },

  listDocuments(employeeId: number): Promise<EmployeeDocument[]> {
    return apiRequest<EmployeeDocument[]>(`/employees/${employeeId}/documents`)
  },
  async uploadDocument(
    employeeId: number,
    file: File,
    meta: { hrDocumentTypeId: number; issueDate?: string | null; expiryDate?: string | null; notes?: string | null }
  ): Promise<EmployeeDocument> {
    const form = new FormData()
    form.append("file", file)
    form.append("HrDocumentTypeId", String(meta.hrDocumentTypeId))
    if (meta.issueDate) form.append("IssueDate", meta.issueDate)
    if (meta.expiryDate) form.append("ExpiryDate", meta.expiryDate)
    if (meta.notes) form.append("Notes", meta.notes)
    return apiRequest<EmployeeDocument>(`/employees/${employeeId}/documents`, { method: "POST", body: form })
  },
  documentDownloadUrl(employeeId: number, documentId: number): string {
    return `/api/v1/employees/${employeeId}/documents/${documentId}/download`
  },
  setDocumentStatus(employeeId: number, documentId: number, status: "Active" | "Archived"): Promise<void> {
    return apiRequest<void>(`/employees/${employeeId}/documents/${documentId}/status`, { method: "PATCH", body: { status } })
  },

  salaryStructureHistory(employeeId: number): Promise<EmployeeSalaryStructure[]> {
    return apiRequest<EmployeeSalaryStructure[]>(`/employees/${employeeId}/salary-structure`)
  },
  createSalaryStructure(employeeId: number, request: CreateSalaryStructureRequest): Promise<EmployeeSalaryStructure> {
    return apiRequest<EmployeeSalaryStructure>(`/employees/${employeeId}/salary-structure`, { method: "POST", body: request })
  },

  listLoans(employeeId: number): Promise<EmployeeLoan[]> {
    return apiRequest<EmployeeLoan[]>(`/employees/${employeeId}/loans`)
  },
  createLoan(employeeId: number, request: CreateEmployeeLoanRequest): Promise<EmployeeLoan> {
    return apiRequest<EmployeeLoan>(`/employees/${employeeId}/loans`, { method: "POST", body: request })
  },

  listLeaveBalances(employeeId: number, year?: number): Promise<LeaveBalance[]> {
    return apiRequest<LeaveBalance[]>(`/employees/${employeeId}/leave-balances${buildQuery({ year })}`)
  },
}

// Re-exported for the Employee create form's cross-link chip (mirrors employeesApi.emailLookup in reverse).
export const employeeCrossLinkApi = {
  findStaffByEmail(email: string): Promise<{ match: EmployeeMatch | null }> {
    return apiRequest<{ match: EmployeeMatch | null }>(`/users/email-lookup${buildQuery({ email })}`)
  },
}
