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

export interface City {
  id: number;
  name: string;
  storage_type: number;
  image: string;
  sort_order: number;
  status: number;
  created_at: string;
  updated_at: string;
  is_interest: number;
}

export interface CityArticle {
  id: number;
  channel_id: number;
  staff_id?: number;
  category_id?: number;
  language_id?: number;
  city_id?: number;
  hashtag_id?: string;
  title: string;
  portrait_img_storage_type?: number;
  portrait_img?: string;
  landscape_img_storage_type?: number;
  landscape_img?: string;
  web_image_storage_type?: number;
  web_image?: string;
  video_upload?: number;
  audio_upload?: number;
  audio?: string;
  short_description?: 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_verified?: number;
  status: number;
  created_at: string;
  updated_at: string;
  channel_name?: string;
  channel_image?: string;
  category?: string;
  language?: string;
  city?: string;
}

// ── Thunks ────────────────────────────────────────────────────────────────────
export const fetchCities = createAsyncThunk<City[], { userId?: number }>(
  "city/fetchCities",
  async ({ userId = 0 }, { rejectWithValue }) => {
    try {
      const { default: apiClient } = await import("@/services/api.client");
      const { API_ENDPOINTS } = await import("@/lib/constants/apiEndpoints");
      const { data } = await apiClient.post<{ status: number; result: City[] }>(
        API_ENDPOINTS.GET_CITY,
        { user_id: userId },
      );
      return (data.result ?? []).filter((c) => c.status === 1);
    } catch (err) {
      return rejectWithValue((err as Error)?.message ?? "Failed to load cities.");
    }
  },
);

export const fetchArticlesByCity = createAsyncThunk<
  CityArticle[],
  { cityIds: number[]; userId?: number }
>("city/fetchArticles", async ({ cityIds, userId = 0 }, { rejectWithValue }) => {
  if (!cityIds.length) return [];
  try {
    const { default: apiClient } = await import("@/services/api.client");
    const { API_ENDPOINTS } = await import("@/lib/constants/apiEndpoints");
    const { data } = await apiClient.post<{ status: number; result: CityArticle[] }>(
      API_ENDPOINTS.GET_ARTICLE_BY_CITY,
      { city_id: cityIds.join(","), user_id: userId },
    );
    return (data.result ?? []).filter((a) => a.status === 1);
  } catch (err) {
    return rejectWithValue((err as Error)?.message ?? "Failed to load articles.");
  }
});

// ── State ─────────────────────────────────────────────────────────────────────
interface CityState {
  cities: City[];
  selectedCityIds: number[];
  articles: CityArticle[];
  citiesLoaded: boolean;
  isLoadingCities: boolean;
  isLoadingArticles: boolean;
  error: string | null;
}

const initialState: CityState = {
  cities: [],
  selectedCityIds: [],
  articles: [],
  citiesLoaded: false,
  isLoadingCities: false,
  isLoadingArticles: false,
  error: null,
};

export const citySlice = createSlice({
  name: "city",
  initialState,
  reducers: {
    toggleCitySelection: (state, action: PayloadAction<number>) => {
      const id = action.payload;
      if (state.selectedCityIds.includes(id)) {
        state.selectedCityIds = state.selectedCityIds.filter((c) => c !== id);
      } else {
        state.selectedCityIds.push(id);
      }
    },
    clearCitySelection: (state) => {
      state.selectedCityIds = [];
      state.articles = [];
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchCities.pending, (state) => { state.isLoadingCities = true; })
      .addCase(fetchCities.fulfilled, (state, action) => {
        state.isLoadingCities = false;
        state.citiesLoaded = true;
        state.cities = action.payload;
        // Pre-select cities where is_interest === 1
        const interested = action.payload.filter((c) => c.is_interest === 1).map((c) => c.id);
        if (interested.length > 0 && state.selectedCityIds.length === 0) {
          state.selectedCityIds = interested;
        }
      })
      .addCase(fetchCities.rejected, (state, action) => {
        state.isLoadingCities = false;
        state.error = (action.payload as string) ?? "Something went wrong.";
      })
      .addCase(fetchArticlesByCity.pending, (state) => { state.isLoadingArticles = true; })
      .addCase(fetchArticlesByCity.fulfilled, (state, action) => {
        state.isLoadingArticles = false;
        state.articles = action.payload;
      })
      .addCase(fetchArticlesByCity.rejected, (state) => {
        state.isLoadingArticles = false;
      });
  },
});

export const { toggleCitySelection, clearCitySelection } = citySlice.actions;
export default citySlice.reducer;

export const selectCities           = (s: RootState) => s.city.cities;
export const selectSelectedCityIds  = (s: RootState) => s.city.selectedCityIds;
export const selectCityArticles     = (s: RootState) => s.city.articles;
export const selectCitiesLoaded     = (s: RootState) => s.city.citiesLoaded;
export const selectCitiesLoading    = (s: RootState) => s.city.isLoadingCities;
export const selectArticlesLoading  = (s: RootState) => s.city.isLoadingArticles;
