import { useState, useRef, useCallback, useEffect } from "react";
import SectionCard from "./SectionCard";
import Toggle from "./Toggle";
import ApiKeyField from "./ApiKeyField";
import SaveToast from "./SaveToast";
import useSettings from "../../hooks/useSettings";

const PROVIDERS_MAP = {
  pexels: { 
    id: "pexels", 
    label: "Pexels", 
    description: "Stock photos from Pexels. Works with default key or add your own.",
    apiKey: true,
    settingKey: "pexels_api_key",
    labelKey: "Pexels API Key (Optional)",
    helpText: "Pexels works with a default key. Leave empty to use default or provide your own.",
    helpUrl: "https://www.pexels.com/api/",
    placeholder: "Leave empty for default key",
    provider: "pexels",
  },
  pixabay: { 
    id: "pixabay", 
    label: "Pixabay", 
    description: "Images and videos from Pixabay. Works with default key or add your own.",
    apiKey: true,
    settingKey: "pixabay_api_key",
    labelKey: "Pixabay API Key (Optional)",
    helpText: "Pixabay works with a default key. Leave empty to use default or provide your own.",
    helpUrl: "https://pixabay.com/api/docs/",
    placeholder: "Leave empty for default key",
    provider: "pixabay",
  },
  unsplash: {
    id: "unsplash",
    label: "Unsplash",
    description: "High-quality photos from Unsplash. Works with default key or add your own.",
    apiKey: true,
    settingKey: "unsplash_access_key",
    labelKey: "Unsplash Access Key (Optional)",
    helpText: "Unsplash works with a default key. Leave empty to use default or provide your own.",
    helpUrl: "https://unsplash.com/developers",
    placeholder: "Leave empty for default key",
    provider: "unsplash",
  },
  openverse: { id: "openverse", label: "Openverse", description: "Search openly licensed images. No API key required." },
  wikimedia: {
    id: "wikimedia",
    label: "Wikimedia",
    description: "Openly licensed images from Wikimedia Commons. No API key required.",
  },
  giphy: {
    id: "giphy",
    label: "Giphy",
    description: "GIFs and stickers from GIPHY. Works with default key or add your own.",
    apiKey: true,
    settingKey: "giphy_api_key",
    labelKey: "Giphy API Key (Optional)",
    helpText: "Giphy works with a default key. Leave empty to use default or provide your own.",
    helpUrl: "https://developers.giphy.com/",
    placeholder: "Leave empty for default key",
    provider: "giphy",
  },
  openai: {
    id: "openai",
    label: "OpenAI",
    description: "Generate images with GPT Image.",
    apiKey: true,
    settingKey: "openai_api_key",
    labelKey: "OpenAI API Key",
    helpText: "Get your API key from OpenAI.",
    helpUrl: "https://platform.openai.com/api-keys",
    placeholder: "sk-...",
    provider: "openai",
  },
  gemini: {
    id: "gemini",
    label: "Google Gemini",
    description: "Generate images with Google's Imagen 4.0 AI.",
    apiKey: true,
    settingKey: "gemini_api_key",
    labelKey: "Gemini API Key",
    helpText: "Get your free API key from Google AI Studio.",
    helpUrl: "https://aistudio.google.com/app/apikey",
    placeholder: "AIza...",
    provider: "gemini",
  },
};

const GripIcon = () => (
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-grip-icon lucide-grip"><circle cx="12" cy="5" r="1"/><circle cx="19" cy="5" r="1"/><circle cx="5" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/><circle cx="12" cy="19" r="1"/><circle cx="19" cy="19" r="1"/><circle cx="5" cy="19" r="1"/></svg>
);

const ArrowUpIcon = () => (
  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M5 15l7-7 7 7" />
  </svg>
);

const ArrowDownIcon = () => (
  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
  </svg>
);

export default function ImageSourcesSection() {
  const {
    settings,
    setSetting,
    providerEnabled,
    setProvider,
    providerOrder,
    setProviderOrder,
    saveSettings,
    testKey,
    saving,
    resetProviderSettings,
  } = useSettings();
  const [saveMessage, setSaveMessage] = useState({ type: null, text: "" });

  // Drag state
  const [draggedId, setDraggedId] = useState(null);
  const [dragOverId, setDragOverId] = useState(null);
  const dragCounter = useRef(0);

  const handleReset = () => {
    if (confirm("Reset image sources settings to default values? This will reset enabled providers and their order. This will not save automatically.")) {
      resetProviderSettings();
      setSaveMessage({ type: "success", text: "Provider settings reset to defaults. Click 'Save Changes' to apply." });
    }
  };

  const handleSave = async () => {
    setSaveMessage({ type: null, text: "" });
    const result = await saveSettings();
    setSaveMessage({
      type: result.success ? "success" : "error",
      text: result.message,
    });
  };

  // Toast handles auto-dismiss

  // Move provider up/down in order
  const moveProvider = useCallback(
    (id, direction) => {
      setProviderOrder((prev) => {
        const idx = prev.indexOf(id);
        if (idx === -1) return prev;
        const newIdx = direction === "up" ? idx - 1 : idx + 1;
        if (newIdx < 0 || newIdx >= prev.length) return prev;
        const updated = [...prev];
        [updated[idx], updated[newIdx]] = [updated[newIdx], updated[idx]];
        return updated;
      });
    },
    [setProviderOrder]
  );

  // Drag handlers
  const handleDragStart = useCallback((e, id) => {
    setDraggedId(id);
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/plain", id);
    // Make drag ghost semi-transparent
    if (e.target) {
      setTimeout(() => {
        e.target.style.opacity = "0.5";
      }, 0);
    }
  }, []);

  const handleDragEnd = useCallback((e) => {
    e.target.style.opacity = "1";
    setDraggedId(null);
    setDragOverId(null);
    dragCounter.current = 0;
  }, []);

  const handleDragEnter = useCallback((e, id) => {
    e.preventDefault();
    dragCounter.current++;
    setDragOverId(id);
  }, []);

  const handleDragLeave = useCallback(() => {
    dragCounter.current--;
    if (dragCounter.current <= 0) {
      setDragOverId(null);
      dragCounter.current = 0;
    }
  }, []);

  const handleDragOver = useCallback((e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
  }, []);

  const handleDrop = useCallback(
    (e, targetId) => {
      e.preventDefault();
      const sourceId = e.dataTransfer.getData("text/plain");
      if (!sourceId || sourceId === targetId) {
        setDragOverId(null);
        dragCounter.current = 0;
        return;
      }
      setProviderOrder((prev) => {
        const sourceIdx = prev.indexOf(sourceId);
        const targetIdx = prev.indexOf(targetId);
        if (sourceIdx === -1 || targetIdx === -1) return prev;
        const updated = [...prev];
        updated.splice(sourceIdx, 1);
        updated.splice(targetIdx, 0, sourceId);
        return updated;
      });
      setDragOverId(null);
      dragCounter.current = 0;
    },
    [setProviderOrder]
  );

  // Build ordered providers list
  const orderedProviders = providerOrder
    .filter((id) => PROVIDERS_MAP[id])
    .map((id) => PROVIDERS_MAP[id]);

  const globalEnabled = providerEnabled.global !== false;

  return (
    <SectionCard
      title="Image Sources"
      description="Enable or disable each image provider. Drag to reorder how tabs appear in the Image Generator. Disabled sources will not appear."
      onReset={handleReset}
    >
      <div className="space-y-6">
        {/* Global Search - fixed at top, not draggable */}
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
          <div>
            <label htmlFor="provider-global" className="block text-sm font-semibold text-gray-700 mb-2">
              Global Search
            </label>
            <p className="mt-1.5 text-xs text-gray-500 leading-relaxed">
              Search across all enabled providers at once. When disabled, the Global Search tab will be hidden from the Image Generator.
            </p>
          </div>
          <Toggle
            checked={globalEnabled}
            onChange={(on) => setProvider("global", on)}
            id="provider-global"
          />
        </div>

        {/* Image Providers section */}
        <div className="pt-6 border-t border-gray-100">
          <p className="text-xs font-bold text-gray-500 uppercase tracking-wider mb-4">Image Providers</p>
          <div className="space-y-4">
        {orderedProviders.map((provider, index) => {
          const enabled = providerEnabled[provider.id] !== false;
          const isDragging = draggedId === provider.id;
          const isDragOver = dragOverId === provider.id && draggedId !== provider.id;

          return (
            <div
              key={provider.id}
              draggable
              onDragStart={(e) => handleDragStart(e, provider.id)}
              onDragEnd={handleDragEnd}
              onDragEnter={(e) => handleDragEnter(e, provider.id)}
              onDragLeave={handleDragLeave}
              onDragOver={handleDragOver}
              onDrop={(e) => handleDrop(e, provider.id)}
              className={`rounded-xl border p-5 transition-all bg-white ${
                isDragging
                  ? "opacity-50 border-gray-200 bg-gray-50/50"
                  : isDragOver
                  ? "border-gray-400 ring-2 ring-gray-100"
                  : "border-gray-200 hover:border-gray-300"
              }`}
              style={{ cursor: "grab" }}
            >
              <div className="flex items-center justify-between gap-3">
                {/* Drag handle + Order controls */}
                <div className="flex items-center gap-2 shrink-0">
                  <div
                    className="flex items-center justify-center cursor-grab active:cursor-grabbing p-1 rounded hover:bg-gray-200 transition-colors"
                    title="Drag to reorder"
                  >
                    <GripIcon />
                  </div>
                  <div className="flex flex-col gap-0.5">
                    <button
                      type="button"
                      onClick={() => moveProvider(provider.id, "up")}
                      disabled={index === 0}
                      className="p-0.5 rounded text-gray-400 hover:text-gray-600 hover:bg-gray-200 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
                      title="Move up"
                    >
                      <ArrowUpIcon />
                    </button>
                    <button
                      type="button"
                      onClick={() => moveProvider(provider.id, "down")}
                      disabled={index === orderedProviders.length - 1}
                      className="p-0.5 rounded text-gray-400 hover:text-gray-600 hover:bg-gray-200 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
                      title="Move down"
                    >
                      <ArrowDownIcon />
                    </button>
                  </div>
                  {/* Position indicator */}
                  <span className="flex items-center justify-center w-6 h-6 rounded-full bg-gray-200 text-xs font-bold text-gray-500">
                    {index + 1}
                  </span>
                </div>

                {/* Provider info */}
                <div className="min-w-0 flex-1">
                  <h3 className="text-sm font-semibold text-gray-700">{provider.label}</h3>
                  <p className="mt-1.5 text-xs text-gray-500 leading-relaxed">{provider.description}</p>
                </div>

                {/* Toggle */}
                <Toggle
                  checked={enabled}
                  onChange={(on) => setProvider(provider.id, on)}
                  id={`provider-${provider.id}`}
                />
              </div>
              {provider.apiKey && enabled && (
                <div className="mt-4 pt-4 border-t border-gray-100 rounded-md ml-[76px]">
                  <ApiKeyField
                    label={provider.labelKey}
                    value={settings[provider.settingKey] || ""}
                    onChange={(v) => setSetting(provider.settingKey, v)}
                    onTest={testKey}
                    provider={provider.provider}
                    helpText={provider.helpText}
                    helpUrl={provider.helpUrl}
                    placeholder={provider.placeholder || ""}
                  />
                </div>
              )}
            </div>
          );
        })}
          </div>
        </div>

        <SaveToast
          message={saveMessage}
          onDismiss={() => setSaveMessage({ type: null, text: "" })}
        />
        <div className="flex items-center justify-end pt-6 border-t border-gray-100">
          <button
            type="button"
            onClick={handleSave}
            disabled={saving}
            className="inline-flex items-center gap-2 px-6 py-2.5 bg-gray-800 text-white text-sm font-medium rounded-md hover:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600 focus:ring-offset-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {saving ? "Saving..." : "Save Changes"}
          </button>
        </div>
      </div>
    </SectionCard>
  );
}
