import { createSlice, createAsyncThunk, type PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "@/store/store";

export interface ClipItem {
  id: number;
  channel_id: number;
  staff_id?: number;
  category_id?: number;
  language_id?: number;
  hashtag_id?: string;
  title: string;
  portrait_img_storage_type?: number;
  portrait_img?: string;
  video_storage_type?: number;
  video?: string;
  description?: string;
  is_premium?: number;
  is_like?: number;
  is_comment?: number;
  is_bookmark?: number;
  total_view: number;
  total_like: number;
  total_comment?: number;
  is_user_bookmark?: number;
  is_user_like?: number;
  is_follow?: number;
  status: number;
  created_at: string;
  updated_at: string;
  channel_name?: string;
  channel_image?: string;
  is_verified?: number;
  language?: string;
  category?: string;
}

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

/** 0=free, 1=paid, 2=all */
export const fetchClips = createAsyncThunk<
  { items: ClipItem[]; page: number; hasMore: boolean; totalRows: number },
  { userId?: number; isPremium?: 0 | 1 | 2; page?: number }
>("clips/fetch", async ({ userId = 0, isPremium = 2, 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<ClipsResponse>(
      API_ENDPOINTS.GET_CLIPS,
      { user_id: userId, is_premium: isPremium, page },
    );
    return {
      items: (data.result ?? []).filter((c) => c.status === 1),
      page,
      hasMore: data.more_page && page < data.total_page,
      totalRows: data.total_rows,
    };
  } catch (err) {
    return rejectWithValue((err as Error)?.message ?? "Failed to load clips.");
  }
});

interface ClipsState {
  items: ClipItem[];
  activeFilter: 0 | 1 | 2;
  currentPage: number;
  hasMore: boolean;
  totalRows: number;
  isLoading: boolean;
  error: string | null;
}

const initialState: ClipsState = {
  items: [],
  activeFilter: 2,
  currentPage: 0,
  hasMore: false,
  totalRows: 0,
  isLoading: false,
  error: null,
};

export const clipsSlice = createSlice({
  name: "clips",
  initialState,
  reducers: {
    setFilter: (state, action: PayloadAction<0 | 1 | 2>) => {
      if (state.activeFilter !== action.payload) {
        state.activeFilter = action.payload;
        state.items = [];
        state.currentPage = 0;
        state.hasMore = false;
      }
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchClips.pending, (state) => { state.isLoading = true; state.error = null; })
      .addCase(fetchClips.fulfilled, (state, action) => {
        state.isLoading = false;
        const { items, page, hasMore, totalRows } = action.payload;
        if (page === 1) {
          state.items = items;
        } else {
          const seen = new Set(state.items.map((c) => c.id));
          state.items = [...state.items, ...items.filter((c) => !seen.has(c.id))];
        }
        state.currentPage = page;
        state.hasMore = hasMore;
        state.totalRows = totalRows;
      })
      .addCase(fetchClips.rejected, (state, action) => {
        state.isLoading = false;
        state.error = (action.payload as string) ?? "Something went wrong.";
      });
  },
});

export const { setFilter } = clipsSlice.actions;
export default clipsSlice.reducer;

export const selectClips       = (s: RootState) => s.clips.items;
export const selectClipsLoading = (s: RootState) => s.clips.isLoading;
export const selectClipsHasMore = (s: RootState) => s.clips.hasMore;
export const selectClipsPage    = (s: RootState) => s.clips.currentPage;
export const selectClipsFilter  = (s: RootState) => s.clips.activeFilter;
export const selectClipsTotal   = (s: RootState) => s.clips.totalRows;
