import { create } from 'zustand';
import { api } from './api';

// =========================
// Types (legacy — kept verbatim for HRManagement.tsx consumers)
// =========================

export interface StaffRecord {
  id: number;
  uid: string;
  user_id: number;
  staff_number: string;
  first_name: string;
  last_name: string;
  email: string;
  role_id: number;
  role_name: string;
  salary_grade_id: number;
  grade_name: string;
  employment_type: string;
  appointment_date: string;
  department: string;
  designation: string;
  is_active: number;
}

export interface LeaveRequest {
  id: number;
  uid: string;
  staff_id: number;
  first_name?: string;
  last_name?: string;
  leave_type_id: number;
  leave_type: string;
  start_date: string;
  end_date: string;
  days_count: number;
  reason: string;
  status: 'pending' | 'approved' | 'rejected' | 'cancelled';
  rejection_reason?: string;
}

export interface PayrollRun {
  id: number;
  uid: string;
  period_month: number;
  period_year: number;
  description: string;
  status: 'draft' | 'calculated' | 'approved' | 'paid' | 'cancelled';
  total_gross: number;
  total_deductions: number;
  total_net: number;
}

/**
 * Payslip — union of legacy list shape (HRManagement.tsx) and the Phase 1
 * backend's `/hr/payslips/:id` detail shape. Optional fields are populated
 * based on which endpoint returned the row.
 */
export interface Payslip {
  id: number;
  uid?: string;
  staff_id: number;
  payroll_run_id?: number;
  first_name?: string;
  last_name?: string;
  email?: string;
  staff_number?: string | null;
  department?: string | null;
  designation?: string | null;
  period_month: number;
  period_year: number;
  basic_salary: number;
  housing_allowance: number;
  transport_allowance: number;
  medical_allowance: number;
  other_allowances: number;
  gross_salary: number;
  tax_deduction: number;
  pension_deduction: number;
  other_deductions: number;
  total_deductions: number;
  net_salary: number;
  status?: string;
  paid_at?: string | null;
  // Phase 1 backend detail endpoint extras
  run_id?: number;
  period?: string;
}

// =========================
// Phase 1 — new types (for HRDashboard / PayslipView)
// =========================

export interface HRDashboardSummary {
  headcount: number;
  open_leave_requests: number;
  last_payroll_run: {
    id: number;
    period: string; // e.g. "2026-06"
    status: 'draft' | 'calculated' | 'paid' | 'cancelled' | string;
  } | null;
  attendance_today_pct: number;
}

export interface PayslipFilters {
  payroll_run_id?: number;
}

// =========================
// Store
// =========================

interface HRStore {
  // -------- Legacy state --------
  records: StaffRecord[];
  leaveRequests: LeaveRequest[];
  payrollRuns: PayrollRun[];
  payslips: Payslip[];
  leaveTypes: any[];
  salaryGrades: any[];
  staffRoles: any[];
  departments: any[];
  vacancies: any[];
  applicants: any[];
  loading: boolean;

  // -------- Phase 1 additions --------
  dashboardSummary: HRDashboardSummary | null;
  currentPayslip: Payslip | null;
  error: string | null;

  // -------- Legacy actions --------
  fetchRecords: (silent?: boolean) => Promise<void>;
  fetchLeaveRequests: () => Promise<void>;
  fetchPayrollRuns: () => Promise<void>;
  fetchPayslips: (payrollRunId?: number) => Promise<void>;
  fetchMetadata: () => Promise<void>;
  fetchVacancies: () => Promise<void>;
  fetchApplicants: () => Promise<void>;

  createLeaveRequest: (data: any) => Promise<void>;
  updateLeaveStatus: (uid: string, status: string, reason?: string) => Promise<void>;
  createPayrollRun: (data: any) => Promise<void>;
  calculatePayroll: (id: number) => Promise<void>;
  payPayrollRun: (id: number) => Promise<void>;
  onboardStaff: (userData: any, staffData: any) => Promise<void>;
  createVacancy: (data: any) => Promise<void>;
  updateVacancy: (id: number, data: any) => Promise<void>;
  updateVacancyStatus: (id: number, status: string) => Promise<void>;
  deleteVacancy: (id: number) => Promise<void>;
  updateApplicantStatus: (id: number, status: string, details?: { interview_date?: string; notes?: string }) => Promise<void>;
  createApplicant: (data: any) => Promise<void>;
  cancelPayrollRun: (id: number) => Promise<void>;
  updateStaffRecord: (id: number, data: any) => Promise<void>;
  deleteStaffRecord: (id: number) => Promise<void>;

  // -------- Phase 1 actions --------
  fetchDashboardSummary: () => Promise<void>;
  /** Loads a single payslip detail from /hr/payslips/:id and stores it in `currentPayslip`. */
  fetchPayslip: (id: number) => Promise<Payslip | null>;
  resetPayslip: () => void;
}

export const useHRStore = create<HRStore>((set, get) => ({
  // -------- Legacy initial state --------
  records: [],
  leaveRequests: [],
  payrollRuns: [],
  payslips: [],
  leaveTypes: [],
  salaryGrades: [],
  staffRoles: [],
  departments: [],
  vacancies: [],
  applicants: [],
  loading: false,

  // -------- Phase 1 initial state --------
  dashboardSummary: null,
  currentPayslip: null,
  error: null,

  // ============ LEGACY ACTIONS ============

  fetchRecords: async (silent = false) => {
    if (!silent) set({ loading: true });
    try {
      const res = await api.get('/hr/records');
      set({ records: res.data, loading: false });
    } catch (err) {
      set({ loading: false });
    }
  },

  fetchLeaveRequests: async () => {
    try {
      const res = await api.get('/hr/leave-requests');
      set({ leaveRequests: res.data });
    } catch (err) {}
  },

  fetchPayrollRuns: async () => {
    try {
      const res = await api.get('/hr/payroll-runs');
      set({ payrollRuns: res.data });
    } catch (err) {}
  },

  fetchPayslips: async (payrollRunId) => {
    try {
      const res = await api.get('/hr/payslips', { params: { payroll_run_id: payrollRunId } });
      set({ payslips: res.data });
    } catch (err) {}
  },

  fetchMetadata: async () => {
    try {
      const [lt, sg, sr, dept] = await Promise.all([
        api.get('/hr/leave-types'),
        api.get('/hr/salary-grades'),
        api.get('/hr/roles'),
        api.get('/departments'),
      ]);
      set({
        leaveTypes: lt.data,
        salaryGrades: sg.data,
        staffRoles: sr.data,
        departments: dept.data,
      });
    } catch (err) {}
  },

  fetchVacancies: async () => {
    try {
      const res = await api.get('/hr/vacancies');
      set({ vacancies: res.data });
    } catch (err) {}
  },

  fetchApplicants: async () => {
    try {
      const res = await api.get('/hr/applicants');
      set({ applicants: res.data });
    } catch (err) {}
  },

  createLeaveRequest: async (data) => {
    await api.post('/hr/leave-requests', data);
    get().fetchLeaveRequests();
  },

  updateLeaveStatus: async (uid, status, reason) => {
    await api.put(`/hr/leave-requests/${uid}/status`, { status, rejection_reason: reason });
    get().fetchLeaveRequests();
  },

  createPayrollRun: async (data) => {
    await api.post('/hr/payroll-runs', data);
    get().fetchPayrollRuns();
  },

  calculatePayroll: async (id) => {
    set({ loading: true });
    await api.post(`/hr/payroll-runs/${id}/calculate`);
    get().fetchPayrollRuns();
    set({ loading: false });
  },

  payPayrollRun: async (id) => {
    set({ loading: true });
    await api.post(`/hr/payroll-runs/${id}/pay`);
    get().fetchPayrollRuns();
    set({ loading: false });
  },

  cancelPayrollRun: async (id) => {
    set({ loading: true });
    try {
      await api.post(`/hr/payroll-runs/${id}/cancel`);
      get().fetchPayrollRuns();
    } finally {
      set({ loading: false });
    }
  },

  onboardStaff: async (userData, staffData) => {
    set({ loading: true });
    try {
      const userRes = await api.post('/users', userData);
      const userId = userRes.data.id;
      await api.post('/hr/records', {
        ...staffData,
        user_id: userId,
      });
      await get().fetchRecords();
    } catch (err) {
      set({ loading: false });
      throw err;
    }
  },

  createVacancy: async (data) => {
    set({ loading: true });
    try {
      await api.post('/hr/vacancies', data);
      await get().fetchVacancies();
    } finally {
      set({ loading: false });
    }
  },

  updateVacancy: async (id, data) => {
    set({ loading: true });
    try {
      await api.put(`/hr/vacancies/${id}`, data);
      await get().fetchVacancies();
    } finally {
      set({ loading: false });
    }
  },

  updateVacancyStatus: async (id, status) => {
    await api.put(`/hr/vacancies/${id}/status`, { status });
    await get().fetchVacancies();
  },

  deleteVacancy: async (id) => {
    await api.delete(`/hr/vacancies/${id}`);
    await get().fetchVacancies();
  },

  updateApplicantStatus: async (id, status, details) => {
    await api.put(`/hr/applicants/${id}/status`, { status, ...details });
    await get().fetchApplicants();
  },

  createApplicant: async (data) => {
    set({ loading: true });
    try {
      await api.post('/hr/applicants', data);
      await get().fetchApplicants();
    } finally {
      set({ loading: false });
    }
  },

  updateStaffRecord: async (id, data) => {
    set({ loading: true });
    try {
      await api.put(`/hr/records/${id}`, data);
      await get().fetchRecords();
    } finally {
      set({ loading: false });
    }
  },

  deleteStaffRecord: async (id) => {
    set({ loading: true });
    try {
      await api.delete(`/hr/records/${id}`);
      await get().fetchRecords();
    } finally {
      set({ loading: false });
    }
  },

  // ============ PHASE 1 ACTIONS ============

  /**
   * GET /api/hr/dashboard/summary
   * Returns the four-tile summary consumed by HRDashboard.tsx.
   * Errors are captured in `error` (caller is expected to render a retry state).
   */
  fetchDashboardSummary: async () => {
    try {
      const res = await api.get('/hr/dashboard/summary');
      set({ dashboardSummary: res.data, error: null });
    } catch (err: any) {
      set({ error: err?.response?.data?.error || err?.message || 'Failed to load HR dashboard' });
      console.error('Failed to fetch HR dashboard summary', err);
    }
  },

  /**
   * GET /api/hr/payslips/:id
   * Stores the resulting row in `currentPayslip` (separate from the
   * `payslips` list-state to avoid stomping HRManagement.tsx's list view).
   */
  fetchPayslip: async (id: number) => {
    try {
      const res = await api.get(`/hr/payslips/${id}`);
      set({ currentPayslip: res.data, error: null });
      return res.data;
    } catch (err: any) {
      const msg = err?.response?.data?.error || err?.message || 'Failed to load payslip';
      set({ error: msg });
      console.error('Failed to fetch payslip', err);
      return null;
    }
  },

  resetPayslip: () => set({ currentPayslip: null }),
}));

export default useHRStore;
