// HRM DTOs mirroring ERPCore's Dtos/Hrm/*.cs (docs/13-BACKEND-HRM-API.md).
import { EntityStatus } from "@/types/common"

// --- Org masters ---

export interface Branch {
  branchId: number
  code: string
  name: string
  address: string | null
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export interface Department {
  departmentId: number
  code: string
  name: string
  parentDepartmentId: number | null
  headEmployeeId: number | null
  branchId: number | null
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export interface Designation {
  designationId: number
  code: string
  name: string
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export interface EmploymentType {
  employmentTypeId: number
  code: string
  name: string
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export interface WorkShift {
  workShiftId: number
  code: string
  name: string
  startTime: string // "HH:mm:ss"
  endTime: string
  isOvernight: boolean
  graceMinutes: number
  breakMinutes: number
  standardWorkingMinutes: number
  otMultiplier: number
  workingDaysMask: number
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export type HrDocumentCategory = "Identity" | "Educational" | "Contract" | "Certification" | "Statutory" | "Other"

export interface HrDocumentType {
  hrDocumentTypeId: number
  code: string
  name: string
  category: HrDocumentCategory
  requiredAtOnboarding: boolean
  expiryTracked: boolean
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

// --- Employee ---

export type EmployeeStatus = "Active" | "Suspended" | "Resigned" | "Terminated" | "Retired"
export type Gender = "Male" | "Female" | "Other"

export interface EmployeeListItem {
  employeeId: number
  employeeCode: string
  fullName: string
  email: string | null
  departmentId: number
  departmentName: string | null
  designationId: number
  designationName: string | null
  employmentTypeId: number
  employmentTypeName: string | null
  branchId: number | null
  branchName: string | null
  status: EmployeeStatus
  hasUserLink: boolean
  hireDate: string
}

export interface EmployeeDetail {
  employeeId: number
  employeeCode: string
  fullName: string
  nic: string | null
  dateOfBirth: string | null
  gender: Gender | null
  nationality: string | null
  profilePhotoPath: string | null
  email: string | null
  personalMobile: string | null
  addressLine1: string | null
  addressLine2: string | null
  city: string | null
  postalCode: string | null
  country: string | null
  emergencyContactName: string | null
  emergencyContactRelationship: string | null
  emergencyContactPhone: string | null
  hireDate: string
  confirmationDate: string | null
  lastWorkingDate: string | null
  departmentId: number
  designationId: number
  employmentTypeId: number
  branchId: number | null
  workShiftId: number
  reportingManagerId: number | null
  epfNumber: string | null
  etfNumber: string | null
  taxIdentificationNumber: string | null
  userId: number | null
  status: EmployeeStatus
  createdAt: string
  updatedAt: string | null
}

export interface CreateEmployeeRequest {
  employeeCode: string
  fullName: string
  nic?: string | null
  dateOfBirth?: string | null
  gender?: Gender | null
  nationality?: string | null
  email?: string | null
  personalMobile?: string | null
  addressLine1?: string | null
  addressLine2?: string | null
  city?: string | null
  postalCode?: string | null
  country?: string | null
  emergencyContactName?: string | null
  emergencyContactRelationship?: string | null
  emergencyContactPhone?: string | null
  hireDate: string
  departmentId: number
  designationId: number
  employmentTypeId: number
  branchId?: number | null
  workShiftId: number
  reportingManagerId?: number | null
  epfNumber?: string | null
  etfNumber?: string | null
  taxIdentificationNumber?: string | null
  linkUserId?: number | null
}

export type UpdateEmployeeRequest = Omit<CreateEmployeeRequest, "employeeCode" | "linkUserId"> & {
  confirmationDate?: string | null
  lastWorkingDate?: string | null
}

export interface EmployeeBankDetail {
  employeeBankDetailId: number | null
  bankName: string
  branchName: string
  accountNumber: string
  accountHolderName: string
  swiftCode: string | null
  isPrimary: boolean
  status: EntityStatus
}

export interface EmployeeMatch {
  employeeId: number
  employeeCode: string
  fullName: string
  email: string
}

export interface UserMatch {
  userId: number
  username: string
  displayName: string
  email: string
}

// --- Documents ---

export type EmployeeDocumentStatus = "Active" | "Archived"

export interface EmployeeDocument {
  employeeDocumentId: number
  employeeId: number
  hrDocumentTypeId: number
  hrDocumentTypeName: string | null
  originalFileName: string
  contentType: string
  sizeBytes: number
  issueDate: string | null
  expiryDate: string | null
  notes: string | null
  uploadedBy: number
  uploadedAt: string
  status: EmployeeDocumentStatus
}

// --- Attendance ---

export type AttendanceSourceType = "Excel" | "Csv" | "Manual" | "BiometricDevice"
export type AttendanceBatchStatus = "Draft" | "Validated" | "Confirmed" | "UsedInPayroll"
export type AttendanceStatusValue = "Present" | "Absent" | "HalfDay" | "OnLeave" | "Holiday" | "WeekOff"
export type RowValidationStatus = "Valid" | "DuplicateWithinBatch" | "DuplicateConfirmed" | "EmployeeNotFound" | "InvalidDateTime" | "Error"

export interface AttendanceUploadBatch {
  attendanceUploadBatchId: number
  docNo: string
  periodStart: string
  periodEnd: string
  sourceType: AttendanceSourceType
  originalFileName: string | null
  uploadedBy: number
  uploadedAt: string
  status: AttendanceBatchStatus
  confirmedBy: number | null
  confirmedAt: string | null
  rowCountTotal: number
  rowCountDuplicate: number
  rowCountError: number
}

export interface AttendanceRecord {
  attendanceRecordId: number
  attendanceUploadBatchId: number | null
  employeeId: number
  employeeCode: string | null
  employeeName: string | null
  attendanceDate: string
  checkIn: string | null
  checkOut: string | null
  workingMinutes: number
  lateMinutes: number
  earlyLeaveMinutes: number
  overtimeMinutes: number
  attendanceStatus: AttendanceStatusValue
  rowValidationStatus: RowValidationStatus
  duplicateOfAttendanceRecordId: number | null
  notes: string | null
}

// --- Leave ---

export interface LeaveType {
  leaveTypeId: number
  code: string
  name: string
  isPaid: boolean
  countsAsNoPay: boolean
  accrualPerYear: number
  carryForwardAllowed: boolean
  maxCarryForwardDays: number | null
  requiresApproval: boolean
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export type LeaveRequestStatus = "Draft" | "Submitted" | "Approved" | "Rejected" | "Cancelled"

export interface LeaveRequest {
  leaveRequestId: number
  docNo: string
  employeeId: number
  employeeName: string | null
  leaveTypeId: number
  leaveTypeName: string | null
  startDate: string
  endDate: string
  daysCount: number
  reason: string | null
  status: LeaveRequestStatus
  approvedBy: number | null
  approvedAt: string | null
  rejectionReason: string | null
  createdAt: string
}

export interface LeaveBalance {
  leaveBalanceId: number
  employeeId: number
  leaveTypeId: number
  leaveTypeName: string | null
  year: number
  entitledDays: number
  takenDays: number
  carriedForwardDays: number
  adjustmentDays: number
  remainingDays: number
}

// --- Payroll ---

export type SalaryComponentType = "Earning" | "Deduction"

export interface SalaryComponent {
  salaryComponentId: number
  code: string
  name: string
  componentType: SalaryComponentType
  isTaxable: boolean
  isEpfEtfApplicable: boolean
  status: EntityStatus
  createdAt: string
  updatedAt: string | null
}

export interface EmployeeSalaryStructureLine {
  salaryComponentId: number
  salaryComponentName: string | null
  amount: number
}

export type SalaryStructureStatus = "Active" | "Superseded"

export interface EmployeeSalaryStructure {
  employeeSalaryStructureId: number
  employeeId: number
  effectiveFrom: string
  effectiveTo: string | null
  basicSalary: number
  currency: string
  status: SalaryStructureStatus
  lines: EmployeeSalaryStructureLine[]
  createdAt: string
}

export type LoanKind = "Loan" | "Advance"
export type LoanStatus = "Active" | "Closed" | "Cancelled"
export type LoanInstallmentStatus = "Pending" | "Deducted" | "Skipped"

export interface LoanInstallment {
  loanInstallmentId: number
  installmentNumber: number
  dueYear: number
  dueMonth: number
  scheduledAmount: number
  paidAmount: number | null
  payrollRunId: number | null
  status: LoanInstallmentStatus
}

export interface EmployeeLoan {
  employeeLoanId: number
  docNo: string
  employeeId: number
  loanKind: LoanKind
  principalAmount: number
  interestRate: number
  installmentAmount: number
  numberOfInstallments: number
  startYear: number
  startMonth: number
  outstandingBalance: number
  status: LoanStatus
  installments: LoanInstallment[]
  createdAt: string
}

export interface PayrollStatutorySetting {
  payrollStatutorySettingId: number
  epfEmployeeRate: number
  epfEmployerRate: number
  etfEmployerRate: number
  otMultiplierDefault: number
  effectiveFrom: string
  effectiveTo: string | null
}

export interface TaxSlab {
  taxSlabId: number
  effectiveFrom: string
  effectiveTo: string | null
  lowerBound: number
  upperBound: number | null
  rate: number
}

export type PayrollRunStatus = "Draft" | "Approved" | "Locked"
export type PayrollLineComponentCategory = "Earning" | "Deduction" | "EmployerContribution"

export interface PayrollLineComponent {
  componentCategory: PayrollLineComponentCategory
  salaryComponentId: number | null
  label: string
  amount: number
  sortOrder: number
}

export interface PayrollLine {
  payrollLineId: number
  payrollRunId: number
  employeeId: number
  employeeCode: string | null
  employeeName: string | null
  basicSalary: number
  totalAllowances: number
  overtimeAmount: number
  grossSalary: number
  lateDeductionAmount: number
  noPayAmount: number
  loanDeductionAmount: number
  epfEmployeeAmount: number
  epfEmployerAmount: number
  etfEmployerAmount: number
  taxAmount: number
  otherDeductionsAmount: number
  netSalary: number
  workingDays: number
  presentDays: number
  absentDays: number
  leaveDays: number
  otMinutesTotal: number
  lateMinutesTotal: number
}

export interface PayrollLineDetail {
  line: PayrollLine
  components: PayrollLineComponent[]
}

export interface PayrollRun {
  payrollRunId: number
  docNo: string
  periodYear: number
  periodMonth: number
  branchId: number | null
  status: PayrollRunStatus
  generatedBy: number
  generatedAt: string
  approvedBy: number | null
  approvedAt: string | null
  lockedBy: number | null
  lockedAt: string | null
  unlockedBy: number | null
  unlockedAt: string | null
  unlockReason: string | null
  totalGross: number
  totalNet: number
  employeeCount: number
}

export interface Payslip {
  payslipId: number
  payrollLineId: number
  generatedAt: string
  releasedAt: string | null
  releasedBy: number | null
}

// --- Reports ---

export interface AttendanceSummaryRow {
  employeeId: number
  employeeCode: string
  employeeName: string
  departmentName: string | null
  presentDays: number
  absentDays: number
  leaveDays: number
  halfDays: number
  otMinutesTotal: number
  lateMinutesTotal: number
}

export interface OvertimeReportRow {
  employeeId: number
  employeeCode: string
  employeeName: string
  attendanceDate: string
  overtimeMinutes: number
}

export interface LateArrivalReportRow {
  employeeId: number
  employeeCode: string
  employeeName: string
  attendanceDate: string
  lateMinutes: number
}

export interface PayrollRegisterRow {
  payrollLineId: number
  employeeId: number
  employeeCode: string
  employeeName: string
  grossSalary: number
  totalDeductions: number
  netSalary: number
}

export interface SalaryHistoryRow {
  employeeSalaryStructureId: number
  effectiveFrom: string
  effectiveTo: string | null
  basicSalary: number
  status: string
}

export interface LeaveBalanceReportRow {
  employeeId: number
  employeeCode: string
  employeeName: string
  leaveTypeName: string
  entitledDays: number
  takenDays: number
  remainingDays: number
}

export interface DocumentExpiryReportRow {
  employeeDocumentId: number
  employeeId: number
  employeeCode: string
  employeeName: string
  documentTypeName: string
  expiryDate: string
  daysUntilExpiry: number
}
