import { api } from '../api'

export interface PortalProfile {
  employee: {
    id: string
    uniqueEmployeeId: string
    firstName: string
    lastName: string
    firstNameAr?: string | null
    lastNameAr?: string | null
    email: string
    department?: { name: string; nameAr?: string | null }
    position?: { title: string; titleAr?: string | null }
  }
  stats: {
    activeLoansCount: number
    pendingLeavesCount: number
    pendingPurchaseRequestsCount: number
    pendingExpenseClaimsCount: number
    leaveBalance: Array<{
      leaveType: string
      totalDays: number
      carriedOver: number
      usedDays: number
      available: number
    }>
  }
}

export interface Loan {
  id: string
  loanNumber: string
  type: string
  amount: number
  currency: string
  installments: number
  monthlyAmount?: number
  reason?: string | null
  status: string
  approvedBy?: string | null
  approvedAt?: string | null
  rejectedReason?: string | null
  startDate?: string | null
  endDate?: string | null
  createdAt: string
  installmentsList?: Array<{
    id: string
    installmentNumber: number
    dueDate: string
    amount: number
    paidDate?: string | null
    status: string
  }>
}

export interface Leave {
  id: string
  leaveType: string
  startDate: string
  endDate: string
  days: number
  reason?: string | null
  status: string
  approvedBy?: string | null
  approvedAt?: string | null
  rejectedReason?: string | null
  createdAt: string
}

export interface PortalOvertimeRequest {
  id: string
  attendanceId: string
  date: string
  hours: number
  reason: string
  status: string
  rejectedReason?: string
  createdAt: string
  employee?: {
    id: string
    firstName: string
    lastName: string
    uniqueEmployeeId: string
    reportingToId?: string
  }
}

export interface PurchaseRequest {
  id: string
  requestNumber: string
  items: any[]
  totalAmount?: number | null
  reason?: string | null
  priority: string
  status: string
  approvedBy?: string | null
  approvedAt?: string | null
  rejectedReason?: string | null
  createdAt: string
}

export interface ExpenseClaim {
  id: string;
  employeeId: string;
  claimNumber: string;

  items?: ExpenseClaimItem[] | null;
  totalAmount?: number | null;

  expenseDate: string | null;
  amount: number | null;
  description: string | null;
  projectOrTender: string | null;

  status: 'PENDING' | 'APPROVED' | 'REJECTED' | string;
  approvedBy?: string | null;
  approvedAt?: string | null;
  rejectedReason?: string | null;
  approvalNote?: string | null;
  isPaid?: boolean;
  createdAt: string;
  updatedAt: string;
  attachments?: Array<{
  id: string;
  fileName: string;
  originalName: string;
  mimeType: string;
  size: number;
  uploadedAt: string;
}> | null;
  employee?: {
    id: string;
    firstName: string;
    lastName: string;
    uniqueEmployeeId?: string | null;
    reportingToId?: string | null;
  };
}

export interface ExpenseClaimItem {
  expenseDate: string;
  amount: number;
  entityName?: string;
  description: string;
  projectOrTender?: string;
  proofRef?: string;
}

export interface Attendance {
  id: string
  date: string
  checkIn?: string | null
  checkOut?: string | null
  workHours?: number | null
  overtimeHours?: number | null
  status: string
}

export interface ManagedLeave {
  id: string
  leaveType: string
  startDate: string
  endDate: string
  days: number
  status: string
  reason?: string
  rejectedReason?: string
  employee: {
    id: string
    firstName: string
    lastName: string
    uniqueEmployeeId: string
    reportingToId?: string
  }
}

export interface Salary {
  id: string
  month: number
  year: number
  basicSalary: number
  allowances: number
  deductions: number
  commissions: number
  overtimePay: number
  netSalary: number
  status: string
  paidDate?: string | null
  createdAt: string
}

export const portalAPI = {

  viewExpenseClaimAttachment: async (attachmentId: string): Promise<Blob> => {
    const response = await api.get(
      `/hr/portal/expense-claims/attachments/${attachmentId}/view`,
      {
        responseType: 'blob',
      }
    );

    return response.data;
  },

  getManagedLeaves: async (status?: string): Promise<ManagedLeave[]> => {
    const q = new URLSearchParams()
    if (status && status !== 'all') q.append('status', status)
    const response = await api.get(`/hr/portal/managed-leaves?${q.toString()}`)
    return response.data.data || []
  },

  approveManagedLeave: async (id: string) => {
    const response = await api.post(`/hr/portal/managed-leaves/${id}/approve`)
    return response.data.data
  },

  rejectManagedLeave: async (id: string, rejectedReason: string) => {
    const response = await api.post(`/hr/portal/managed-leaves/${id}/reject`, { rejectedReason })
    return response.data.data
  },

  getMe: async (): Promise<PortalProfile> => {
    const response = await api.get('/hr/portal/me')
    return response.data.data
  },

  getLoans: async (): Promise<Loan[]> => {
    const response = await api.get('/hr/portal/loans')
    return response.data.data || []
  },

  submitLoanRequest: async (data: { type: string; amount: number; installments?: number; reason?: string }): Promise<Loan> => {
    const response = await api.post('/hr/portal/loans', data)
    return response.data.data
  },

  updateLoanRequest: async (
    id: string,
    data: { type?: string; amount?: number; installments?: number; reason?: string }
  ): Promise<Loan> => {
    const response = await api.put(`/hr/portal/loans/${id}`, data)
    return response.data.data
  },

  deleteLoanRequest: async (id: string): Promise<void> => {
    await api.delete(`/hr/portal/loans/${id}`)
  },

    getOvertimeRequests: async (): Promise<PortalOvertimeRequest[]> => {
    const response = await api.get('/hr/portal/overtime-requests')
    return response.data.data || []
  },

  submitOvertimeRequest: async (data: {
    date: string
    hours: number
    reason: string
  }): Promise<PortalOvertimeRequest> => {
    const response = await api.post('/hr/portal/overtime-requests', data)
    return response.data.data
  },

  updateOvertimeRequest: async (
    attendanceId: string,
    data: { hours?: number; reason?: string }
  ): Promise<PortalOvertimeRequest> => {
    const response = await api.put(`/hr/portal/overtime-requests/${attendanceId}`, data)
    return response.data.data
  },

  deleteOvertimeRequest: async (attendanceId: string): Promise<void> => {
    await api.delete(`/hr/portal/overtime-requests/${attendanceId}`)
  },

  getManagedOvertimeRequests: async (): Promise<PortalOvertimeRequest[]> => {
    const response = await api.get('/hr/portal/managed-overtime-requests')
    return response.data.data || []
  },

  approveManagedOvertimeRequest: async (attendanceId: string): Promise<PortalOvertimeRequest> => {
    const response = await api.post(`/hr/portal/managed-overtime-requests/${attendanceId}/approve`)
    return response.data.data
  },

  rejectManagedOvertimeRequest: async (
    attendanceId: string,
    rejectedReason: string
  ): Promise<PortalOvertimeRequest> => {
    const response = await api.post(`/hr/portal/managed-overtime-requests/${attendanceId}/reject`, {
      rejectedReason,
    })
    return response.data.data
  },

  getLeaveBalance: async (year?: number): Promise<PortalProfile['stats']['leaveBalance']> => {
    const params = year ? `?year=${year}` : ''
    const response = await api.get(`/hr/portal/leave-balance${params}`)
    return response.data.data || []
  },

  getLeaves: async (): Promise<Leave[]> => {
    const response = await api.get('/hr/portal/leaves')
    return response.data.data || []
  },

  submitLeaveRequest: async (data: {
    leaveType: string
    startDate: string
    endDate: string
    leaveDate?: string
    startTime?: string
    endTime?: string
    reason?: string
  }): Promise<Leave> => {
      const response = await api.post('/hr/portal/leaves', data)
    return response.data.data
  },

  updateLeaveRequest: async (
    id: string,
    data: {
      leaveType?: string
      startDate?: string
      endDate?: string
      leaveDate?: string
      startTime?: string
      endTime?: string
      reason?: string
    }
  ): Promise<Leave> => {
    const response = await api.put(`/hr/portal/leaves/${id}`, data)
    return response.data.data
  },

  deleteLeaveRequest: async (id: string): Promise<void> => {
    await api.delete(`/hr/portal/leaves/${id}`)
  },

  getPurchaseRequests: async (): Promise<PurchaseRequest[]> => {
    const response = await api.get('/hr/portal/purchase-requests')
    return response.data.data || []
  },

  submitPurchaseRequest: async (data: { items: Array<{ description: string; quantity?: number; estimatedPrice?: number }>; reason?: string; priority?: string }): Promise<PurchaseRequest> => {
    const response = await api.post('/hr/portal/purchase-requests', data)
    return response.data.data
  },

  updatePurchaseRequest: async (
    id: string,
    data: {
      items?: Array<{ description: string; quantity?: number; estimatedPrice?: number }>
      reason?: string
      priority?: string
    }
  ): Promise<PurchaseRequest> => {
    const response = await api.put(`/hr/portal/purchase-requests/${id}`, data)
    return response.data.data
  },

  deletePurchaseRequest: async (id: string): Promise<void> => {
    await api.delete(`/hr/portal/purchase-requests/${id}`)
  },

    getExpenseClaims: async (): Promise<ExpenseClaim[]> => {
    const response = await api.get('/hr/portal/expense-claims')
    return response.data.data || []
  },

 submitExpenseClaim: async (data: {
  items: Array<{
    expenseDate: string;
    amount: number;
    entityName?: string;
    description: string;
    projectOrTender?: string;
    proofRef?: string;
  }>;
  description?: string;
  attachments?: File[];
}): Promise<ExpenseClaim> => {
  const formData = new FormData();

  formData.append('items', JSON.stringify(data.items));

  if (data.description) {
    formData.append('description', data.description);
  }

  if (data.attachments && data.attachments.length > 0) {
    for (const file of data.attachments) {
      formData.append('attachments', file);
    }
  }

  const response = await api.post('/hr/portal/expense-claims', formData, {
    headers: { 'Content-Type': undefined as any },
  });

  return response.data.data;
},

  updateExpenseClaim: async (
    id: string,
    data: {
      items: Array<{
        expenseDate: string;
        amount: number;
        entityName?: string;
        description: string;
        projectOrTender?: string;
        proofRef?: string;
      }>;
      description?: string;
      attachments?: File[];
      removeAttachmentIds?: string[];
    }
  ): Promise<ExpenseClaim> => {
    const formData = new FormData();
    formData.append('items', JSON.stringify(data.items));
    if (data.description) formData.append('description', data.description);
    if (data.removeAttachmentIds && data.removeAttachmentIds.length > 0) {
      formData.append('removeAttachmentIds', JSON.stringify(data.removeAttachmentIds));
    }
    if (data.attachments && data.attachments.length > 0) {
      for (const file of data.attachments) formData.append('attachments', file);
    }
    const response = await api.put(`/hr/portal/expense-claims/${id}`, formData, {
      headers: { 'Content-Type': undefined as any },
    });
    return response.data.data;
  },

  deleteExpenseClaim: async (id: string): Promise<void> => {
    await api.delete(`/hr/portal/expense-claims/${id}`);
  },

  getManagedExpenseClaims: async (
    status?: string,
    search?: string,
    paid?: 'all' | 'paid' | 'unpaid',
  ): Promise<ExpenseClaim[]> => {
    const q = new URLSearchParams()
    if (status && status !== 'all') q.append('status', status)
    if (search && search.trim()) q.append('search', search.trim())
    if (paid && paid !== 'all') q.append('paid', paid)
    const response = await api.get(`/hr/portal/managed-expense-claims?${q.toString()}`)
    return response.data.data || []
  },

  approveManagedExpenseClaim: async (id: string, approvalNote?: string): Promise<ExpenseClaim> => {
    const response = await api.post(
      `/hr/portal/managed-expense-claims/${id}/approve`,
      approvalNote?.trim() ? { approvalNote: approvalNote.trim() } : {},
    );
    return response.data.data;
  },

  rejectManagedExpenseClaim: async (id: string, rejectedReason: string): Promise<ExpenseClaim> => {
    const response = await api.post(`/hr/portal/managed-expense-claims/${id}/reject`, { rejectedReason })
    return response.data.data
  },

  markExpenseClaimPaid: async (id: string, isPaid: boolean): Promise<ExpenseClaim> => {
    const response = await api.patch(`/hr/portal/managed-expense-claims/${id}/paid`, { isPaid })
    return response.data.data
  },

  getAttendance: async (month?: number, year?: number): Promise<Attendance[]> => {
    const params = new URLSearchParams()
    if (month) params.append('month', String(month))
    if (year) params.append('year', String(year))
    const query = params.toString() ? `?${params.toString()}` : ''
    const response = await api.get(`/hr/portal/attendance${query}`)
    return response.data.data || []
  },

  getSalaries: async (): Promise<Salary[]> => {
    const response = await api.get('/hr/portal/salaries')
    return response.data.data || []
  },
}
