import ApiService from "./ApiService";

// Employee interfaces
export interface Employee {
  id: string;
  department: Department;
  subDepartment: SubDepartment;
  sub_department_id: number;
  role: Role;
  first_name: string;
  last_name: string;
  email: string;
  contact_no: string;
  joining_date: string;
  status: boolean;
  gross_salary: number;
  salary_settings: SalarySetting[];
  created_at?: string;
  updated_at?: string;
  team_lead_id?: string | null;
  team_lead?: {
    id: string;
    first_name: string;
    last_name: string;
    email: string;
  } | null;
  // Employment fields
  employee_number?: string | null;
  work_location?: string | null;
  probation_period?: number | null;
  notice_period?: number | null;
  employee_type?: string;
  // Additional fields for display
  department_name?: string;
  role_name?: string;
  full_name?: string;
  resume_url?: string | null;
  // Employee Information (nested object from API)
  employeeInformation?: {
    id?: number;
    employee_id?: number;
    address?: string;
    gender?: string;
    alternate_mobile_number?: string;
    date_of_birth?: string;
    marital_status?: string;
    parents_name?: string;
    parents_contact_number?: string;
    blood_group?: string;
    native_place?: string;
    aadhar_card?: string;
    pan_card_number?: string;
    education_qualification?: string;
    total_work_experience_years?: string | number;
    resume_url?: string | null;
    // Personal
    personal_email?: string | null;
    emergency_contact_name?: string | null;
    emergency_contact_relationship?: string | null;
    emergency_contact_number?: string | null;
    // Address
    permanent_address?: string | null;
    state?: string | null;
    city?: string | null;
    pincode?: string | null;
    // Experience
    previous_company_name?: string | null;
    previous_designation?: string | null;
    last_salary?: number | null;
    // Bank
    bank_name?: string | null;
    account_number?: string | null;
    ifsc_code?: string | null;
    account_holder_name?: string | null;
    // Identity
    uan?: string | null;
    // Documents
    offer_letter?: string | null;
    appointment_letter?: string | null;
    id_proof?: string | null;
    address_proof?: string | null;
    education_certificates?: string | null;
    created_at?: string;
    updated_at?: string;
  };
  technologyAssignments: {
    id: number;
    technology: {
      id: number;
      name: string;
    };
  }[];
}

export interface SalarySetting {
  salary_setting_id: number;
  individual_value: string;
  code?: string;
}

export interface EmployeeFilters {
  search?: string;
  company_id?: number;
  department_id?: number;
  role_id?: number;
  status?: number;
  team_lead_id?: string;
  column_name?: string;
  order?: "ASC" | "DESC";
  page?: number;
  limit?: number;
}

export interface CreateEmployeeData {
  department_id: number;
  role_id: number;
  first_name: string;
  last_name: string;
  email: string;
  contact_no: string;
  joining_date: string;
  status: number;
  gross_salary: number;
  salary_settings: SalarySetting[];
  team_lead_id?: string | null;
  // New fields
  address: string;
  gender: string;
  alternate_mobile_number: string;
  date_of_birth?: string;
  marital_status?: string;
  parents_name?: string;
  parents_contact_number?: string;
  blood_group?: string;
  native_place?: string;
  aadhar_card?: string;
  pan_card_number?: string;
  education_qualification?: string;
  total_work_experience_years?: number;
  resume?: File | string;
}

export interface UpdateEmployeeData {
  id: string;
  department_id: number;
  role_id: number;
  first_name: string;
  last_name: string;
  email: string;
  contact_no: string;
  joining_date: string;
  status: number;
  gross_salary: number;
  salary_settings: SalarySetting[];
  team_lead_id?: string | null;
  // New fields
  address: string;
  gender: string;
  alternate_mobile_number: string;
  date_of_birth?: string;
  marital_status?: string;
  parents_name?: string;
  parents_contact_number?: string;
  blood_group?: string;
  native_place?: string;
  aadhar_card?: string;
  pan_card_number?: string;
  education_qualification?: string;
  total_work_experience_years?: number;
  resume?: File | string;
}

export interface EmployeeListResponse {
  success: boolean;
  message?: string;
  data: {
    data: Employee[];
    count: number;
  };
}

export interface EmployeeResponse {
  success: boolean;
  message?: string;
  data: Employee;
}

// Department interface for dropdown
export interface Department {
  id: number;
  name: string;
  status: boolean;
  subDepartment?: any;
}
export interface SubDepartment {
  id: number;
  name: string;
}

// Role interface for dropdown
export interface Role {
  id: number;
  name: string;
  status: boolean;
}

// Salary Setting interface for dropdown
export interface SalarySettingOption {
  id: number;
  code: string;
  name: string;
  type: string;
  type_value: string;
  value: string;
  status: boolean;
  is_taxable?: number;
}

export interface DepartmentListResponse {
  success: boolean;
  message?: string;
  data: {
    data: Department[];
    count: number;
  };
}

export interface RoleListResponse {
  success: boolean;
  message?: string;
  data: {
    data: Role[];
    count: number;
  };
}

export interface SalarySettingListResponse {
  success: boolean;
  message?: string;
  data: {
    data: SalarySettingOption[];
    count: number;
  };
}

// Create Employee
export async function createEmployee(data: CreateEmployeeData | FormData) {
  return ApiService.request<EmployeeResponse>({
    url: "/employees",
    method: "post",
    data,
  });
}

// Get Employees with filters
export async function getEmployees(filters?: EmployeeFilters) {
  const params: any = {
    search: filters?.search || "",
    page: filters?.page || 1,
    limit: filters?.limit || 10,
  };

  // Only add filters if they're defined
  if (filters?.company_id !== undefined) {
    params.company_id = filters.company_id;
  }
  if (filters?.department_id !== undefined) {
    params.department_id = filters.department_id;
  }
  if (filters?.role_id !== undefined) {
    params.role_id = filters.role_id;
  }
  if (filters?.status !== undefined) {
    params.status = filters.status;
  }
  if (filters?.team_lead_id !== undefined) {
    params.team_lead_id = filters.team_lead_id;
  }

  if (filters?.column_name) {
    params.column_name = filters.column_name;
  }

  if (filters?.order) {
    params.order = filters.order;
  }

  return ApiService.request<EmployeeListResponse>({
    url: "/employees",
    method: "get",
    params,
  });
}

// Get Employee by ID
export async function getEmployeeById(id: string) {
  return ApiService.request<EmployeeResponse>({
    url: `/employees/${id}`,
    method: "get",
  });
}

// Update Employee
export async function updateEmployee(data: UpdateEmployeeData | FormData) {
  // Handle FormData
  if (data instanceof FormData) {
    // Extract id from FormData
    const id = data.get("id") as string;
    if (!id) {
      throw new Error("Employee ID is required for update");
    }
    return ApiService.request<EmployeeResponse>({
      url: `/employees/${id}`,
      method: "put",
      data,
    });
  }

  // Handle regular object
  const { id, ...updateData } = data;
  return ApiService.request<EmployeeResponse>({
    url: `/employees/${id}`,
    method: "put",
    data: updateData,
  });
}

export interface DeleteEmployeeResponse {
  success: boolean;
  message?: string;
}

// Delete Employee
export async function deleteEmployee(id: string) {
  return ApiService.request<DeleteEmployeeResponse>({
    url: `/employees/${id}`,
    method: "delete",
  });
}

// Toggle Employee Status
export async function toggleEmployeeStatus(id: string) {
  return ApiService.request<EmployeeResponse>({
    url: `/employees/active-inactive/${id}`,
    method: "patch",
  });
}

// Get Departments for dropdown
export async function getDepartmentsForDropdown() {
  return ApiService.request<DepartmentListResponse>({
    url: "/departments",
    method: "get",
    params: {
      status: 1, // Only active departments
      limit: 1000, // Get all departments
    },
  });
}

// Get Roles for dropdown
export async function getRolesForDropdown(remove_admin?: string) {
  return ApiService.request<RoleListResponse>({
    url: "/roles",
    method: "get",
    params: {
      status: 1, // Only active roles
      limit: 1000, // Get all roles
      remove_admin: remove_admin,
    },
  });
}

// Get Salary Settings for dropdown
export async function getSalarySettingsForDropdown() {
  return ApiService.request<SalarySettingListResponse>({
    url: "/salary-settings",
    method: "get",
    params: {
      status: 1, // Only active salary settings
      limit: 1000, // Get all salary settings
    },
  });
}

// Get Employees for dropdown
export async function getEmployeesForDropdown() {
  return ApiService.request<EmployeeListResponse>({
    url: "/employees",
    method: "get",
    params: {
      status: 1, // Only active employees
      limit: 1000, // Get all employees
    },
  });
}

// Bulk Upload interfaces
export interface BulkUploadError {
  row_number: number;
  employee_name: string;
  email: string;
  error_message: string;
}

export interface BulkUploadResponse {
  total_records: number;
  success_count: number;
  failure_count: number;
  errors: BulkUploadError[];
  error_file?: string | Blob;
  error_file_base64?: string;
  error_file_name?: string;
}

export interface BulkUploadApiResponse {
  success: boolean;
  message?: string;
  data: BulkUploadResponse;
}

// Bulk Upload Employees
export async function bulkUploadEmployees(file: File) {
  try {
    const formData = new FormData();
    formData.append("file", file);

    const response = await ApiService.request<BulkUploadApiResponse>({
      url: "/employees/bulk-upload",
      method: "post",
      data: formData,
      headers: {
        "Content-Type": "multipart/form-data",
      },
    });

    // Handle error file download if present in response
    if (
      response.data?.data?.error_file_base64 &&
      response.data?.data?.error_file_name
    ) {
      // Convert base64 to blob
      try {
        const base64Data = response.data.data.error_file_base64;
        const byteCharacters = atob(base64Data);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        const blob = new Blob([byteArray], {
          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        });

        // Store the blob and filename for download
        response.data.data.error_file = blob;
        response.data.data.error_file_name = response.data.data.error_file_name;
      } catch (error) {
        console.warn("Failed to convert base64 error file:", error);
      }
    } else if (response.data?.data?.error_file) {
      // If error_file is a string (URL), fetch it as blob
      if (typeof response.data.data.error_file === "string") {
        try {
          const errorFileResponse = await fetch(response.data.data.error_file);
          if (errorFileResponse.ok) {
            response.data.data.error_file = await errorFileResponse.blob();
          }
        } catch (error) {
          console.warn("Failed to fetch error file:", error);
        }
      }
    }

    return {
      success: response.data?.success !== false,
      data: response.data?.data,
      message: response.data?.message || "Upload completed",
    };
  } catch (error: any) {
    // Handle different error scenarios
    if (error?.response?.status === 413) {
      return {
        success: false,
        data: null,
        message:
          "File size too large. Please reduce the file size and try again.",
      };
    }

    if (error?.response?.status === 415) {
      return {
        success: false,
        data: null,
        message:
          "Unsupported file format. Please upload a valid Excel file (.xlsx or .xls).",
      };
    }

    // Check if error response contains bulk upload result
    if (error?.response?.data?.data) {
      return {
        success: false,
        data: error.response.data.data,
        message: error.response.data.message || "Upload completed with errors",
      };
    }

    return {
      success: false,
      data: null,
      message:
        error?.response?.data?.message || error?.message || "Upload failed",
    };
  }
}

// Employee Leave Balance interfaces
export interface LeaveBalance {
  id: number;
  name: string;
  code: string;
  annual_allowed_days: number;
  is_paid: number;
  carry_forward: number;
  total_allocated: number;
  used_days: number;
  available_days: number;
  year: number;
}

export interface LeaveBalanceResponse {
  success: boolean;
  data: LeaveBalance[];
}

// Employee Salary History interfaces
export interface SalaryHistory {
  id: number;
  employee_id: number;
  company_id: number;
  from_date: Date;
  to_date: Date;
  gross_salary: number;
  basic_salary: number;
  total_earnings: number;
  total_deductions: number;
  net_payable_salary: number;
  basic_salary_percentage: string;
  notes: string;
  tds_amount: number;
  user: {
    first_name: string;
    last_name: string;
  };
}

export interface SalaryHistoryResponse {
  success: boolean;
  data: SalaryHistory[];
}

// Get Employee Leave Balances
export async function getEmployeeLeaveBalances(employeeId?: string) {
  const url = employeeId
    ? `/employees/my-leave-balances?employee_id=${employeeId}`
    : "/employees/my-leave-balances";

  return ApiService.request<LeaveBalanceResponse>({
    url,
    method: "get",
  });
}

// Get Employee Salary History
export async function getEmployeeSalaryHistory(id: string) {
  return ApiService.request<SalaryHistoryResponse>({
    url: `/employees/salary-history/${id}`,
    method: "get",
  });
}

// Update Employee Salary History
export interface UpdateSalaryHistoryData {
  gross_salary: number;
  notes?: string;
  from_date: string; // YYYY-MM-DD format
}

export async function updateEmployeeSalaryHistory(
  id: number,
  data: UpdateSalaryHistoryData,
) {
  return ApiService.request<{ success: boolean; message: string }>({
    url: `/employees/salary-history/${id}`,
    method: "put",
    data,
  });
}

// Employee Project interfaces
export interface EmployeeProject {
  id: number;
  employee_id: number;
  project_id: number;
  assigned_by: number;
  assigned_at: string;
  created_by: number;
  updated_by: number | null;
  created_at: string;
  updated_at: string;
  deleted_at: string | null;
  project: {
    id: number;
    name?: string;
    project_name?: string;
    project_code?: string;
    code?: string;
    status: "Planning" | "In Progress" | "On Hold" | "Completed" | string;
  };
}

export interface EmployeeProjectResponse {
  success: boolean;
  message: string;
  data: EmployeeProject[];
}

export interface AssignProjectsData {
  project_ids: number[];
}

export interface AssignProjectsResponse {
  success: boolean;
  message: string;
  data: any;
}

export interface UnassignProjectResponse {
  success: boolean;
  message: string;
}

// Get Employee Projects
export async function getEmployeeProjects(employeeId: string) {
  return ApiService.request<EmployeeProjectResponse>({
    url: `/employees/employee-projects/${employeeId}`,
    method: "get",
  });
}

// Assign Projects to Employee
export async function assignProjects(
  employeeId: string,
  data: AssignProjectsData,
) {
  return ApiService.request<AssignProjectsResponse>({
    url: `/employees/assign-projects/${employeeId}`,
    method: "post",
    data,
  });
}

// Unassign Project from Employee
export async function unassignProject(projectId: number, assignmentId: number) {
  return ApiService.request<UnassignProjectResponse>({
    url: `/projects/${projectId}/assigned-employees/${assignmentId}`,
    method: "delete",
  });
}

// Update Employee Leave Balances
export interface UpdateLeaveBalanceItem {
  leave_type_id: number;
  year: number;
  total_allocated: number;
}

export interface UpdateLeaveBalancesData {
  leave_balances: UpdateLeaveBalanceItem[];
}

export interface UpdateLeaveBalancesResponse {
  success: boolean;
  code: number;
  message: string;
  data: {
    updated_balances: Array<{
      employee_id: number;
      leave_type_id: number;
      year: number;
      old_total_allocated: number;
      new_total_allocated: number;
      new_available_days: number;
      action: string;
    }>;
    errors: Array<{
      employee_id: number;
      leave_type_id: number;
      year: number;
      error: string;
    }>;
    summary: {
      total_requested: number;
      successful_updates: number;
      failed_updates: number;
    };
  };
}

export async function updateEmployeeLeaveBalances(
  employeeId: string,
  data: UpdateLeaveBalancesData,
) {
  return ApiService.request<UpdateLeaveBalancesResponse>({
    url: `/employees/update-leave-balances?employee_id=${employeeId}`,
    method: "put",
    data,
  });
}
