import { useState } from "@wordpress/element";
import { Button, TextControl, Spinner, Notice } from "@wordpress/components";
import { __ } from "@wordpress/i18n";
import apiFetch from "@wordpress/api-fetch";
import { check, search, link as linkIcon } from "@wordpress/icons";

const CATEGORY_PRESETS = [
  { id: "business", label: __("Business", "zenblocks"), query: "business" },
  { id: "people", label: __("People", "zenblocks"), query: "people" },
  { id: "nature", label: __("Nature", "zenblocks"), query: "nature" },
  { id: "travel", label: __("Travel", "zenblocks"), query: "travel" },
  { id: "city", label: __("City", "zenblocks"), query: "city" },
  { id: "architecture", label: __("Architecture", "zenblocks"), query: "architecture" },
  { id: "lifestyle", label: __("Lifestyle", "zenblocks"), query: "lifestyle" },
  { id: "interior", label: __("Interior", "zenblocks"), query: "interior" },
  { id: "work", label: __("Work", "zenblocks"), query: "workspace" },
  { id: "food", label: __("Food", "zenblocks"), query: "food" },
  { id: "abstract", label: __("Abstract", "zenblocks"), query: "abstract" },
  { id: "texture", label: __("Texture", "zenblocks"), query: "texture" },
  { id: "technology", label: __("Technology", "zenblocks"), query: "technology" },
  { id: "illustration", label: __("Illustration", "zenblocks"), query: "illustration" },
  { id: "line-art", label: __("Line Art", "zenblocks"), query: "line art" },
  { id: "vector", label: __("Vector", "zenblocks"), query: "vector illustration" },
  { id: "flat", label: __("Flat", "zenblocks"), query: "flat illustration" },
  { id: "fashion", label: __("Fashion", "zenblocks"), query: "fashion" },
  { id: "sports", label: __("Sports", "zenblocks"), query: "sports" },
  { id: "animals", label: __("Animals", "zenblocks"), query: "animals" },
  { id: "wireframe", label: __("Wireframe", "zenblocks"), query: "wireframe" },
];

const PROVIDERS = [
  { id: "openverse", label: __("Openverse", "zenblocks") },
  { id: "unsplash", label: __("Unsplash", "zenblocks") },
  { id: "pexels", label: __("Pexels", "zenblocks") },
  { id: "pixabay", label: __("Pixabay", "zenblocks") },
];

const SEARCH_ENDPOINTS = {
  openverse: "/zenblocks/v1/media/openverse/search",
  unsplash: "/zenblocks/v1/media/unsplash/search",
  pexels: "/zenblocks/v1/media/pexels/search",
  pixabay: "/zenblocks/v1/media/pixabay/search",
};

const getSettingsPageUrl = () => {
  const ajaxUrl = window?.zenBlocks?.ajaxUrl || "";
  if (ajaxUrl.includes("admin-ajax.php")) {
    return ajaxUrl.replace("admin-ajax.php", "admin.php?page=zenblocks");
  }
  if (typeof window !== "undefined") {
    return `${window.location.origin}/wp-admin/admin.php?page=zenblocks`;
  }
  return "/wp-admin/admin.php?page=zenblocks";
};

const OpenverseImageSelector = ({ onSelect, showToggle = true, initialOpen = false }) => {
  const [isOpen, setIsOpen] = useState(showToggle ? initialOpen : true);
  const [provider, setProvider] = useState("openverse");
  const [query, setQuery] = useState("");
  const [activeCategory, setActiveCategory] = useState("");
  const [results, setResults] = useState([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(false);
  const [isSearching, setIsSearching] = useState(false);
  const [isCheckingProviderConfig, setIsCheckingProviderConfig] = useState(false);
  const [isImportingId, setIsImportingId] = useState("");
  const [error, setError] = useState("");
  const [isProviderConfigMissing, setIsProviderConfigMissing] = useState(false);
  const [providerConfigMessage, setProviderConfigMessage] = useState("");

  const isApiKeyMissingError = (searchError, providerId) => {
    const errorCode = searchError?.code || "";
    const errorStatus = searchError?.data?.status;
    return (
      (providerId === "unsplash" && (errorCode === "zenblocks_unsplash_key_missing" || errorStatus === 401)) ||
      (providerId === "pexels" && (errorCode === "zenblocks_pexels_key_missing" || errorStatus === 401)) ||
      (providerId === "pixabay" && (errorCode === "zenblocks_pixabay_key_missing" || errorStatus === 401))
    );
  };

  const getProviderConfigMessage = (providerId) => {
    if (providerId === "unsplash") {
      return __("An API key is required for Unsplash search. Please set the Unsplash Access Key in ZenBlocks Settings > External Media API.", "zenblocks");
    }
    if (providerId === "pexels") {
      return __("An API key is required for Pexels search. Please set the Pexels API Key in ZenBlocks Settings > External Media API.", "zenblocks");
    }
    if (providerId === "pixabay") {
      return __("An API key is required for Pixabay search. Please set the Pixabay API Key in ZenBlocks Settings > External Media API.", "zenblocks");
    }
    return "";
  };

  const checkProviderConfig = async (providerId) => {
    if (providerId === "openverse") {
      setIsCheckingProviderConfig(false);
      setIsProviderConfigMissing(false);
      setProviderConfigMessage("");
      return;
    }

    setIsCheckingProviderConfig(true);
    try {
      await apiFetch({
        path: `${SEARCH_ENDPOINTS[providerId]}?q=&page=1&per_page=1`,
        method: "GET",
      });
      setIsProviderConfigMissing(false);
      setProviderConfigMessage("");
    } catch (searchError) {
      if (isApiKeyMissingError(searchError, providerId)) {
        setIsProviderConfigMissing(true);
        setProviderConfigMessage(getProviderConfigMessage(providerId));
        setResults([]);
        setHasMore(false);
        setPage(1);
        setError("");
      } else {
        setIsProviderConfigMissing(false);
        setProviderConfigMessage("");
      }
    } finally {
      setIsCheckingProviderConfig(false);
    }
  };

  const searchImages = async ({ nextPage = 1, append = false, keyword = "", providerId = "" } = {}) => {
    const effectiveProvider = providerId || provider;
    const searchTerm = String(keyword || query).trim();
    if (!searchTerm) {
      setError(__("Please enter a keyword.", "zenblocks"));
      return;
    }

    setIsSearching(true);
    setError("");

    try {
      const endpoint = SEARCH_ENDPOINTS[effectiveProvider] || SEARCH_ENDPOINTS.openverse;
      const response = await apiFetch({
        path: `${endpoint}?q=${encodeURIComponent(searchTerm)}&page=${nextPage}&per_page=20`,
        method: "GET",
      });

      const items = response?.items || [];
      const nextHasMore = Boolean(response?.pagination?.has_more);
      setResults((prev) => (append ? [...prev, ...items] : items));
      setPage(nextPage);
      setHasMore(nextHasMore);
      setIsProviderConfigMissing(false);
      setProviderConfigMessage("");
    } catch (searchError) {
      if (isApiKeyMissingError(searchError, effectiveProvider)) {
        setIsProviderConfigMissing(true);
        setProviderConfigMessage(getProviderConfigMessage(effectiveProvider));
        setResults([]);
        setHasMore(false);
        setPage(1);
        setError("");
      } else {
        setError(searchError?.message || __("Failed to search images.", "zenblocks"));
      }
    } finally {
      setIsSearching(false);
    }
  };

  const handleProviderChange = (nextProvider) => {
    if (provider === nextProvider) return;
    setProvider(nextProvider);
    setActiveCategory("");
    setResults([]);
    setPage(1);
    setHasMore(false);
    setError("");
    setIsProviderConfigMissing(false);
    setProviderConfigMessage("");
    checkProviderConfig(nextProvider);
  };

  const handleCategoryClick = (category) => {
    setActiveCategory(category.id);
    setQuery(category.query);
    searchImages({ nextPage: 1, append: false, keyword: category.query });
  };

  const importImage = async (item) => {
    setError("");
    setIsImportingId(item.id);

    try {
      if (provider === "unsplash" && item.downloadLocation) {
        await apiFetch({
          path: "/zenblocks/v1/media/unsplash/track-download",
          method: "POST",
          data: {
            download_location: item.downloadLocation,
          },
        });
      }

      const response = await apiFetch({
        path: "/zenblocks/v1/media/import",
        method: "POST",
        data: {
          image_url: item.fullUrl || item.thumbnailUrl,
          title: item.title || "",
          creator: item.creator || "",
          source: item.source || provider,
          source_url: item.sourceUrl || "",
          license: item.license || (provider === "unsplash" ? "unsplash" : "cc0"),
        },
      });

      if (response?.url && onSelect) {
        onSelect(response.url);
      }
    } catch (importError) {
      setError(importError?.message || __("Failed to import image.", "zenblocks"));
    } finally {
      setIsImportingId("");
    }
  };

  const getMetaLinks = (item) => {
    const authorUrl = item.attributionUrl || item.creatorUrl || item.authorUrl || item.sourceUrl || "";
    const sourceUrl = item.sourceUrl || item.unsplashUrl || item.providerUrl || "";
    const licenseUrl = item.licenseUrl || item.license_url || "";
    return { authorUrl, sourceUrl, licenseUrl };
  };

  return (
    <div className="zenblocks-openverse-image-selector">
      {showToggle && (
        <Button
          variant={isOpen ? "primary" : "secondary"}
          onClick={() => setIsOpen((prev) => !prev)}
          className="zenblocks-openverse-image-selector__toggle"
        >
          {__("Image Search", "zenblocks")}
        </Button>
      )}
      <p className="zenblocks-openverse-image-selector__notice">
        {provider === "unsplash" && __("Unsplash images require attribution. Download tracking is performed when selecting an image.", "zenblocks")}
        {provider === "openverse" && __("Images shown are filtered to CC0, making them relatively safe for commercial use.", "zenblocks")}
        {provider === "pexels" && __("Search Pexels images. Please review Pexels terms of use.", "zenblocks")}
        {provider === "pixabay" && __("Search Pixabay images. Please review Pixabay terms of use.", "zenblocks")}
      </p>

      {(showToggle ? isOpen : true) && (
        <div className="zenblocks-openverse-image-selector__content">
          <div className="zenblocks-openverse-image-selector__provider-tabs">
            {PROVIDERS.map((item) => (
              <Button
                key={item.id}
                isSmall
                variant={provider === item.id ? "primary" : "secondary"}
                onClick={() => handleProviderChange(item.id)}
                className="zenblocks-openverse-image-selector__provider-btn"
              >
                {item.label}
              </Button>
            ))}
          </div>

          {isProviderConfigMissing && (
            <div className="zenblocks-openverse-image-selector__setup">
              <p className="zenblocks-openverse-image-selector__setup-text">
                {providerConfigMessage}
              </p>
              <Button
                href={getSettingsPageUrl()}
                target="_blank"
                rel="noopener noreferrer"
                variant="secondary"
              >
                {__("ZenBlocks Settings", "zenblocks")}
              </Button>
            </div>
          )}

          {isCheckingProviderConfig && !isProviderConfigMissing && (
            <div className="zenblocks-openverse-image-selector__loading">
              <Spinner />
            </div>
          )}

          {!isProviderConfigMissing && !isCheckingProviderConfig && (
            <>
          <div className="zenblocks-openverse-image-selector__search">
            <TextControl
              label={__("Search images", "zenblocks")}
              hideLabelFromVision={true}
              value={query}
              onChange={(value) => {
                setQuery(value);
                setActiveCategory("");
              }}
              placeholder={__("e.g. business, nature, workspace", "zenblocks")}
            />
            <Button
              variant="primary"
              onClick={() => searchImages({ nextPage: 1, append: false })}
              disabled={isSearching || !query.trim()}
              icon={search}
              label={__("Search", "zenblocks")}
              className="zenblocks-openverse-image-selector__search-button"
            >
              <span className="screen-reader-text">
                {isSearching ? __("Searching...", "zenblocks") : __("Search", "zenblocks")}
              </span>
            </Button>
          </div>

          <div className="zenblocks-openverse-image-selector__categories">
            {CATEGORY_PRESETS.map((category) => (
              <Button
                key={category.id}
                isSmall
                variant={activeCategory === category.id ? "primary" : "secondary"}
                onClick={() => handleCategoryClick(category)}
                className="zenblocks-openverse-image-selector__category-btn"
              >
                {category.label}
              </Button>
            ))}
          </div>

          {error && (
            <Notice status="error" isDismissible onDismiss={() => setError("")}>
              {error}
            </Notice>
          )}

          {isSearching && results.length === 0 && (
            <div className="zenblocks-openverse-image-selector__loading">
              <Spinner />
            </div>
          )}

          {results.length > 0 && (
            <>
              <div className="zenblocks-openverse-image-selector__grid">
                {results.map((item) => (
                  <div key={item.id} className="zenblocks-openverse-image-selector__item-card">
                    <div className="zenblocks-openverse-image-selector__image-wrap">
                      <button
                        type="button"
                        className="zenblocks-openverse-image-selector__image-button"
                        onClick={() => importImage(item)}
                        disabled={Boolean(isImportingId)}
                        aria-label={item.title || __("Use image", "zenblocks")}
                      >
                        <img
                          src={item.thumbnailUrl}
                          alt={item.title || __("Image", "zenblocks")}
                          title={item.title || __("Image", "zenblocks")}
                        />
                        {isImportingId === item.id && (
                          <span className="zenblocks-openverse-image-selector__importing">
                            {__("Importing...", "zenblocks")}
                          </span>
                        )}
                      </button>
                    </div>
                    {(() => {
                      const { authorUrl, sourceUrl, licenseUrl } = getMetaLinks(item);
                      return (
                        <>
                          <div className="zenblocks-openverse-image-selector__item-actions">
                            {(authorUrl || sourceUrl) && (
                              <a
                                href={authorUrl || sourceUrl}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="zenblocks-openverse-image-selector__action-icon"
                                title={__("Author", "zenblocks")}
                                aria-label={__("Author", "zenblocks")}
                              >
                                <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
                                  <circle cx="12" cy="8" r="3.5" fill="none" stroke="currentColor" strokeWidth="1.8" />
                                  <path d="M5.5 19c0-3.2 2.9-5.5 6.5-5.5s6.5 2.3 6.5 5.5" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" />
                                </svg>
                              </a>
                            )}
                            {sourceUrl && (
                              <a
                                href={sourceUrl}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="zenblocks-openverse-image-selector__action-icon"
                                title={__("Source", "zenblocks")}
                                aria-label={__("Source", "zenblocks")}
                              >
                                {linkIcon}
                              </a>
                            )}
                            {licenseUrl && (
                              <a
                                href={licenseUrl}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="zenblocks-openverse-image-selector__action-icon"
                                title={__("License", "zenblocks")}
                                aria-label={__("License", "zenblocks")}
                              >
                                {check}
                              </a>
                            )}
                          </div>
                        </>
                      );
                    })()}
                  </div>
                ))}
              </div>

              {hasMore && (
                <div className="zenblocks-openverse-image-selector__actions">
                  <Button
                    variant="secondary"
                    onClick={() => searchImages({ nextPage: page + 1, append: true })}
                    disabled={isSearching}
                  >
                    {isSearching ? __("Loading...", "zenblocks") : __("Load more", "zenblocks")}
                  </Button>
                </div>
              )}
            </>
          )}
            </>
          )}
        </div>
      )}
    </div>
  );
};

export default OpenverseImageSelector;
