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 { OK } from "../../../config/axois/apiStatusCode";
import { contractorApi } from "../../../config/apiUrls/apiUrl";
import { errorHandler, isEmpty } from "../../../helper/helper";

export interface Contractor {
  id: string | number;
  name: string;
  type: string;
  phone_no: string;
  email?: string | null;
  note?: string | null;
}

interface ContractorListing extends Contractor {
  created_by: string;
  deleted_at?: string;
}

interface ContractorState {
  contractors: ContractorListing[];
  contractorsList: ContractorListing[];
  details: Contractor | null;
  loading: boolean;
  contractorsListLoading: boolean;
  detailsLoading: boolean;
  error: string | null;
}

interface QueryParam {
  currentOffset: number;
  limit: number;
  search?: string;
  projectId?: number;
  projectIdList?: number;
  ordering?: string;
  isModal?: boolean;
  isDeleted?: boolean;
}

const initialState: ContractorState = {
  contractors: [],
  contractorsList: [],
  details: null,
  loading: false,
  contractorsListLoading: false,
  detailsLoading: false,
  error: null,
};

export const fetchContractors: any = createAsyncThunk(
  "contractors/fetchContractors",
  async ({
    currentOffset,
    limit,
    search,
    projectId,
    ordering,
    projectIdList,
    isModal,
    isDeleted,
  }: QueryParam) => {
    try {
      let url = `${contractorApi.getContractors}?limit=${limit}&offset=${currentOffset}`;

      if (!isEmpty(search)) {
        url += `&search=${search}`;
      }

      if (!isEmpty(projectId)) {
        url += `&contractor_without_project_id=${projectId}`;
      }

      if (!isEmpty(projectIdList)) {
        url += `&project_id=${projectIdList}`;
      }

      if (!isEmpty(ordering)) {
        url += `&ordering=${ordering}`;
      }

      if (isDeleted) {
        url += `&with_trashed=true`;
      }

      const response = await getRequest(url, true);

      return { ...response, isModal: isModal };
    } catch (error: any) {
      return error;
    }
  }
);

export const clearContractor: any = createAsyncThunk(
  "contractors/clearContractor",
  async (value: boolean) => {
    return value;
  }
);

export const createContractor = createAsyncThunk(
  "contractors/createContractor",
  async (newVendor: Omit<Contractor, "id">) => {
    // Omitting "id" from newVendor
    try {
      const response = await postRequest(
        contractorApi.createContractor,
        newVendor,
        true
      );

      return response;
    } catch (error: any) {
      if (error?.response?.data?.errors) {
        errorHandler(error?.response?.data?.errors);
        return;
      } else {
        showError("Something Went Wrong");
      }

      return error;
    }
  }
);

export const updateContractor = createAsyncThunk(
  "contractors/updateContractor",
  async (updatedConsultant: Contractor) => {
    try {
      const response = await patchRequest(
        contractorApi.updateContractor + updatedConsultant.id,
        updatedConsultant,
        true
      );

      return response;
    } catch (error: any) {
      if (error?.response?.data?.errors) {
        errorHandler(error?.response?.data?.errors);
        return;
      } else {
        showError("Something Went Wrong");
      }

      return error;
    }
  }
);

export const getContractorById = createAsyncThunk(
  "contractors/getContractorById",
  async (contractorId: any) => {
    try {
      const response = await getRequest(
        `${contractorApi.getContractors}/${contractorId}`,
        true
      );

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

const contractorsSlice = createSlice({
  name: "contractors",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchContractors.pending, (state, action) => {
        if (action?.meta?.arg?.isModal) {
          state.contractorsListLoading = true;
        } else {
          state.loading = true;
        }

        state.error = null;
      })
      .addCase(fetchContractors.fulfilled, (state, action) => {
        // only for add vendor modal in project details
        if (action.payload?.isModal) {
          state.contractorsListLoading = false;
          state.contractorsList = [
            ...state.contractorsList,
            ...(action.payload?.data?.data ?? []),
          ];
        } else {
          state.loading = false;
          state.contractors = action.payload?.data?.data ?? [];
        }
      })
      .addCase(clearContractor.fulfilled, (state, action) => {
        state.contractorsList = [];
      })
      .addCase(fetchContractors.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || "Failed to fetch contractors";
      })
      .addCase(createContractor.fulfilled, (state, action) => {
        if ([200, 201].includes(action?.payload?.status)) {
          showSuccess("Contractor Added Successfully");
        }
      })
      .addCase(updateContractor.fulfilled, (state, action) => {
        if ([200, 201].includes(action?.payload?.status)) {
          showSuccess("Contractor Updated Successfully");
        }
      })
      .addCase(getContractorById.pending, (state) => {
        state.detailsLoading = true;
        state.error = null;
      })
      .addCase(getContractorById.fulfilled, (state, action) => {
        state.detailsLoading = false;
        state.details = action?.payload?.data?.data ?? null;
      })
      .addCase(getContractorById.rejected, (state, action) => {
        state.detailsLoading = false;
        state.error = action.error.message || "Failed to fetch vendor";
      });
  },
});

// Selectors
export const contractorsSelectors = (state: RootState) => state.contractors;

const contractorsReducer = contractorsSlice.reducer;

export default contractorsReducer;
