import { apiGet } from '@/services/api/api';
import { createAsyncThunk, createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
import { message } from 'antd';
import axios, { AxiosResponse } from 'axios';
import { ServerErrorResponse, RejectedActionPayload } from '@/interface/Shared';
import Helpers from '@/utilities/Helpers';

interface PayslipSummary {
  id: string;
  payroll_run_id: string;
  period_name?: string;
  period_year?: number;
  basic_salary: string;
  gross_salary: string;
  total_deductions: string;
  net_salary: string;
  created_at: string;
}

interface SalarySummary {
  grade_assignment: any;
  allowances: any[];
  deductions: any[];
  latest_payslip: {
    basic_salary: string;
    total_allowances: string;
    gross_salary: string;
    total_deductions: string;
    tax_amount: string;
    net_salary: string;
    period_name: string;
  } | null;
}

interface LoanRecord {
  id: string;
  loan_type: string;
  principal_amount: string;
  interest_rate: string;
  monthly_deduction: string;
  total_paid: string;
  balance: string;
  start_date: string;
  expected_end_date: string;
  status: string;
  repayments: any[];
}

interface PaginationMeta {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

interface EmployeePayrollState {
  payslips: PayslipSummary[];
  payslipsMeta: PaginationMeta | null;
  salarySummary: SalarySummary | null;
  loans: LoanRecord[];
  loading: boolean;
  error: string | null;
}

const initialState: EmployeePayrollState = {
  payslips: [],
  payslipsMeta: null,
  salarySummary: null,
  loans: [],
  loading: false,
  error: null,
};

export const fetchMyPayslips = createAsyncThunk(
  'employeePayroll/FETCH_PAYSLIPS',
  async (params?: { year?: number; page?: number; per_page?: number }, { rejectWithValue }) => {
    try {
      const query = new URLSearchParams();
      if (params?.year) query.set('year', String(params.year));
      if (params?.page) query.set('page', String(params.page));
      if (params?.per_page) query.set('per_page', String(params.per_page));
      const qs = query.toString();
      const response = (await apiGet(
        `/payroll/me/payslips${qs ? `?${qs}` : ''}`,
      )) as AxiosResponse<{ data: PayslipSummary[]; meta: PaginationMeta }>;
      return response.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMySalarySummary = createAsyncThunk(
  'employeePayroll/FETCH_SALARY_SUMMARY',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/payroll/me/salary-summary')) as AxiosResponse<{
        data: SalarySummary;
      }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyLoans = createAsyncThunk('employeePayroll/FETCH_LOANS', async (_, { rejectWithValue }) => {
  try {
    const response = (await apiGet('/payroll/me/loans')) as AxiosResponse<{ data: LoanRecord[] }>;
    return response.data.data;

  } catch (error) {
    if (axios.isAxiosError(error) && error.response) {
      return rejectWithValue(error.response.data as ServerErrorResponse);
    }
    throw error;
  }
  });

export const EmployeePayrollSlice = createSlice({
  name: 'employeePayroll',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchMyPayslips.pending, (state: Draft<EmployeePayrollState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchMyPayslips.fulfilled,
        (
          state: Draft<EmployeePayrollState>,
          action: PayloadAction<{ data: PayslipSummary[]; meta: PaginationMeta }>,
        ) => {
          state.payslips = action.payload.data;
          state.payslipsMeta = action.payload.meta;
          state.loading = false;
        },
      )
      .addCase(fetchMyPayslips.rejected, (state: Draft<EmployeePayrollState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchMySalarySummary.pending, (state: Draft<EmployeePayrollState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchMySalarySummary.fulfilled,
        (state: Draft<EmployeePayrollState>, action: PayloadAction<SalarySummary>) => {
          state.salarySummary = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchMySalarySummary.rejected, (state: Draft<EmployeePayrollState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchMyLoans.pending, (state: Draft<EmployeePayrollState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchMyLoans.fulfilled,
        (state: Draft<EmployeePayrollState>, action: PayloadAction<LoanRecord[]>) => {
          state.loans = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchMyLoans.rejected, (state: Draft<EmployeePayrollState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });
  },
});

export default EmployeePayrollSlice;
export type { EmployeePayrollState, PayslipSummary, SalarySummary, LoanRecord };
