import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import apiClient from "@/lib/axiosClient";
import { API_ENDPOINTS } from "@/lib/apiEndpoints";
import type { ApiListing } from "@/types/marketplace";

export interface FetchListingsParams {
  search?: string;
  category_id?: number;
  min_price?: number;
  max_price?: number;
  listing_condition?: number;
  date?: string;
  latitude?: number;
  longitude?: number;
  radius?: number;
}

interface MarketplaceListingsState {
  listings: ApiListing[];
  isLoading: boolean;
  error: string | null;
  totalRows: number;
  hasMore: boolean;
}

const initialState: MarketplaceListingsState = {
  listings: [],
  isLoading: false,
  error: null,
  totalRows: 0,
  hasMore: false,
};

export const fetchListings = createAsyncThunk(
  "marketplaceListings/fetch",
  async (params: FetchListingsParams, { rejectWithValue, getState }) => {
    try {
      const payload: Record<string, string | number> = {};
      if (params.search) payload.search = params.search;
      if (params.category_id != null) payload.category_id = params.category_id;
      if (params.min_price != null) payload.min_price = params.min_price;
      if (params.max_price != null) payload.max_price = params.max_price;
      if (params.listing_condition) payload.listing_condition = params.listing_condition;
      if (params.date) payload.date = params.date;
      if (params.latitude != null) payload.latitude = params.latitude;
      if (params.longitude != null) payload.longitude = params.longitude;
      if (params.radius != null) payload.radius = params.radius;

      const res = await apiClient.post(API_ENDPOINTS.CLASSIFIED.GET_LISTINGS, payload);
      return {
        listings: (res.data.result ?? []) as ApiListing[],
        totalRows: (res.data.total_rows ?? 0) as number,
        hasMore: (res.data.more_page ?? false) as boolean,
      };
    } catch (err: unknown) {
      /* API returns 400 "Data Not Found" when no listings match filters —
         keep existing store data rather than clearing to empty. */
      if (err && typeof err === "object" && "response" in err) {
        const axiosErr = err as { response: { status: number } };
        if (axiosErr.response.status === 400) {
          const s = getState() as { marketplaceListings: MarketplaceListingsState };
          return {
            listings: s.marketplaceListings.listings,
            totalRows: s.marketplaceListings.totalRows,
            hasMore: false,
          };
        }
      }
      const message = err instanceof Error ? err.message : "Failed to load listings";
      return rejectWithValue(message);
    }
  }
);

const marketplaceListingsSlice = createSlice({
  name: "marketplaceListings",
  initialState,
  reducers: {
    clearListings: (state) => {
      state.listings = [];
      state.totalRows = 0;
      state.hasMore = false;
      state.error = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchListings.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchListings.fulfilled, (state, action) => {
        state.isLoading = false;
        state.listings = action.payload.listings;
        state.totalRows = action.payload.totalRows;
        state.hasMore = action.payload.hasMore;
      })
      .addCase(fetchListings.rejected, (state, action) => {
        state.isLoading = false;
        state.listings = [];
        state.totalRows = 0;
        state.hasMore = false;
        state.error = action.payload as string;
      });
  },
});

export const { clearListings } = marketplaceListingsSlice.actions;
export default marketplaceListingsSlice.reducer;
