import React, { useEffect, useState } from "react";
import { fetchInstanceList, sendStartInstanceRequest, sendStopInstanceRequest, sendCreateInstanceRequest } from "../api";
import type { Instance } from "../types";
import InstanceDetail from "./InstanceDetail";


export default function InstancesTable() {
  const [instances, setInstances] = useState<Instance[] | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({});

  const [createModalOpen, setCreateModalOpen] = useState(false);
  const [createForm, setCreateForm] = useState({ name: "", version: "", port: "" });
  const [createError, setCreateError] = useState<string | null>(null);
  const [createLoading, setCreateLoading] = useState(false);
  const [selectedInstance, setSelectedInstance] = useState<Instance | null>(null);

  async function refreshInstanceList() {
    setLoading(true);
    setError(null);
    try {
      const data = await fetchInstanceList();
      setInstances(data);
    } catch (e: any) {
      setError(e.message ?? String(e));
      setInstances([]);
    } finally {
      setLoading(false);
    }
  }

  async function waitForStatus(name: string, expectedStatus: string, timeoutMs = 10000, intervalMs = 700) {
    const start = Date.now();
    while (Date.now() - start < timeoutMs) {
      try {
        const list = await fetchInstanceList();
        const inst = list.find(i => i.name === name);
        if (inst?.status === expectedStatus) {
          setInstances(list);
          return inst;
        }
        setInstances(list);
      } catch (e) {
      }
      await new Promise(r => setTimeout(r, intervalMs));
    }
    throw new Error("Timeout waiting for status change");
  }

  async function handleToggle(inst: Instance) {
    setActionLoading(prev => ({ ...prev, [inst.name]: true }));
    try {
      if (inst.status === "STOPPED") {
        await sendStartInstanceRequest(inst.name);
        try {
          await waitForStatus(inst.name, "RUNNING", 15000, 700);
        } catch {
          await refreshInstanceList();
        }
      } else {
        await sendStopInstanceRequest(inst.name);
        try {
          await waitForStatus(inst.name, "STOPPED", 15000, 700);
        } catch {
          await refreshInstanceList();
        }
      }
    } catch (e) {
      console.error(e);
      await refreshInstanceList();
    } finally {
      setActionLoading(prev => ({ ...prev, [inst.name]: false }));
    }
  }

  function openCreateModal() {
    setCreateForm({ name: "", version: "", port: "" });
    setCreateError(null);
    setCreateModalOpen(true);
  }

  function handleFormChange(e: React.ChangeEvent<HTMLInputElement>) {
    setCreateForm(prev => ({ ...prev, [e.target.name]: e.target.value }));
  }

  async function handleCreate() {
    setCreateError(null);
    setCreateLoading(true);
    try {
      await sendCreateInstanceRequest(createForm.name, createForm.version, parseInt(createForm.port));
      setCreateModalOpen(false);
      await refreshInstanceList();
    } catch (e: any) {
      setCreateError(e.message ?? String(e));
    } finally {
      setCreateLoading(false);
    }
  }

  useEffect(() => {
    const interval = setInterval(refreshInstanceList, 3000);
    return () => clearInterval(interval);
  }, []);

  if (selectedInstance) {
    return <InstanceDetail instance={selectedInstance} onClose={() => setSelectedInstance(null)} onDeleted={() => { setSelectedInstance(null); refreshInstanceList(); }} onSaved={() => {setSelectedInstance(null); refreshInstanceList(); }}/>;
  }

  return (
    <div className="instancesBlock">
      <h2>Instances</h2>

      {error && <div className="error">Error: {error}</div>}

      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Status</th>
            <th>Port</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {!instances && !loading && (
            <tr>
              <td colSpan={4}>No instances found, create one below!</td>
            </tr>
          )}

          {instances?.map((inst) => (
            <tr key={`${inst.name}-${inst.port}`}>
              <td>{inst.name}</td>
              <td>
                <span id="statusIndicator" className={inst.status.toLowerCase()}>
                  &#x25E6;{inst.status}
                </span>
              </td>
              <td>{inst.port}</td>
              <td>
                <div className="flexboxHorizontal">
                  <button
                    id="startStopButton"
                    className={inst.status === "RUNNING" ? "stop" : "start"}
                    onClick={() => void handleToggle(inst)}
                    disabled={loading || actionLoading[inst.name]}
                  >
                    {actionLoading[inst.name] ? "..." : inst.status === "RUNNING" ? "\u25FC Stop" : "\u25B6 Start"}
                  </button>
                  <button className="normalButton" onClick={() => setSelectedInstance(inst)}>&#x270E; Manage</button>
                </div>
              </td>
            </tr>
          ))}

          <tr>
            <td>
              <div className="flexboxHorizontal">
                <b>Create new instance</b>
                <button onClick={() => openCreateModal()}>+</button>
              </div>
            </td>
            <td></td>
            <td></td>
            <td></td>
          </tr>
        </tbody>
      </table>

      {createModalOpen && (
        <div className="modalBackdrop" onClick={() => setCreateModalOpen(false)}>
          <div className="modalCard" onClick={e => e.stopPropagation()}>
            <h3>Create New Instance</h3>
            {createError && <div className="error">Error: {createError}</div>}
            <input type="text" name="name" value={createForm.name} onChange={handleFormChange} placeholder="Instance Name" />
            <input type="text" name="version" value={createForm.version} onChange={handleFormChange} placeholder="1.22.3" />
            <input type="text" name="port" value={createForm.port} onChange={handleFormChange} placeholder="12345" />
            <button onClick={handleCreate} disabled={createLoading}>
              {createLoading ? "Creating..." : "Create"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}