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

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

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

export const InstanceList = ({ projectId, repoId, projectName, repoName, toolTypes }: InstanceListProps) => {
  const navigate = useNavigate();
  const [instances, setInstances] = useState<ToolInstance[]>([]);
  const [loading, setLoading] = useState(false);
  const [showCreate, setShowCreate] = useState(false);
  const [error, setError] = useState<string | null>(null);
  
  // Stop confirmation
  const [stopConfirmId, setStopConfirmId] = useState<string | null>(null);
  
  // Health check state
  const [healthStatus, setHealthStatus] = useState<Record<string, { healthy: boolean; lastCheck: number }>>({});

  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]);

  // Health check polling
  useEffect(() => {
    const runningInstances = instances.filter(i => i.status === "running" && i.url?.startsWith("http"));
    if (runningInstances.length === 0) return;

    const checkHealth = async () => {
      for (const instance of runningInstances) {
        try {
          const health = await checkInstanceHealth(projectId, repoId, instance.id);
          setHealthStatus(prev => ({
            ...prev,
            [instance.id]: { healthy: health.healthy, lastCheck: Date.now() }
          }));
        } catch {
          setHealthStatus(prev => ({
            ...prev,
            [instance.id]: { healthy: false, lastCheck: Date.now() }
          }));
        }
      }
    };

    // Check immediately
    void checkHealth();
    
    // Then every 30 seconds
    const interval = setInterval(() => void checkHealth(), 30000);
    return () => clearInterval(interval);
  }, [instances, projectId, repoId]);

  const handleCreateSuccess = async () => {
    setShowCreate(false);
    await loadInstances();
  };

  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);
      setStopConfirmId(null);
      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);
      // Update state immediately instead of reloading
      setInstances(prev => prev.filter(i => i.id !== instanceId));
    } catch {
      setError("Failed to delete instance");
    }
  };

  const handleRecreateTunnel = async (instanceId: string) => {
    try {
      await recreateInstanceTunnel(projectId, repoId, instanceId);
      await loadInstances();
    } catch {
      setError("Failed to recreate tunnel");
    }
  };

  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)";
    }
  };

  const isTunnelUnhealthy = (instance: ToolInstance) => {
    if (instance.status !== "running") return false;
    if (!instance.url?.startsWith("http")) return false;
    const health = healthStatus[instance.id];
    if (!health) return false;
    return !health.healthy;
  };

  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}
                  {isTunnelUnhealthy(instance) && (
                    <span className="error-badge" title="Tunnel unreachable">
                      <Icon name="warning" size="sm" />
                      tunnel error
                    </span>
                  )}
                </div>
              </div>
              <div className="instance-actions">
                {instance.status === "running" && instance.url && instance.tool_type_interfaces.includes("web") && (
                  <>
                    <a
                      href={instance.url.startsWith("http") ? instance.url : `${API_BASE_URL}${instance.url}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="secondary-button small"
                    >
                      <Icon name="external" size="sm" />
                      Open
                    </a>
                    {isTunnelUnhealthy(instance) && (
                      <button
                        className="secondary-button small warning"
                        onClick={() => void handleRecreateTunnel(instance.id)}
                        type="button"
                        title="Recreate tunnel"
                      >
                        <Icon name="refresh" size="sm" />
                        Fix Tunnel
                      </button>
                    )}
                  </>
                )}
                {instance.status === "running" && instance.tool_type_interfaces.includes("terminal") && (
                  <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" && (
                  <>
                    {stopConfirmId === instance.id ? (
                      <div className="inline-confirm">
                        <span>Stop?</span>
                        <button
                          className="ghost-button small danger-text"
                          onClick={() => void handleStop(instance.id)}
                          type="button"
                        >
                          Yes
                        </button>
                        <button
                          className="ghost-button small"
                          onClick={() => setStopConfirmId(null)}
                          type="button"
                        >
                          No
                        </button>
                      </div>
                    ) : (
                      <button
                        className="ghost-button small"
                        onClick={() => setStopConfirmId(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>
            <CreateSessionForm
              projects={[]}
              repositories={[]}
              toolTypes={toolTypes}
              fixedProjectId={projectId}
              fixedRepoId={repoId}
              projectName={projectName}
              repoName={repoName}
              onSuccess={handleCreateSuccess}
              onCancel={() => setShowCreate(false)}
              submitLabel="Launch"
            />
          </div>
        </div>
      )}
    </div>
  );
};
