import { useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

import { Icon } from "../components/icon";
import type { ToolType } from "../types/tool-type";
import type { ToolConfig } from "../types/tool-config";
import { listToolTypes } from "../api/tool_types";
import {
  createToolConfig,
  deleteToolConfig,
  listToolConfigs,
  updateToolConfig,
} from "../api/tool_configs";

type ConfigStatus = "loading" | "ready" | "error";

export const ToolConfigsPage = () => {
  const navigate = useNavigate();
  const [status, setStatus] = useState<ConfigStatus>("loading");
  const [toolTypes, setToolTypes] = useState<ToolType[]>([]);
  const [configs, setConfigs] = useState<ToolConfig[]>([]);
  const [selectedToolType, setSelectedToolType] = useState<string>("");
  const [showForm, setShowForm] = useState(false);
  const [editingConfig, setEditingConfig] = useState<ToolConfig | null>(null);
  const [formData, setFormData] = useState({
    key: "",
    value: "",
    config_type: "env",
    file_path: "",
  });
  const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle");

  const loadData = useCallback(async () => {
    try {
      const [typesData, configsData] = await Promise.all([
        listToolTypes(),
        listToolConfigs(),
      ]);
      setToolTypes(typesData);
      setConfigs(configsData);
      if (typesData.length > 0 && !selectedToolType) {
        setSelectedToolType(typesData[0].id);
      }
      setStatus("ready");
    } catch {
      setStatus("error");
    }
  }, [selectedToolType]);

  useEffect(() => {
    void loadData();
  }, [loadData]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaveStatus("saving");
    try {
      const data = {
        tool_type_id: selectedToolType,
        key: formData.key,
        value: formData.value,
        config_type: formData.config_type,
        file_path: formData.config_type === "file" ? formData.file_path : undefined,
      };

      if (editingConfig) {
        await updateToolConfig(editingConfig.id, data);
      } else {
        await createToolConfig(data);
      }

      setSaveStatus("saved");
      setShowForm(false);
      setEditingConfig(null);
      setFormData({ key: "", value: "", config_type: "env", file_path: "" });
      await loadData();
    } catch {
      setSaveStatus("error");
    }
  };

  const handleEdit = (config: ToolConfig) => {
    setEditingConfig(config);
    setFormData({
      key: config.key,
      value: config.value,
      config_type: config.config_type,
      file_path: config.file_path || "",
    });
    setSelectedToolType(config.tool_type_id);
    setShowForm(true);
  };

  const handleDelete = async (id: string) => {
    if (!window.confirm("Delete this config?")) return;
    try {
      await deleteToolConfig(id);
      await loadData();
    } catch {
      // Error handled by UI state
    }
  };

  const filteredConfigs = configs.filter(
    (c) => c.tool_type_id === selectedToolType
  );

  const selectedTool = toolTypes.find((t) => t.id === selectedToolType);

  if (status === "loading") {
    return (
      <section className="stack">
        <div className="page-header">
          <h1>Tool Configurations</h1>
        </div>
        <p className="muted">Loading...</p>
      </section>
    );
  }

  if (status === "error") {
    return (
      <section className="stack">
        <div className="page-header">
          <h1>Tool Configurations</h1>
        </div>
        <div className="card stack">
          <p>Failed to load configurations</p>
          <button className="secondary-button" onClick={() => void loadData()} type="button">
            <Icon name="refresh" size="sm" />
            Retry
          </button>
        </div>
      </section>
    );
  }

  return (
    <section className="stack">
      <div className="page-header">
        <div>
          <p className="eyebrow">Settings</p>
          <h1>Tool Configurations</h1>
        </div>
        <button className="secondary-button" type="button" onClick={() => navigate("/settings")}>
          Back to settings
        </button>
        <p className="muted">
          Manage environment variables and configuration files for your tools
        </p>
      </div>

      {/* Tool Type Selector */}
      <div className="card">
        <label htmlFor="tool-type-select">Select Tool</label>
        <select
          id="tool-type-select"
          value={selectedToolType}
          onChange={(e) => {
            setSelectedToolType(e.target.value);
            setShowForm(false);
            setEditingConfig(null);
          }}
          className="form-input"
        >
          {toolTypes.map((tool) => (
            <option key={tool.id} value={tool.id}>
              {tool.display_name}
            </option>
          ))}
        </select>
        {selectedTool && (
          <p className="muted" style={{ marginTop: "0.5rem" }}>
            Category: {selectedTool.category} · Interfaces: {selectedTool.interfaces?.join(", ")}
          </p>
        )}
      </div>

      {/* Config List */}
      <div className="card stack">
        <div className="row" style={{ justifyContent: "space-between", alignItems: "center" }}>
          <h2>Configuration Variables</h2>
          <button
            className="primary-button small"
            onClick={() => {
              setShowForm(true);
              setEditingConfig(null);
              setFormData({ key: "", value: "", config_type: "env", file_path: "" });
            }}
            type="button"
          >
            <Icon name="add" size="sm" />
            Add Config
          </button>
        </div>

        {filteredConfigs.length === 0 ? (
          <p className="muted">No configurations for this tool yet.</p>
        ) : (
          <div className="stack" style={{ gap: "0.5rem" }}>
            {filteredConfigs.map((config) => (
              <div
                key={config.id}
                className="card"
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  padding: "0.75rem 1rem",
                }}
              >
                <div>
                  <div className="row" style={{ gap: "0.5rem", alignItems: "center" }}>
                    <code style={{ fontWeight: 600 }}>{config.key}</code>
                    <span
                      className="badge"
                      style={{
                        fontSize: "0.7rem",
                        textTransform: "uppercase",
                        background: config.config_type === "env" ? "var(--color-info)" : "var(--color-warning)",
                        color: "white",
                        padding: "0.125rem 0.5rem",
                        borderRadius: "9999px",
                      }}
                    >
                      {config.config_type}
                    </span>
                  </div>
                  <p className="muted" style={{ marginTop: "0.25rem", fontSize: "0.875rem" }}>
                    {config.config_type === "file" && config.file_path
                      ? `File: ${config.file_path}`
                      : "Environment variable"}
                  </p>
                </div>
                <div className="row" style={{ gap: "0.5rem" }}>
                  <button
                    className="ghost-button small"
                    onClick={() => handleEdit(config)}
                    type="button"
                  >
                    <Icon name="edit" size="sm" />
                  </button>
                  <button
                    className="ghost-button small"
                    onClick={() => void handleDelete(config.id)}
                    type="button"
                  >
                    <Icon name="delete" size="sm" />
                  </button>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Add/Edit Form */}
      {showForm && (
        <div className="card stack">
          <h3>{editingConfig ? "Edit Config" : "Add Config"}</h3>
          <form onSubmit={handleSubmit} className="stack">
            <div>
              <label htmlFor="config-key">Key</label>
              <input
                id="config-key"
                type="text"
                value={formData.key}
                onChange={(e) => setFormData({ ...formData, key: e.target.value })}
                placeholder="e.g., OPENAI_API_KEY"
                className="form-input"
                required
              />
            </div>

            <div>
              <label htmlFor="config-type">Type</label>
              <select
                id="config-type"
                value={formData.config_type}
                onChange={(e) =>
                  setFormData({ ...formData, config_type: e.target.value })
                }
                className="form-input"
              >
                <option value="env">Environment Variable</option>
                <option value="file">Configuration File</option>
              </select>
            </div>

            {formData.config_type === "file" && (
              <div>
                <label htmlFor="config-file-path">File Path</label>
                <input
                  id="config-file-path"
                  type="text"
                  value={formData.file_path}
                  onChange={(e) =>
                    setFormData({ ...formData, file_path: e.target.value })
                  }
                  placeholder="e.g., /app/config.json"
                  className="form-input"
                  required
                />
              </div>
            )}

            <div>
              <label htmlFor="config-value">Value</label>
              <textarea
                id="config-value"
                value={formData.value}
                onChange={(e) => setFormData({ ...formData, value: e.target.value })}
                placeholder={
                  formData.config_type === "env"
                    ? "Enter value..."
                    : "Enter file contents..."
                }
                className="form-input"
                rows={formData.config_type === "file" ? 8 : 2}
                required
              />
            </div>

            <div className="row" style={{ gap: "0.5rem", justifyContent: "flex-end" }}>
              <button
                type="button"
                className="secondary-button"
                onClick={() => {
                  setShowForm(false);
                  setEditingConfig(null);
                }}
              >
                Cancel
              </button>
              <button type="submit" className="primary-button">
                {editingConfig ? "Update" : "Add"} Config
              </button>
            </div>

            {saveStatus === "saved" && (
              <p className="text-success" style={{ textAlign: "right" }}>
                Saved successfully!
              </p>
            )}
            {saveStatus === "error" && (
              <p className="text-error" style={{ textAlign: "right" }}>
                Failed to save. Please try again.
              </p>
            )}
          </form>
        </div>
      )}
    </section>
  );
};
