import React, { useState, useEffect } from "react";
import {
  FileText,
  Globe,
  Search,
  Monitor,
  Wrench,
  Terminal,
  Image,
  ChevronDown,
  Code,
  ArrowDownToLine,
  MousePointer2,
  History,
} from "lucide-react";

interface ToolCategoryConfig {
  enabled: boolean;
  priority: "high" | "normal" | "low";
  description?: string;
}

interface BuiltinToolsSettingsData {
  categories: {
    code: ToolCategoryConfig;
    webfetch: ToolCategoryConfig;
    browser: ToolCategoryConfig;
    search: ToolCategoryConfig;
    system: ToolCategoryConfig;
    file: ToolCategoryConfig;
    skill: ToolCategoryConfig;
    shell: ToolCategoryConfig;
    image: ToolCategoryConfig;
    chronicle: ToolCategoryConfig;
    computer_use: ToolCategoryConfig;
  };
  toolOverrides: Record<string, { enabled: boolean; priority?: "high" | "normal" | "low" }>;
  toolTimeouts: Record<string, number>;
  toolAutoApprove: Record<string, boolean>;
  runCommandApprovalMode: "per_command" | "single_bundle";
  codexRuntimeMode: "native" | "acpx";
  computerUseAutomation: {
    browserAutomationMode: "background" | "visible" | "ask";
    nativeComputerUseMode: "background_first" | "ask_visible" | "visible";
  };
  version: string;
}

type CategoryKey = keyof BuiltinToolsSettingsData["categories"];

const IC = { size: 18, strokeWidth: 1.5 } as const;
const CATEGORY_INFO: Record<
  CategoryKey,
  { name: string; icon: React.ReactNode; description: string }
> = {
  code: {
    name: "Code & Search in Repo",
    icon: <Code {...IC} />,
    description: "Glob, grep, edit, and code navigation tools",
  },
  webfetch: {
    name: "Integrations & Web Fetch",
    icon: <ArrowDownToLine {...IC} />,
    description: "Lightweight HTTP and connector actions (Drive, Gmail, calendar, etc.)",
  },
  file: {
    name: "File Operations",
    icon: <FileText {...IC} />,
    description: "Read, write, copy, delete files and directories",
  },
  browser: {
    name: "Browser Automation",
    icon: <Globe {...IC} />,
    description: "Navigate websites, click, fill forms, take screenshots",
  },
  search: {
    name: "Web Search",
    icon: <Search {...IC} />,
    description: "Search the web using configured providers (Brave, Tavily, etc.)",
  },
  system: {
    name: "System Tools",
    icon: <Monitor {...IC} />,
    description: "Clipboard, screenshots, open apps and URLs",
  },
  skill: {
    name: "Document Skills",
    icon: <Wrench {...IC} />,
    description: "Create spreadsheets, documents, presentations",
  },
  shell: {
    name: "Shell Commands",
    icon: <Terminal {...IC} />,
    description: "Execute terminal commands (requires approval)",
  },
  image: {
    name: "Image Generation",
    icon: <Image {...IC} />,
    description: "Generate images using AI (requires Gemini API)",
  },
  chronicle: {
    name: "Chronicle",
    icon: <History {...IC} />,
    description: "Passive local screen-context disambiguation and recall",
  },
  computer_use: {
    name: "Computer Use (macOS)",
    icon: <MousePointer2 {...IC} />,
    description: "Native desktop control — mouse, keyboard, screenshots (last resort vs browser/shell)",
  },
};

/** Stable order for settings UI (matches backend category keys). */
const CATEGORY_ORDER: CategoryKey[] = [
  "code",
  "webfetch",
  "browser",
  "search",
  "system",
  "file",
  "skill",
  "shell",
  "image",
  "chronicle",
  "computer_use",
];

const PRIORITY_OPTIONS: Array<{
  value: "high" | "normal" | "low";
  label: string;
  description: string;
}> = [
  { value: "high", label: "High", description: "Prefer these tools over others" },
  { value: "normal", label: "Normal", description: "Default priority" },
  { value: "low", label: "Low", description: "Use only when specifically needed" },
];

export function BuiltinToolsSettings() {
  const [settings, setSettings] = useState<BuiltinToolsSettingsData | null>(null);
  const [categories, setCategories] = useState<Record<string, string[]>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [expandedCategory, setExpandedCategory] = useState<string | null>(null);

  useEffect(() => {
    loadSettings();
  }, []);

  const loadSettings = async () => {
    try {
      setLoading(true);
      const [loadedSettings, loadedCategories] = await Promise.all([
        window.electronAPI.getBuiltinToolsSettings(),
        window.electronAPI.getBuiltinToolsCategories(),
      ]);
      const mergedCategories = { ...loadedSettings.categories } as BuiltinToolsSettingsData["categories"];
      for (const key of CATEGORY_ORDER) {
        if (!mergedCategories[key]) {
          mergedCategories[key] = {
            enabled: true,
            priority: key === "code" || key === "webfetch" ? "high" : "normal",
            description: CATEGORY_INFO[key].description,
          };
        }
      }
      setSettings({
        ...loadedSettings,
        categories: mergedCategories,
        computerUseAutomation: {
          browserAutomationMode:
            loadedSettings.computerUseAutomation?.browserAutomationMode || "background",
          nativeComputerUseMode:
            loadedSettings.computerUseAutomation?.nativeComputerUseMode || "background_first",
        },
      });
      setCategories(loadedCategories);
    } catch (error) {
      console.error("Failed to load built-in tools settings:", error);
    } finally {
      setLoading(false);
    }
  };

  const handleCategoryToggle = async (category: CategoryKey, enabled: boolean) => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      categories: {
        ...settings.categories,
        [category]: {
          ...settings.categories[category],
          enabled,
        },
      },
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleCategoryPriority = async (
    category: CategoryKey,
    priority: "high" | "normal" | "low",
  ) => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      categories: {
        ...settings.categories,
        [category]: {
          ...settings.categories[category],
          priority,
        },
      },
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleRunCommandAutoApprove = async (enabled: boolean) => {
    if (!settings) return;

    const nextAutoApprove = { ...settings.toolAutoApprove };
    if (enabled) {
      nextAutoApprove.run_command = true;
    } else {
      delete nextAutoApprove.run_command;
    }

    const newSettings = {
      ...settings,
      toolAutoApprove: nextAutoApprove,
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleRunCommandApprovalMode = async (mode: "per_command" | "single_bundle") => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      runCommandApprovalMode: mode,
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleRunCommandTimeout = async (value: string) => {
    if (!settings) return;

    const parsed = Number(value);
    const nextTimeouts = { ...settings.toolTimeouts };

    if (!value || !Number.isFinite(parsed) || parsed <= 0) {
      delete nextTimeouts.run_command;
    } else {
      nextTimeouts.run_command = Math.round(parsed);
    }

    const newSettings = {
      ...settings,
      toolTimeouts: nextTimeouts,
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleCodexRuntimeMode = async (mode: "native" | "acpx") => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      codexRuntimeMode: mode,
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleBrowserAutomationMode = async (mode: "background" | "visible" | "ask") => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      computerUseAutomation: {
        ...settings.computerUseAutomation,
        browserAutomationMode: mode,
      },
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleNativeComputerUseMode = async (
    mode: "background_first" | "ask_visible" | "visible",
  ) => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      computerUseAutomation: {
        ...settings.computerUseAutomation,
        nativeComputerUseMode: mode,
      },
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  const handleToolToggle = async (tool: string, enabled: boolean) => {
    if (!settings) return;

    const newSettings = {
      ...settings,
      toolOverrides: {
        ...settings.toolOverrides,
        [tool]: {
          ...settings.toolOverrides?.[tool],
          enabled,
        },
      },
    };

    setSettings(newSettings);

    try {
      setSaving(true);
      await window.electronAPI.saveBuiltinToolsSettings(newSettings);
    } catch (error) {
      console.error("Failed to save settings:", error);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return <div className="settings-loading">Loading settings...</div>;
  }

  if (!settings) {
    return <div className="settings-error">Failed to load settings</div>;
  }

  return (
    <div className="builtin-tools-settings">
      <div className="settings-section">
        <h3>Built-in Tools</h3>
        <p className="settings-description">
          Control which built-in tools are available to the agent. Disabling a category will prevent
          the agent from using those tools. Setting a lower priority makes the agent less likely to
          choose those tools when alternatives exist.
        </p>
      </div>

      <div className="builtin-tools-categories">
        {CATEGORY_ORDER.map((category) => {
          const info = CATEGORY_INFO[category];
          const config = settings.categories[category];
          const tools = categories[category] || [];
          const runCommandAutoApprove =
            category === "shell" ? Boolean(settings.toolAutoApprove?.run_command) : false;
          const runCommandApprovalMode =
            category === "shell" ? settings.runCommandApprovalMode : "per_command";
          const runCommandTimeout =
            category === "shell" ? (settings.toolTimeouts?.run_command ?? "") : "";
          const browserAutomationMode =
            settings.computerUseAutomation?.browserAutomationMode || "background";
          const nativeComputerUseMode =
            settings.computerUseAutomation?.nativeComputerUseMode || "background_first";

          return (
            <div
              key={category}
              className={`builtin-tool-category ${!config.enabled ? "disabled" : ""}`}
            >
              <div className="builtin-tool-category-header">
                <div className="builtin-tool-category-info">
                  <div className="builtin-tool-category-icon">{info.icon}</div>
                  <div className="builtin-tool-category-text">
                    <div className="builtin-tool-category-name">{info.name}</div>
                    <div className="builtin-tool-category-desc">{info.description}</div>
                  </div>
                </div>

                <div className="builtin-tool-category-controls">
                  <select
                    className="builtin-tool-priority-select"
                    value={config.priority}
                    onChange={(e) =>
                      handleCategoryPriority(category, e.target.value as "high" | "normal" | "low")
                    }
                    disabled={!config.enabled}
                    title="Tool priority"
                  >
                    {PRIORITY_OPTIONS.map((opt) => (
                      <option key={opt.value} value={opt.value}>
                        {opt.label}
                      </option>
                    ))}
                  </select>

                  <label className="builtin-tool-toggle">
                    <input
                      type="checkbox"
                      checked={config.enabled}
                      onChange={(e) => handleCategoryToggle(category, e.target.checked)}
                    />
                    <span className="builtin-tool-toggle-slider"></span>
                  </label>

                  <button
                    className="builtin-tool-expand-btn"
                    onClick={() =>
                      setExpandedCategory(expandedCategory === category ? null : category)
                    }
                    title="Show tools in this category"
                  >
                    <ChevronDown
                      size={16}
                      strokeWidth={2}
                      style={{
                        transform: expandedCategory === category ? "rotate(180deg)" : "none",
                        transition: "transform 0.2s",
                      }}
                    />
                  </button>
                </div>
              </div>

              {category === "shell" && expandedCategory === category && (
                <div className="builtin-tool-advanced">
                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">Approval mode</div>
                      <div className="builtin-tool-advanced-hint">
                        Single bundle is the lower-noise option. It asks once and reuses approval
                        for safe commands in this task.
                      </div>
                    </div>
                    <select
                      className="builtin-tool-mode-select"
                      value={runCommandApprovalMode}
                      onChange={(e) =>
                        handleRunCommandApprovalMode(
                          e.target.value as "per_command" | "single_bundle",
                        )
                      }
                      disabled={!config.enabled}
                    >
                      <option value="per_command">Per command</option>
                      <option value="single_bundle">Single approval bundle (Recommended)</option>
                    </select>
                  </div>

                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">Codex runtime</div>
                      <div className="builtin-tool-advanced-hint">
                        Native uses CoWork&apos;s current shell path. ACP routes explicit Codex child
                        tasks through acpx with structured session output.
                      </div>
                    </div>
                    <select
                      className="builtin-tool-mode-select"
                      value={settings.codexRuntimeMode}
                      onChange={(e) =>
                        handleCodexRuntimeMode(e.target.value as "native" | "acpx")
                      }
                      disabled={!config.enabled}
                    >
                      <option value="native">Native</option>
                      <option value="acpx">ACP via acpx</option>
                    </select>
                  </div>

                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">Auto-approve safe commands</div>
                      <div className="builtin-tool-advanced-hint">
                        Skips approval prompts for non-destructive commands.
                      </div>
                    </div>
                    <label className="builtin-tool-toggle">
                      <input
                        type="checkbox"
                        checked={runCommandAutoApprove}
                        onChange={(e) => handleRunCommandAutoApprove(e.target.checked)}
                        disabled={!config.enabled}
                      />
                      <span className="builtin-tool-toggle-slider"></span>
                    </label>
                  </div>

                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">run_command timeout (ms)</div>
                      <div className="builtin-tool-advanced-hint">
                        Used when the command doesn't set its own timeout.
                      </div>
                    </div>
                    <input
                      className="builtin-tool-timeout-input"
                      type="number"
                      min={1000}
                      step={1000}
                      value={runCommandTimeout}
                      onChange={(e) => handleRunCommandTimeout(e.target.value)}
                      disabled={!config.enabled}
                      placeholder="30000"
                    />
                  </div>
                </div>
              )}

              {category === "computer_use" && expandedCategory === category && (
                <div className="builtin-tool-advanced">
                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">Browser automation</div>
                      <div className="builtin-tool-advanced-hint">
                        Background uses headless browser control unless a task already has a visible
                        browser session.
                      </div>
                    </div>
                    <select
                      className="builtin-tool-mode-select"
                      value={browserAutomationMode}
                      onChange={(e) =>
                        handleBrowserAutomationMode(
                          e.target.value as "background" | "visible" | "ask",
                        )
                      }
                      disabled={!config.enabled}
                    >
                      <option value="background">Background (Recommended)</option>
                      <option value="visible">Visible workbench</option>
                      <option value="ask">Ask</option>
                    </select>
                  </div>

                  <div className="builtin-tool-advanced-row">
                    <div className="builtin-tool-advanced-text">
                      <div className="builtin-tool-advanced-label">Native desktop control</div>
                      <div className="builtin-tool-advanced-hint">
                        Background first tries Accessibility actions before visible Mac control.
                      </div>
                    </div>
                    <select
                      className="builtin-tool-mode-select"
                      value={nativeComputerUseMode}
                      onChange={(e) =>
                        handleNativeComputerUseMode(
                          e.target.value as "background_first" | "ask_visible" | "visible",
                        )
                      }
                      disabled={!config.enabled}
                    >
                      <option value="background_first">Background first (Recommended)</option>
                      <option value="ask_visible">Ask before visible control</option>
                      <option value="visible">Visible control</option>
                    </select>
                  </div>
                </div>
              )}

              {expandedCategory === category && tools.length > 0 && (
                <div className="builtin-tool-list">
                  {tools.map((tool) => {
                    const toolOverride = settings.toolOverrides?.[tool];
                    const toolEnabled = toolOverride
                      ? toolOverride.enabled
                      : config.enabled;

                    return (
                      <div key={tool} className="builtin-tool-item">
                        <code>{tool}</code>
                        <label className="builtin-tool-toggle">
                          <input
                            type="checkbox"
                            checked={toolEnabled}
                            onChange={(e) => handleToolToggle(tool, e.target.checked)}
                            disabled={!config.enabled || saving}
                          />
                          <span className="builtin-tool-toggle-slider"></span>
                        </label>
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          );
        })}
      </div>

      <div className="settings-section">
        <h3>About Tool Priority</h3>
        <p className="settings-description">
          Tool priority affects which tools the agent chooses when multiple options could work:
        </p>
        <ul className="settings-list">
          <li>
            <strong>High:</strong> The agent will prefer these tools over alternatives
          </li>
          <li>
            <strong>Normal:</strong> Default behavior - tools are considered equally
          </li>
          <li>
            <strong>Low:</strong> The agent will only use these if specifically needed or no
            alternatives exist
          </li>
        </ul>
        <p className="settings-hint">
          For example, if you have MCP servers that provide similar functionality to built-in tools,
          you can set the built-in tools to "Low" priority so the agent prefers the MCP versions.
        </p>
      </div>

      {saving && <div className="builtin-tools-saving">Saving...</div>}
    </div>
  );
}
