import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { RootState } from "../../store";
import {
  getRequest,
  patchRequest,
  postRequest,
} from "../../../config/axois/apiRequest";
import { showError, showSuccess } from "../../../components/alerts/alerts";
import { clientsApi } from "../../../config/apiUrls/apiUrl";
import { OK } from "../../../config/axois/apiStatusCode";
import { isEmpty } from "../../../helper/helper";

export interface Client {
  id: string | number;
  name: string;
  phone_no: string;
  address?: string | null;
  deleted_at?: string | null;
}

interface ClientsState {
  clients: Client[];
  details: Client | null;
  loading: boolean;
  detailsLoading: boolean;
  error: string | null;
}

interface QueryParam {
  currentOffset: number;
  limit: number;
  search?: string;
  ordering?: string;
  isDeleted?: string;
}

const initialState: ClientsState = {
  clients: [],
  details: null,
  loading: false,
  detailsLoading: false,
  error: null,
};

export const fetchClients: any = createAsyncThunk(
  "clients/fetchClients",
  async ({ currentOffset, limit, search, ordering, isDeleted }: QueryParam) => {
    try {
      const response = await getRequest(
        `${
          clientsApi.getClients
        }?limit=${limit}&offset=${currentOffset}&search=${
          isEmpty(search) ? "" : search
        }&ordering=${isEmpty(ordering) ? "" : ordering}&with_trashed=${
          isDeleted ? "true" : "false"
        }`,
        true
      );

      return response;
    } catch (error: any) {
      return error;
    }
  }
);

export const createClient = createAsyncThunk(
  "clients/createClient",
  async (newClient: Omit<Client, "id">) => {
    // Omitting "id" from newClient
    try {
      const response = await postRequest(
        clientsApi.createClient,
        newClient,
        true
      );

      return response;
    } catch (error: any) {
      showError(error.message);

      return error;
    }
  }
);

export const updateClient = createAsyncThunk(
  "clients/updateClient",
  async (updatedClient: Client) => {
    try {
      const response = await patchRequest(
        clientsApi.updateClient + updatedClient.id,
        updatedClient,
        true
      );

      return response;
    } catch (error: any) {
      showError(error.message);

      return error;
    }
  }
);

export const getClientById = createAsyncThunk(
  "clients/getClientById",
  async (clientId: any) => {
    try {
      const response = await getRequest(
        `${clientsApi.getClients}/${clientId}`,
        true
      );

      return response;
    } catch (error: any) {
      return error;
    }
  }
);

const clientsSlice = createSlice({
  name: "clients",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchClients.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchClients.fulfilled, (state, action) => {
        state.loading = false;
        state.clients = action?.payload?.data?.data ?? {};
      })
      .addCase(fetchClients.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || "Failed to fetch clients";
      })
      .addCase(createClient.fulfilled, (state, action) => {
        if ([200, 201].includes(action?.payload?.status)) {
          showSuccess("Client Added Successfully");
        }
      })
      .addCase(updateClient.fulfilled, (state, action) => {
        if ([200, 201].includes(action?.payload?.status)) {
          showSuccess("Client Updated Successfully");
        }
      })
      .addCase(getClientById.pending, (state) => {
        state.detailsLoading = true;
        state.error = null;
      })
      .addCase(getClientById.fulfilled, (state, action) => {
        state.detailsLoading = false;
        state.details = action?.payload?.data?.data ?? null;
      })
      .addCase(getClientById.rejected, (state, action) => {
        state.detailsLoading = false;
        state.error = action.error.message || "Failed to fetch client";
      });
  },
});

// Selectors
export const selectClients = (state: RootState) => state.clients.clients;

export const selectDetails = (state: RootState) => state.clients.details;

export const selectClientsLoading = (state: RootState) => state.clients.loading;

export const selectDetailsLoading = (state: RootState) =>
  state.clients.detailsLoading;

export const selectClientsError = (state: RootState) => state.clients.error;

const clientReducer = clientsSlice.reducer;

export default clientReducer;
