import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import type { SectionDataItem } from "@/types/api/section.types";
import type { RootState } from "@/store/store";

interface PaginationMeta {
  currentPage: number;
  totalPage: number;
  totalRows: number;
  hasMore: boolean;
}

interface SectionDetailResponse {
  status: number;
  message: string;
  result: SectionDataItem[];
  total_rows: number;
  total_page: number;
  current_page: number;
  more_page: boolean;
}

interface FetchSectionDetailPayload {
  sectionId: number;
  userId: number;
  page?: number;
}

export const fetchSectionDetail = createAsyncThunk<
  { sectionId: number; items: SectionDataItem[]; meta: PaginationMeta; page: number },
  FetchSectionDetailPayload
>(
  "sectionDetail/fetch",
  async ({ sectionId, userId, page = 1 }, { rejectWithValue }) => {
    try {
      const { default: apiClient } = await import("@/services/api.client");
      const { API_ENDPOINTS } = await import("@/lib/constants/apiEndpoints");
      const { data } = await apiClient.post<SectionDetailResponse>(
        API_ENDPOINTS.GET_SECTION_DETAIL,
        { section_id: sectionId, user_id: userId, page },
      );
      return {
        sectionId,
        page,
        items: (data.result ?? []).filter((i) => (i as unknown as Record<string, unknown>).status === 1),
        meta: {
          currentPage: page,
          totalPage: data.total_page,
          totalRows: data.total_rows,
          hasMore: data.more_page && page < data.total_page,
        },
      };
    } catch (err) {
      return rejectWithValue((err as Error)?.message ?? "Failed to load section detail.");
    }
  },
);

interface SectionDetailState {
  itemsBySection: Record<number, SectionDataItem[]>;
  paginationBySection: Record<number, PaginationMeta>;
  loadedSections: number[];
  isLoading: boolean;
  error: string | null;
}

const initialState: SectionDetailState = {
  itemsBySection: {},
  paginationBySection: {},
  loadedSections: [],
  isLoading: false,
  error: null,
};

export const sectionDetailSlice = createSlice({
  name: "sectionDetail",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchSectionDetail.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchSectionDetail.fulfilled, (state, action) => {
        state.isLoading = false;
        const { sectionId, items, meta, page } = action.payload;

        if (page === 1) {
          state.itemsBySection[sectionId] = items;
          if (!state.loadedSections.includes(sectionId)) {
            state.loadedSections.push(sectionId);
          }
        } else {
          const existing = state.itemsBySection[sectionId] ?? [];
          const existingIds = new Set(existing.map((i) => (i as unknown as Record<string, unknown>).id));
          const fresh = items.filter((i) => !existingIds.has((i as unknown as Record<string, unknown>).id));
          state.itemsBySection[sectionId] = [...existing, ...fresh];
        }
        state.paginationBySection[sectionId] = meta;
      })
      .addCase(fetchSectionDetail.rejected, (state, action) => {
        state.isLoading = false;
        state.error = (action.payload as string) ?? "Something went wrong.";
      });
  },
});

export default sectionDetailSlice.reducer;

export const selectSectionDetailItems = (sectionId: number) => (s: RootState) =>
  s.sectionDetail.itemsBySection[sectionId] ?? [];

export const selectSectionDetailPagination = (sectionId: number) => (s: RootState) =>
  s.sectionDetail.paginationBySection[sectionId] ?? null;

export const selectSectionDetailLoaded = (sectionId: number) => (s: RootState) =>
  s.sectionDetail.loadedSections.includes(sectionId);

export const selectSectionDetailLoading = (s: RootState) => s.sectionDetail.isLoading;
