import { useState } from "react";
import type { DatasetInfo, Preset } from "../types";
import { api } from "../api";

interface SidebarProps {
  datasets: DatasetInfo[];
  presets: Preset[];
  setPresets: (p: Preset[]) => void;
  loading: Record<string, boolean>;
  onAddDataset: (repo: string, config?: string, split?: string, presetId?: string, presetName?: string) => void;
  onRemoveDataset: (id: string) => void;
  onToggleDataset: (id: string) => void;
  onSelectDataset: (id: string) => void;
  onUpdateDatasetPresetName: (dsId: string, name: string) => void;
  onClearDatasetPreset: (dsId: string) => void;
}

export default function Sidebar({
  datasets,
  presets,
  setPresets,
  loading,
  onAddDataset,
  onRemoveDataset,
  onToggleDataset,
  onSelectDataset,
  onUpdateDatasetPresetName,
  onClearDatasetPreset,
}: SidebarProps) {
  const [showAddForm, setShowAddForm] = useState(false);
  const [repo, setRepo] = useState("");
  const [config, setConfig] = useState("rlm_call_traces");
  const [split, setSplit] = useState("train");
  const [presetSearch, setPresetSearch] = useState("");

  // Inline preset saving
  const [savingPresetForId, setSavingPresetForId] = useState<string | null>(null);
  const [presetName, setPresetName] = useState("");

  // Preset editing panel
  const [editingDatasetId, setEditingDatasetId] = useState<string | null>(null);
  const [editPresetName, setEditPresetName] = useState("");

  const handleAdd = () => {
    if (!repo.trim()) return;
    onAddDataset(repo.trim(), config, split);
    setRepo("");
    setShowAddForm(false);
  };

  const handleLoadPreset = (p: Preset) => {
    onAddDataset(p.repo, p.config, p.split || "train", p.id, p.name);
  };

  const handleSavePresetForRepo = async (ds: DatasetInfo) => {
    if (!presetName.trim()) return;
    try {
      const preset = (await api.createPreset({
        name: presetName.trim(),
        repo: ds.repo,
        config: ds.config,
        split: ds.split,
      })) as unknown as Preset;
      setPresets([...presets, preset]);
      onUpdateDatasetPresetName(ds.id, presetName.trim());
    } catch {
      /* ignore */
    }
    setPresetName("");
    setSavingPresetForId(null);
  };

  const handleUpdatePreset = async (presetId: string, dsId: string) => {
    if (!editPresetName.trim()) return;
    try {
      await api.updatePreset(presetId, { name: editPresetName.trim() });
      setPresets(
        presets.map((p) => (p.id === presetId ? { ...p, name: editPresetName.trim() } : p))
      );
      onUpdateDatasetPresetName(dsId, editPresetName.trim());
    } catch {
      /* ignore */
    }
    setEditingDatasetId(null);
  };

  const handleDeletePreset = async (id: string, dsId?: string) => {
    await api.deletePreset(id).catch(() => {});
    setPresets(presets.filter((p) => p.id !== id));
    if (dsId) {
      onClearDatasetPreset(dsId);
    }
    setEditingDatasetId(null);
  };

  const filteredPresets = presetSearch
    ? presets.filter(
        (p) =>
          p.name.toLowerCase().includes(presetSearch.toLowerCase()) ||
          p.repo.toLowerCase().includes(presetSearch.toLowerCase())
      )
    : presets;

  return (
    <div className="w-64 min-w-64 bg-gray-900 border-r border-gray-700 flex flex-col h-full overflow-hidden">
      {/* Header */}
      <div className="p-3 border-b border-gray-700">
        <h1 className="text-sm font-bold tracking-wide text-gray-200">RLM Eval Visualizer</h1>
      </div>

      {/* Presets section */}
      <div className="p-3 border-b border-gray-700">
        <div className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2">
          Presets
        </div>
        {presets.length === 0 ? (
          <p className="text-xs text-gray-500 italic">No presets saved</p>
        ) : (
          <>
            {presets.length > 6 && (
              <input
                type="text"
                value={presetSearch}
                onChange={(e) => setPresetSearch(e.target.value)}
                placeholder="Search presets..."
                className="w-full px-2 py-1 mb-2 text-xs bg-gray-800 border border-gray-600 rounded text-gray-200 placeholder-gray-500 focus:border-emerald-500 focus:outline-none"
              />
            )}
            <div className="flex flex-wrap gap-1 max-h-32 overflow-y-auto">
              {filteredPresets.map((p) => (
                <div key={p.id} className="group relative">
                  <button
                    onClick={() => handleLoadPreset(p)}
                    className="px-2 py-1 text-xs bg-gray-800 hover:bg-gray-700 rounded border border-gray-600 text-gray-300 transition-colors"
                    title={`${p.repo} (${p.config}, ${p.split ?? "train"})`}
                  >
                    {p.name}
                  </button>
                  <div className="hidden group-hover:flex absolute top-full left-0 mt-1 z-10 gap-1">
                    <button
                      onClick={() => handleDeletePreset(p.id)}
                      className="px-1.5 py-0.5 text-[10px] bg-red-900 hover:bg-red-800 rounded text-red-300"
                    >
                      Delete
                    </button>
                  </div>
                </div>
              ))}
            </div>
          </>
        )}
      </div>

      {/* Loaded Experiments */}
      <div className="flex-1 overflow-y-auto p-3">
        <div className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2">
          Loaded Datasets
        </div>
        {datasets.length === 0 ? (
          <p className="text-xs text-gray-500 italic">No datasets loaded</p>
        ) : (
          <div className="space-y-1">
            {datasets.map((ds) => (
              <div key={ds.id}>
                <div
                  onClick={() => {
                    if (ds.presetId) {
                      setEditingDatasetId(editingDatasetId === ds.id ? null : ds.id);
                      setEditPresetName(ds.presetName || "");
                      setShowAddForm(false);
                    }
                    onSelectDataset(ds.id);
                  }}
                  className={`flex items-center gap-2 px-2 py-1.5 rounded text-sm transition-colors cursor-pointer ${
                    ds.active ? "bg-gray-800" : "bg-gray-900 opacity-60"
                  } ${editingDatasetId === ds.id ? "ring-1 ring-emerald-500" : "hover:bg-gray-800"}`}
                >
                  <input
                    type="checkbox"
                    checked={ds.active}
                    onChange={() => onToggleDataset(ds.id)}
                    onClick={(e) => e.stopPropagation()}
                    className="accent-emerald-500 shrink-0"
                  />
                  <div className="flex-1 min-w-0">
                    <div
                      className="text-xs font-medium text-gray-200 truncate"
                      title={ds.presetName ? `${ds.presetName}\n${ds.repo}` : ds.repo}
                    >
                      {ds.presetName || ds.name}
                    </div>
                    <div className="text-[10px] text-gray-500">
                      {ds.metadata.model} | {ds.n_examples} examples
                    </div>
                  </div>
                  {/* Save as preset bookmark */}
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      setSavingPresetForId(savingPresetForId === ds.id ? null : ds.id);
                      setPresetName(ds.presetName || ds.name);
                    }}
                    className={`transition-colors shrink-0 ${
                      savingPresetForId === ds.id
                        ? "text-emerald-400"
                        : ds.presetId
                          ? "text-emerald-500"
                          : "text-gray-600 hover:text-emerald-400"
                    }`}
                    title={ds.presetId ? "Saved as preset" : "Save as preset"}
                  >
                    <svg
                      className="w-3.5 h-3.5"
                      fill={ds.presetId ? "currentColor" : "none"}
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
                      />
                    </svg>
                  </button>
                  {/* Remove */}
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      onRemoveDataset(ds.id);
                    }}
                    className="text-gray-600 hover:text-red-400 transition-colors shrink-0"
                    title="Remove"
                  >
                    <svg
                      className="w-3.5 h-3.5"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M6 18L18 6M6 6l12 12"
                      />
                    </svg>
                  </button>
                </div>

                {/* Inline preset name input */}
                {savingPresetForId === ds.id && (
                  <div className="flex gap-1 mt-1 ml-6">
                    <input
                      type="text"
                      value={presetName}
                      onChange={(e) => setPresetName(e.target.value)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter") handleSavePresetForRepo(ds);
                        if (e.key === "Escape") setSavingPresetForId(null);
                      }}
                      placeholder="Preset name..."
                      className="flex-1 px-2 py-1 text-xs bg-gray-800 border border-gray-600 rounded text-gray-200 placeholder-gray-500 focus:border-emerald-500 focus:outline-none"
                      autoFocus
                    />
                    <button
                      onClick={() => handleSavePresetForRepo(ds)}
                      className="px-2 py-1 text-xs bg-emerald-600 hover:bg-emerald-500 rounded text-white"
                    >
                      Save
                    </button>
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Preset edit panel */}
      {editingDatasetId &&
        (() => {
          const editDs = datasets.find((d) => d.id === editingDatasetId);
          if (!editDs?.presetId) return null;
          return (
            <div className="p-3 border-t border-gray-700 space-y-2">
              <div className="text-[10px] text-gray-500 uppercase font-semibold tracking-wider">
                Edit Preset
              </div>
              <input
                type="text"
                value={editPresetName}
                onChange={(e) => setEditPresetName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter" && editPresetName.trim()) {
                    handleUpdatePreset(editDs.presetId!, editDs.id);
                  }
                  if (e.key === "Escape") setEditingDatasetId(null);
                }}
                placeholder="Preset name..."
                className="w-full px-2 py-1 text-xs bg-gray-800 border border-gray-600 rounded text-gray-200 placeholder-gray-500 focus:border-emerald-500 focus:outline-none"
                autoFocus
              />
              <div className="flex gap-2">
                <button
                  onClick={() => handleUpdatePreset(editDs.presetId!, editDs.id)}
                  disabled={!editPresetName.trim()}
                  className="flex-1 px-2 py-1 text-xs bg-emerald-600 hover:bg-emerald-500 disabled:bg-gray-700 disabled:text-gray-500 rounded text-white transition-colors"
                >
                  Save
                </button>
                <button
                  onClick={() => handleDeletePreset(editDs.presetId!, editDs.id)}
                  className="px-2 py-1 text-xs bg-red-900 hover:bg-red-800 rounded text-red-300 transition-colors"
                >
                  Delete
                </button>
                <button
                  onClick={() => setEditingDatasetId(null)}
                  className="px-2 py-1 text-xs bg-gray-700 hover:bg-gray-600 rounded text-gray-300 transition-colors"
                >
                  Cancel
                </button>
              </div>
            </div>
          );
        })()}

      {/* Add Dataset Form */}
      <div className="p-3 border-t border-gray-700">
        {showAddForm ? (
          <div className="space-y-2">
            <input
              className="w-full bg-gray-800 text-sm text-gray-200 rounded px-2 py-1.5 border border-gray-600 focus:border-emerald-500 outline-none"
              placeholder="org/repo-name"
              value={repo}
              onChange={(e) => setRepo(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleAdd()}
              autoFocus
            />
            <div className="flex gap-2">
              <input
                className="flex-1 bg-gray-800 text-xs text-gray-200 rounded px-2 py-1 border border-gray-600 focus:border-emerald-500 outline-none"
                placeholder="Config"
                value={config}
                onChange={(e) => setConfig(e.target.value)}
              />
              <input
                className="w-16 bg-gray-800 text-xs text-gray-200 rounded px-2 py-1 border border-gray-600 focus:border-emerald-500 outline-none"
                placeholder="Split"
                value={split}
                onChange={(e) => setSplit(e.target.value)}
              />
            </div>
            <div className="flex gap-2">
              <button
                className="flex-1 px-2 py-1.5 text-sm bg-emerald-600 hover:bg-emerald-500 disabled:bg-gray-700 disabled:text-gray-500 rounded text-white transition-colors"
                onClick={handleAdd}
                disabled={!repo.trim() || !!loading[repo.trim()]}
              >
                {loading[repo.trim()] ? "Loading..." : "Load"}
              </button>
              <button
                className="px-3 py-1.5 text-sm bg-gray-700 hover:bg-gray-600 rounded text-gray-300 transition-colors"
                onClick={() => setShowAddForm(false)}
              >
                Cancel
              </button>
            </div>
          </div>
        ) : (
          <button
            className="w-full px-3 py-2 text-sm bg-emerald-600 hover:bg-emerald-500 rounded text-white font-medium transition-colors"
            onClick={() => {
              setEditingDatasetId(null);
              setShowAddForm(true);
              setRepo("");
              setConfig("rlm_call_traces");
              setSplit("train");
            }}
          >
            + Add Dataset
          </button>
        )}
      </div>
    </div>
  );
}
