import React, {
  createContext,
  useContext,
  useState,
  useCallback,
  useEffect,
} from "react";

const STORAGE_KEYS = {
  FAVORITES: "ai-image-favorites",
  SEARCH_HISTORY: "ai-image-search-history",
};

const defaultFilters = () => ({
  orientation: "",
  size: "",
  license: "",
  rating: "",
  color: "",
  imageType: "",
  order: "",
  sort: "",
  category: "",
  source: "",
  mediaType: "",
});

const GeneratorContext = createContext(null);

function readViewMode() {
  try {
    // Read from backend settings
    const config = typeof AI_IMAGE_AdminConfig !== "undefined" ? AI_IMAGE_AdminConfig : {};
    const defaultMode = config.general_settings?.default_view_mode || "grid";
    return defaultMode === "list" ? "list" : "grid";
  } catch {
    return "grid";
  }
}

function readItemsPerPage() {
  try {
    const config = typeof AI_IMAGE_AdminConfig !== "undefined" ? AI_IMAGE_AdminConfig : {};
    const perPage = config.general_settings?.items_per_page;
    if (typeof perPage === "number" && perPage >= 20 && perPage <= 100) {
      return perPage;
    }
    return 30;
  } catch {
    return 30;
  }
}

function readThumbnailSize() {
  try {
    const config = typeof AI_IMAGE_AdminConfig !== "undefined" ? AI_IMAGE_AdminConfig : {};
    const size = config.general_settings?.thumbnail_size;
    if (size === "small" || size === "medium" || size === "large") {
      return size;
    }
    return "medium";
  } catch {
    return "medium";
  }
}

function readLoadMoreMode() {
  try {
    const config = typeof AI_IMAGE_AdminConfig !== "undefined" ? AI_IMAGE_AdminConfig : {};
    const mode = config.general_settings?.load_more_mode;
    if (mode === "auto" || mode === "manual") {
      return mode;
    }
    return "auto";
  } catch {
    return "auto";
  }
}

function readFavorites() {
  try {
    const raw = localStorage.getItem(STORAGE_KEYS.FAVORITES);
    if (!raw) return {};
    const parsed = JSON.parse(raw);
    return typeof parsed === "object" && parsed !== null ? parsed : {};
  } catch {
    return {};
  }
}

function readSearchHistory() {
  try {
    const raw = localStorage.getItem(STORAGE_KEYS.SEARCH_HISTORY);
    if (!raw) return {};
    const parsed = JSON.parse(raw);
    return typeof parsed === "object" && parsed !== null ? parsed : {};
  } catch {
    return {};
  }
}

function writeFavorites(data) {
  try {
    localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(data));
  } catch (e) {
    console.error("GeneratorContext: could not write favorites", e);
  }
}

function writeSearchHistory(byProvider) {
  try {
    const limited = {};
    for (const [providerId, list] of Object.entries(byProvider)) {
      limited[providerId] = Array.isArray(list) ? list.slice(0, 10) : [];
    }
    localStorage.setItem(STORAGE_KEYS.SEARCH_HISTORY, JSON.stringify(limited));
  } catch (e) {
    console.error("GeneratorContext: could not write search history", e);
  }
}

export function GeneratorProvider({ children }) {
  const [viewMode, setViewModeState] = useState(readViewMode);
  const [filters, setFiltersState] = useState({});
  const [favorites, setFavoritesState] = useState(readFavorites);
  const [searchHistory, setSearchHistoryState] = useState(readSearchHistory);
  const [selectedImages, setSelectedImages] = useState(new Set());
  const [selectedItemsData, setSelectedItemsData] = useState({});
  const [selectionMode, setSelectionMode] = useState(false);
  const [previewImage, setPreviewImage] = useState(null);
  const [previewImageList, setPreviewImageList] = useState([]);
  const [isGenerating, setIsGenerating] = useState(false);
  
  // Read display settings from config (now as state so they can be updated)
  const [itemsPerPage, setItemsPerPage] = useState(readItemsPerPage);
  const [thumbnailSize, setThumbnailSize] = useState(readThumbnailSize);
  const [loadMoreMode, setLoadMoreMode] = useState(readLoadMoreMode);

  useEffect(() => {
    writeFavorites(favorites);
  }, [favorites]);

  useEffect(() => {
    writeSearchHistory(searchHistory);
  }, [searchHistory]);

  // Listen for settings updates
  useEffect(() => {
    const handleSettingsUpdate = (event) => {
      const updatedSettings = event.detail;
      if (updatedSettings) {
        // Update AI_IMAGE_AdminConfig if it exists
        if (typeof AI_IMAGE_AdminConfig !== "undefined" && AI_IMAGE_AdminConfig.general_settings) {
          if (updatedSettings.items_per_page !== undefined) {
            AI_IMAGE_AdminConfig.general_settings.items_per_page = updatedSettings.items_per_page;
            setItemsPerPage(updatedSettings.items_per_page);
          }
          if (updatedSettings.thumbnail_size !== undefined) {
            AI_IMAGE_AdminConfig.general_settings.thumbnail_size = updatedSettings.thumbnail_size;
            setThumbnailSize(updatedSettings.thumbnail_size);
          }
          if (updatedSettings.load_more_mode !== undefined) {
            AI_IMAGE_AdminConfig.general_settings.load_more_mode = updatedSettings.load_more_mode;
            setLoadMoreMode(updatedSettings.load_more_mode);
          }
          if (updatedSettings.default_view_mode !== undefined) {
            AI_IMAGE_AdminConfig.general_settings.default_view_mode = updatedSettings.default_view_mode;
            setViewModeState(updatedSettings.default_view_mode === "list" ? "list" : "grid");
          }
        }
      }
    };

    window.addEventListener('aiImageSettingsUpdated', handleSettingsUpdate);
    return () => window.removeEventListener('aiImageSettingsUpdated', handleSettingsUpdate);
  }, []);

  const setViewMode = useCallback((mode) => {
    setViewModeState((m) => (mode === "list" ? "list" : "grid"));
  }, []);

  const getFilters = useCallback((providerId) => {
    return {
      ...defaultFilters(),
      ...(filters[providerId] || {}),
    };
  }, [filters]);

  const setFilter = useCallback((providerId, filterKey, value) => {
    setFiltersState((prev) => ({
      ...prev,
      [providerId]: {
        ...defaultFilters(),
        ...(prev[providerId] || {}),
        [filterKey]: value,
      },
    }));
  }, []);

  const clearFilters = useCallback((providerId) => {
    setFiltersState((prev) => {
      const next = { ...prev };
      if (providerId) delete next[providerId];
      else return {};
      return next;
    });
  }, []);

  const toggleFavorite = useCallback((providerId, imageId, imageData = {}) => {
    setFavoritesState((prev) => {
      const byProvider = { ...prev };
      const obj = { ...(typeof byProvider[providerId] === "object" && byProvider[providerId] && !Array.isArray(byProvider[providerId]) ? byProvider[providerId] : {}) };
      const exists = obj[imageId];
      if (exists) delete obj[imageId];
      else obj[imageId] = { id: imageId, ...imageData };
      byProvider[providerId] = Object.keys(obj).length ? obj : undefined;
      if (!byProvider[providerId]) delete byProvider[providerId];
      return byProvider;
    });
  }, []);

  const isFavorite = useCallback(
    (providerId, imageId) => {
      const byProvider = favorites[providerId];
      if (!byProvider || Array.isArray(byProvider)) return false;
      return Boolean(byProvider[imageId]);
    },
    [favorites]
  );

  const getFavoritesList = useCallback(() => {
    const list = [];
    for (const [providerId, items] of Object.entries(favorites)) {
      if (items && typeof items === "object" && !Array.isArray(items)) {
        Object.entries(items).forEach(([id, data]) =>
          list.push({ providerId, imageId: id, ...data })
        );
      }
    }
    return list;
  }, [favorites]);

  const addSearchToHistory = useCallback((providerId, query) => {
    const q = (query || "").trim();
    if (!q) return;
    setSearchHistoryState((prev) => {
      const list = [...(prev[providerId] || [])];
      const filtered = list.filter((s) => s !== q);
      return { ...prev, [providerId]: [q, ...filtered].slice(0, 10) };
    });
  }, []);

  const getSearchHistory = useCallback(
    (providerId) => searchHistory[providerId] || [],
    [searchHistory]
  );

  const clearSearchHistory = useCallback((providerId) => {
    setSearchHistoryState((prev) => {
      const next = { ...prev };
      if (providerId) delete next[providerId];
      else return {};
      return next;
    });
  }, []);

  const selectionKey = useCallback((providerId, imageId) => `${providerId}:${imageId}`, []);

  const toggleSelection = useCallback((providerId, imageId, itemData) => {
    const key = `${providerId}:${imageId}`;
    setSelectedImages((prev) => {
      const next = new Set(prev);
      const isRemoving = next.has(key);
      if (isRemoving) next.delete(key);
      else next.add(key);
      setSelectedItemsData((d) => {
        const nextData = { ...d };
        if (isRemoving) delete nextData[key];
        else if (itemData && (itemData.importUrl || itemData.imageSrc)) {
          nextData[key] = { importUrl: itemData.importUrl, imageSrc: itemData.imageSrc, imageAlt: itemData.imageAlt, author: itemData.author, previewUrl: itemData.previewUrl };
        }
        return nextData;
      });
      return next;
    });
  }, []);

  const isSelected = useCallback(
    (providerId, imageId) => selectedImages.has(`${providerId}:${imageId}`),
    [selectedImages]
  );

  const selectAll = useCallback((providerId, imageIds, imageData = {}) => {
    setSelectedImages((prev) => {
      const next = new Set(prev);
      (imageIds || []).forEach((id) => next.add(`${providerId}:${id}`));
      return next;
    });
    setSelectedItemsData((prev) => ({ ...prev, ...imageData }));
  }, []);

  const clearSelection = useCallback(() => {
    setSelectedImages(new Set());
    setSelectedItemsData({});
    setSelectionMode(false);
  }, []);

  const setSelectionModeOn = useCallback((on) => {
    setSelectionMode(Boolean(on));
    if (!on) {
      setSelectedImages(new Set());
      setSelectedItemsData({});
    }
  }, []);

  const getSelectedUrls = useCallback(() => {
    const urls = [];
    selectedImages.forEach((key) => {
      const data = selectedItemsData[key];
      if (data?.importUrl) urls.push(data.importUrl);
    });
    return urls;
  }, [selectedImages, selectedItemsData]);

  const getSelectedItemsData = useCallback(() => {
    const items = [];
    selectedImages.forEach((key) => {
      const [providerId, imageId] = key.split(":");
      const data = selectedItemsData[key];
      if (data) items.push({ providerId, imageId, ...data });
    });
    return items;
  }, [selectedImages, selectedItemsData]);

  const getSelectedCount = useCallback(() => selectedImages.size, [selectedImages]);

  const getSelectedIdsByProvider = useCallback(() => {
    const byProvider = {};
    selectedImages.forEach((key) => {
      const [providerId, imageId] = key.split(":");
      if (!byProvider[providerId]) byProvider[providerId] = [];
      byProvider[providerId].push(imageId);
    });
    return byProvider;
  }, [selectedImages]);

  const value = {
    viewMode,
    setViewMode,
    itemsPerPage,
    thumbnailSize,
    loadMoreMode,
    filters,
    getFilters,
    setFilter,
    clearFilters,
    favorites,
    toggleFavorite,
    isFavorite,
    getFavoritesList,
    searchHistory,
    addSearchToHistory,
    getSearchHistory,
    clearSearchHistory,
    selectedImages,
    selectionMode,
    setSelectionMode: setSelectionModeOn,
    toggleSelection,
    isSelected,
    selectAll,
    clearSelection,
    getSelectedCount,
    getSelectedIdsByProvider,
    getSelectedUrls,
    getSelectedItemsData,
    selectionKey,
    previewImage,
    setPreviewImage,
    previewImageList,
    setPreviewImageList,
    isGenerating,
    setIsGenerating,
  };

  return (
    <GeneratorContext.Provider value={value}>
      {children}
    </GeneratorContext.Provider>
  );
}

export function useGenerator() {
  const context = useContext(GeneratorContext);
  if (!context) {
    throw new Error("useGenerator must be used within GeneratorProvider");
  }
  return context;
}
