import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { videoListService, FetchVideoListParams } from "@/services/videoListService";
import { VideoItem } from "@/types/home";

interface VideoListState {
  videos: VideoItem[];
  isLoading: boolean;
  isLoadingMore: boolean;
  error: string | null;
  currentPage: number;
  hasMore: boolean;
  activeCategoryId: number;
}

const initialState: VideoListState = {
  videos: [],
  isLoading: false,
  isLoadingMore: false,
  error: null,
  currentPage: 1,
  hasMore: false,
  activeCategoryId: 0,
};

export const fetchVideoList = createAsyncThunk(
  "videoList/fetch",
  async (params: FetchVideoListParams, { rejectWithValue }) => {
    try {
      const res = await videoListService.getVideoList(params);
      if (res.status !== 200) return rejectWithValue(res.message);
      return {
        videos: res.result.map(videoListService.mapVideo),
        hasMore: res.more_page,
        currentPage: res.current_page,
        categoryId: params.categoryId,
      };
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : "Failed to load videos";
      return rejectWithValue(msg);
    }
  },
  {
    // Skip page-1 fetch if the same category is already cached —
    // prevents re-fetching when the user navigates back to Home or Videos.
    // Page > 1 (infinite scroll) always proceeds.
    condition: (params, { getState }) => {
      if (params.pageNo !== 1) return true;
      const { videoList } = getState() as { videoList: VideoListState };
      if (videoList.isLoading) return false;
      return (
        videoList.videos.length === 0 ||
        videoList.activeCategoryId !== params.categoryId
      );
    },
  },
);

const videoListSlice = createSlice({
  name: "videoList",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchVideoList.pending, (state, action) => {
        state.error = null;
        if (action.meta.arg.pageNo === 1) {
          state.isLoading = true;
          state.isLoadingMore = false;
          state.videos = [];
        } else {
          state.isLoadingMore = true;
        }
      })
      .addCase(fetchVideoList.fulfilled, (state, action) => {
        state.isLoading = false;
        state.isLoadingMore = false;
        state.hasMore = action.payload.hasMore;
        state.currentPage = action.payload.currentPage;
        state.activeCategoryId = action.payload.categoryId;
        if (action.payload.currentPage === 1) {
          state.videos = action.payload.videos;
        } else {
          state.videos.push(...action.payload.videos);
        }
      })
      .addCase(fetchVideoList.rejected, (state, action) => {
        state.isLoading = false;
        state.isLoadingMore = false;
        state.error = action.payload as string;
      });
  },
});

export default videoListSlice.reducer;
