import { useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Icon } from "./icon";
import type { ToolInstance } from "../api/sessions";
import {
  createInstance,
  deleteInstance,
  listInstances,
  restartInstance,
  startInstance,
  stopInstance,
} from "../api/sessions";
import type { ToolType } from "../api/tool_types";

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8000";

interface InstanceListProps {
  projectId: string;
  repoId: string;
  toolTypes: ToolType[];
}

export const InstanceList = ({ projectId, repoId, toolTypes }: InstanceListProps) => {
  const navigate = useNavigate();
  const [instances, setInstances] = useState<ToolInstance[]>([]);
  const [loading, setLoading] = useState(false);
  const [showCreate, setShowCreate] = useState(false);
  const [selectedToolType, setSelectedToolType] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [error, setError] = useState<string | null>(null);

  const loadInstances = useCallback(async () => {
    setLoading(true);
    try {
      const data = await listInstances(projectId, repoId);
      setInstances(data);
    } catch {
      setError("Failed to load instances");
    } finally {
      setLoading(false);
    }
  }, [projectId, repoId]);

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

  const handleCreate = async () => {
    if (!selectedToolType) return;
    setError(null);
    try {
      await createInstance(projectId, repoId, selectedToolType, displayName || undefined);
      setShowCreate(false);
      setSelectedToolType("");
      setDisplayName("");
      await loadInstances();
    } catch {
      setError("Failed to create instance");
    }
  };

  const handleStart = async (instanceId: string) => {
    try {
      await startInstance(projectId, repoId, instanceId);
      await loadInstances();
    } catch {
      setError("Failed to start instance");
    }
  };

  const handleStop = async (instanceId: string) => {
    try {
      await stopInstance(projectId, repoId, instanceId);
      await loadInstances();
    } catch {
      setError("Failed to stop instance");
    }
  };

  const handleRestart = async (instanceId: string) => {
    try {
      await restartInstance(projectId, repoId, instanceId);
      await loadInstances();
    } catch {
      setError("Failed to restart instance");
    }
  };

  const handleDelete = async (instanceId: string) => {
    if (!confirm("Are you sure you want to delete this instance?")) return;
    try {
      await deleteInstance(projectId, repoId, instanceId);
      await loadInstances();
    } catch {
      setError("Failed to delete instance");
    }
  };

  const getStatusColor = (status: string) => {
    switch (status) {
      case "running":
        return "var(--success)";
      case "error":
        return "var(--danger)";
      case "pending":
      case "building":
        return "var(--warning)";
      default:
        return "var(--muted)";
    }
  };

  return (
    <div className="instance-list">
      <div className="instance-list-header">
        <h3>Tool Instances</h3>
        <button
          className="secondary-button small"
          onClick={() => setShowCreate(true)}
          type="button"
        >
          <Icon name="add" size="sm" />
          Launch Tool
        </button>
      </div>

      {error && (
        <div className="error-message">{error}</div>
      )}

      {loading ? (
        <p className="muted">Loading instances...</p>
      ) : instances.length === 0 ? (
        <p className="muted">No instances yet. Launch a tool to get started.</p>
      ) : (
        <div className="instance-grid">
          {instances.map((instance) => (
            <div key={instance.id} className="instance-card">
              <div className="instance-info">
                <div className="instance-name">{instance.display_name}</div>
                <div className="instance-meta">
                  <span
                    className="status-dot"
                    style={{ backgroundColor: getStatusColor(instance.status) }}
                  />
                  {instance.status}
                </div>
              </div>
              <div className="instance-actions">
                {instance.status === "running" && instance.url && (
                  <a
                    href={`${API_BASE_URL}${instance.url}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="secondary-button small"
                  >
                    <Icon name="external" size="sm" />
                    Open
                  </a>
                )}
                {instance.status === "running" && (
                  <button
                    className="secondary-button small"
                    onClick={() => navigate(`/instances/${instance.id}/terminal`)}
                    type="button"
                  >
                    <Icon name="terminal" size="sm" />
                    Terminal
                  </button>
                )}
                {instance.status !== "running" && (
                  <button
                    className="secondary-button small"
                    onClick={() => void handleStart(instance.id)}
                    type="button"
                  >
                    <Icon name="play" size="sm" />
                    Start
                  </button>
                )}
                {instance.status === "running" && (
                  <>
                    <button
                      className="ghost-button small"
                      onClick={() => void handleStop(instance.id)}
                      type="button"
                    >
                      <Icon name="stop" size="sm" />
                    </button>
                    <button
                      className="ghost-button small"
                      onClick={() => void handleRestart(instance.id)}
                      type="button"
                    >
                      <Icon name="refresh" size="sm" />
                    </button>
                  </>
                )}
                <button
                  className="ghost-button small danger-text"
                  onClick={() => void handleDelete(instance.id)}
                  type="button"
                >
                  <Icon name="delete" size="sm" />
                </button>
              </div>
            </div>
          ))}
        </div>
      )}

      {showCreate && (
        <div className="dialog-overlay" role="dialog" aria-modal="true">
          <div className="dialog">
            <h2>Launch Tool</h2>
            <div className="stack">
              <label className="form-field">
                Tool Type
                <select
                  value={selectedToolType}
                  onChange={(e) => setSelectedToolType(e.target.value)}
                >
                  <option value="">Select a tool...</option>
                  {toolTypes.map((tool) => (
                    <option key={tool.id} value={tool.id}>
                      {tool.display_name}
                    </option>
                  ))}
                </select>
              </label>
              <label className="form-field">
                Display Name (optional)
                <input
                  type="text"
                  value={displayName}
                  onChange={(e) => setDisplayName(e.target.value)}
                  placeholder="My Development Environment"
                />
              </label>
              <div className="dialog-actions">
                <button
                  className="secondary-button"
                  onClick={() => setShowCreate(false)}
                  type="button"
                >
                  Cancel
                </button>
                <button
                  className="primary-button"
                  onClick={() => void handleCreate()}
                  disabled={!selectedToolType}
                  type="button"
                >
                  Launch
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};
