const useState = React.useState;
const useEffect = React.useEffect;
const useMemo = React.useMemo;
const useCallback = React.useCallback;

const ENVIRONMENT_KIND_OPTIONS = [
  {
    value: "local_path",
    label: "Path on local machine",
    hint: "Folder on the current machine, e.g. a mounted project directory.",
  },
  {
    value: "ssh",
    label: "SSH",
    hint: "Remote host accessible over SSH with a workspace path.",
  },
  {
    value: "vm_local",
    label: "VM on local machine",
    hint: "Local VM or libvirt guest on this host.",
  },
  {
    value: "proxmox_remote",
    label: "Proxmox machine on remote",
    hint: "Remote Proxmox host, node and VM identifier.",
  },
  {
    value: "rdp",
    label: "RDP machine",
    hint: "Remote desktop machine reachable over RDP.",
  },
];

const EMPTY_ENVIRONMENT_FORM = {
  name: "",
  kind: "local_path",
  path: "",
  host: "",
  user: "",
  port: 22,
  vm_name: "",
  proxmox_node: "",
  proxmox_vm_id: "",
  notes: "",
  active: true,
};

function _environmentKindMeta(kind) {
  return ENVIRONMENT_KIND_OPTIONS.find((option) => option.value === kind) || ENVIRONMENT_KIND_OPTIONS[0];
}

function _environmentFormToPayload(form) {
  return {
    name: form.name.trim(),
    kind: form.kind,
    path: form.path || "",
    host: form.host || "",
    user: form.user || "",
    port: Number(form.port || 0) || 0,
    vm_name: form.vm_name || "",
    proxmox_node: form.proxmox_node || "",
    proxmox_vm_id: form.proxmox_vm_id || "",
    notes: form.notes || "",
    active: !!form.active,
  };
}

function _environmentFormFromItem(item) {
  return {
    name: item?.name || "",
    kind: item?.kind || "local_path",
    path: item?.path || "",
    host: item?.host || "",
    user: item?.user || "",
    port: item?.port || 22,
    vm_name: item?.vm_name || "",
    proxmox_node: item?.proxmox_node || "",
    proxmox_vm_id: item?.proxmox_vm_id || "",
    notes: item?.notes || "",
    active: item?.active ?? true,
  };
}

function _environmentToolLabel(environment) {
  if (!environment) return "—";
  return `${environment.name} · ${_environmentKindMeta(environment.kind).label}`;
}

function _toolInstanceNames(tool) {
  const instances = Array.isArray(tool?.instances) ? tool.instances : [];
  if (instances.length > 0) {
    return instances.map((instance) => instance.name).filter(Boolean);
  }
  return tool?.default_instance ? [tool.default_instance] : [];
}

function _toolCurrentInstanceName(tool) {
  return tool?.environment?.tool_instance_name
    || tool?.environment?.tool_instance?.name
    || tool?.environment_instance_name
    || tool?.default_instance
    || "";
}

function _toolInstanceLabel(instance) {
  if (!instance) return "—";
  const parts = [instance.name || ""];
  if (instance.kind && instance.kind !== instance.name) {
    parts.push(instance.kind);
  }
  return parts.filter(Boolean).join(" · ");
}

function EnvironmentsPanel() {
  const [environments, setEnvironments] = useState([]);
  const [toolAssignments, setToolAssignments] = useState({});
  const [tools, setTools] = useState([]);
  const [loading, setLoading] = useState(true);
  const [savingEnvironment, setSavingEnvironment] = useState("");
  const [savingTool, setSavingTool] = useState("");
  const [editingEnvironmentId, setEditingEnvironmentId] = useState("");
  const [form, setForm] = useState(EMPTY_ENVIRONMENT_FORM);
  const [error, setError] = useState("");

  const environmentMap = useMemo(
    () => Object.fromEntries(environments.map((environment) => [environment.id, environment])),
    [environments],
  );

  const refresh = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const [environmentData, toolData] = await Promise.all([
        get("/dashboard/environments"),
        get("/dashboard/tools/"),
      ]);
      setEnvironments(environmentData?.environments || []);
      setToolAssignments(environmentData?.tool_assignments || {});
      setTools(toolData?.tools || []);
    } catch (e) {
      console.error("Failed to load environments:", e);
      setError("Nie udało się pobrać środowisk.");
    } finally {
      setLoading(false);
    }
  }, []);

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

  const resetForm = () => {
    setEditingEnvironmentId("");
    setForm(EMPTY_ENVIRONMENT_FORM);
  };

  const handleSubmit = async (event) => {
    event.preventDefault();
    setSavingEnvironment("form");
    setError("");
    try {
      const payload = _environmentFormToPayload(form);
      if (!payload.name) {
        setError("Nazwa środowiska jest wymagana.");
        return;
      }
      if (editingEnvironmentId) {
        await put(`/dashboard/environments/${editingEnvironmentId}`, payload);
      } else {
        await post("/dashboard/environments", payload);
      }
      resetForm();
      await refresh();
    } catch (e) {
      console.error("Failed to save environment:", e);
      setError("Nie udało się zapisać środowiska.");
    } finally {
      setSavingEnvironment("");
    }
  };

  const handleEdit = (environment) => {
    setEditingEnvironmentId(environment.id);
    setForm(_environmentFormFromItem(environment));
  };

  const handleDelete = async (environment) => {
    if (!globalThis.confirm(`Usunąć środowisko '${environment.name}'?`)) {
      return;
    }
    setSavingEnvironment(environment.id);
    setError("");
    try {
      const response = await globalThis.fetch(`${_api()}/dashboard/environments/${environment.id}`, {
        method: "DELETE",
        headers: {
          Authorization: `Bearer ${_key()}`,
        },
      });
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      if (editingEnvironmentId === environment.id) {
        resetForm();
      }
      await refresh();
    } catch (e) {
      console.error("Failed to delete environment:", e);
      setError("Nie udało się usunąć środowiska.");
    } finally {
      setSavingEnvironment("");
    }
  };

  const handleToolAssign = async (toolName, environmentId, instanceName = "") => {
    setSavingTool(toolName);
    setError("");
    try {
      const response = await post("/dashboard/environments/assign", {
        tool: toolName,
        environment_id: environmentId,
        instance_name: instanceName,
      });
      setToolAssignments(response?.tool_assignments || {});
      await refresh();
    } catch (e) {
      console.error("Failed to assign tool:", e);
      setError("Nie udało się przypisać toola do środowiska.");
    } finally {
      setSavingTool("");
    }
  };

  const countsByKind = useMemo(() => {
    return environments.reduce((acc, environment) => {
      acc[environment.kind] = (acc[environment.kind] || 0) + 1;
      return acc;
    }, {});
  }, [environments]);

  const assignedToolCount = Object.values(toolAssignments).filter(Boolean).length;
  const assignedInstanceCount = environments.reduce(
    (count, environment) => count + Object.keys(environment.tool_instance_assignments || {}).length,
    0,
  );

  if (loading) {
    return <Card title="Zdefiniowane środowiska"><p className="text-sm text-gray-400">Loading...</p></Card>;
  }

  return (
    <div className="space-y-6">
      <Card
        title="Zdefiniowane środowiska"
        badge={<span className="text-xs text-gray-500">{environments.length} environments · {assignedToolCount} assigned tools · {assignedInstanceCount} instance bindings</span>}
      >
        <div className="grid grid-cols-2 md:grid-cols-5 gap-3 mb-4 text-xs">
          {ENVIRONMENT_KIND_OPTIONS.map((option) => (
            <div key={option.value} className="rounded-lg border border-gray-200 bg-gray-50 p-3">
              <div className="font-medium text-gray-800">{option.label}</div>
              <div className="mt-1 text-gray-500">{countsByKind[option.value] || 0}</div>
            </div>
          ))}
        </div>

        <form onSubmit={handleSubmit} className="space-y-4 rounded-lg border border-gray-200 bg-white p-4">
          <div className="flex items-center justify-between gap-3">
            <div>
              <div className="text-sm font-semibold text-gray-800">
                {editingEnvironmentId ? "Edytuj środowisko" : "Dodaj nowe środowisko"}
              </div>
              <div className="text-xs text-gray-500">
                { _environmentKindMeta(form.kind).hint }
              </div>
            </div>
            {editingEnvironmentId && (
              <button
                type="button"
                onClick={resetForm}
                className="text-xs px-3 py-1.5 rounded bg-gray-100 text-gray-600 hover:bg-gray-200"
              >
                Anuluj edycję
              </button>
            )}
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            <label className="block">
              <span className="text-xs font-medium text-gray-600">Nazwa</span>
              <input
                value={form.name}
                onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}
                className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                placeholder="np. Local dev path"
              />
            </label>
            <label className="block">
              <span className="text-xs font-medium text-gray-600">Typ</span>
              <select
                value={form.kind}
                onChange={(e) => setForm((prev) => ({ ...prev, kind: e.target.value }))}
                className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
              >
                {ENVIRONMENT_KIND_OPTIONS.map((option) => (
                  <option key={option.value} value={option.value}>{option.label}</option>
                ))}
              </select>
            </label>
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            <label className="block">
              <span className="text-xs font-medium text-gray-600">
                {form.kind === "ssh" || form.kind === "proxmox_remote" || form.kind === "rdp"
                  ? "Host / address"
                  : "Path"}
              </span>
              <input
                value={form.path}
                onChange={(e) => setForm((prev) => ({ ...prev, path: e.target.value }))}
                className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                placeholder={form.kind === "local_path" ? "/home/tom/github/proj" : "Optional workspace path"}
              />
            </label>
            <label className="block">
              <span className="text-xs font-medium text-gray-600">Notes</span>
              <input
                value={form.notes}
                onChange={(e) => setForm((prev) => ({ ...prev, notes: e.target.value }))}
                className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                placeholder="Optional notes"
              />
            </label>
          </div>

          {(form.kind === "ssh" || form.kind === "proxmox_remote" || form.kind === "rdp") && (
            <div className="grid gap-3 md:grid-cols-3">
              <label className="block">
                <span className="text-xs font-medium text-gray-600">User</span>
                <input
                  value={form.user}
                  onChange={(e) => setForm((prev) => ({ ...prev, user: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="root"
                />
              </label>
              <label className="block">
                <span className="text-xs font-medium text-gray-600">Port</span>
                <input
                  type="number"
                  value={form.port}
                  onChange={(e) => setForm((prev) => ({ ...prev, port: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="22"
                />
              </label>
              <label className="block">
                <span className="text-xs font-medium text-gray-600">Host</span>
                <input
                  value={form.host}
                  onChange={(e) => setForm((prev) => ({ ...prev, host: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="server.example.com"
                />
              </label>
            </div>
          )}

          {form.kind === "vm_local" && (
            <div className="grid gap-3 md:grid-cols-2">
              <label className="block">
                <span className="text-xs font-medium text-gray-600">VM name</span>
                <input
                  value={form.vm_name}
                  onChange={(e) => setForm((prev) => ({ ...prev, vm_name: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="proxym-dev"
                />
              </label>
              <label className="block">
                <span className="text-xs font-medium text-gray-600">Workspace path</span>
                <input
                  value={form.path}
                  onChange={(e) => setForm((prev) => ({ ...prev, path: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="/home/user/project"
                />
              </label>
            </div>
          )}

          {form.kind === "proxmox_remote" && (
            <div className="grid gap-3 md:grid-cols-2">
              <label className="block">
                <span className="text-xs font-medium text-gray-600">Proxmox node</span>
                <input
                  value={form.proxmox_node}
                  onChange={(e) => setForm((prev) => ({ ...prev, proxmox_node: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="pve-node-1"
                />
              </label>
              <label className="block">
                <span className="text-xs font-medium text-gray-600">VM ID</span>
                <input
                  value={form.proxmox_vm_id}
                  onChange={(e) => setForm((prev) => ({ ...prev, proxmox_vm_id: e.target.value }))}
                  className="mt-1 w-full rounded-lg border px-3 py-2 text-sm"
                  placeholder="101"
                />
              </label>
            </div>
          )}

          <label className="flex items-center gap-2 text-sm text-gray-600">
            <input
              type="checkbox"
              checked={!!form.active}
              onChange={(e) => setForm((prev) => ({ ...prev, active: e.target.checked }))}
              className="h-4 w-4 rounded border-gray-300"
            />
            <span>Active</span>
          </label>

          <div className="flex items-center gap-2">
            <button
              type="submit"
              disabled={savingEnvironment === "form"}
              className="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
            >
              {editingEnvironmentId ? "Save environment" : "Create environment"}
            </button>
            <button
              type="button"
              onClick={refresh}
              className="rounded-lg bg-gray-100 px-4 py-2 text-sm text-gray-700 hover:bg-gray-200"
            >
              Refresh
            </button>
          </div>
        </form>
      </Card>

      <Card title="Tool → environment assignment" badge={<span className="text-xs text-gray-500">Select where each tool should run</span>}>
        {tools.length === 0 ? (
          <p className="text-sm text-gray-400">No tools available.</p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 text-xs uppercase text-gray-500">
                  <th className="px-3 py-2 text-left">Tool</th>
                  <th className="px-3 py-2 text-left">Current environment</th>
                  <th className="px-3 py-2 text-left">Current instance</th>
                  <th className="px-3 py-2 text-left">Assign</th>
                </tr>
              </thead>
              <tbody>
                {tools.map((tool) => {
                  const currentEnvironmentId = tool.environment_id || toolAssignments[tool.name] || "";
                  const currentEnvironment = currentEnvironmentId ? environmentMap[currentEnvironmentId] : null;
                  const currentInstanceName = currentEnvironment?.tool_instance_assignments?.[tool.name] || _toolCurrentInstanceName(tool);
                  const toolInstances = Array.isArray(tool.instances) ? tool.instances : [];
                  const toolInstanceOptions = toolInstances.length > 0
                    ? toolInstances
                    : (_toolInstanceNames(tool).map((instanceName) => ({ name: instanceName })));
                  return (
                    <tr key={tool.name} className="border-b border-gray-100 hover:bg-gray-50">
                      <td className="px-3 py-3">
                        <div className="flex flex-col gap-1">
                          <span className="font-medium text-gray-900">{tool.name}</span>
                          <span className="text-xs text-gray-500">{tool.category}</span>
                        </div>
                      </td>
                      <td className="px-3 py-3 text-sm">
                        {currentEnvironment ? (
                          <div className="flex flex-col gap-1">
                            <span className="font-medium text-gray-800">{currentEnvironment.name}</span>
                            <span className="text-xs text-gray-500">{currentEnvironment.target}</span>
                          </div>
                        ) : (
                          <span className="text-gray-400">—</span>
                        )}
                      </td>
                      <td className="px-3 py-3 text-sm">
                        {currentInstanceName ? (
                          <div className="flex flex-col gap-1">
                            <span className="font-medium text-gray-800">{currentInstanceName || "—"}</span>
                            {tool.environment?.tool_instance && (
                              <span className="text-xs text-gray-500 truncate" title={tool.environment.tool_instance.description || ""}>
                                {tool.environment.tool_instance.kind}
                              </span>
                            )}
                          </div>
                        ) : (
                          <span className="text-gray-400">—</span>
                        )}
                      </td>
                      <td className="px-3 py-3">
                        <div className="flex flex-col gap-2">
                          <select
                            value={currentEnvironmentId}
                            onChange={(e) => handleToolAssign(tool.name, e.target.value, currentInstanceName)}
                            disabled={savingTool === tool.name || environments.length === 0}
                            className="rounded-lg border px-3 py-2 text-xs disabled:opacity-50"
                          >
                            <option value="">No environment</option>
                            {environments.map((environment) => (
                              <option key={environment.id} value={environment.id}>
                                {environment.name} · {_environmentKindMeta(environment.kind).label}
                              </option>
                            ))}
                          </select>
                          <div className="flex items-center gap-2">
                            {toolInstanceOptions.length > 0 ? (
                              <select
                                value={currentInstanceName}
                                onChange={(e) => handleToolAssign(tool.name, currentEnvironmentId, e.target.value)}
                                disabled={savingTool === tool.name || !currentEnvironmentId}
                                className="min-w-[10rem] rounded-lg border px-3 py-2 text-xs disabled:opacity-50"
                                title={currentEnvironmentId ? "Select a specific tool instance for this environment" : "Assign an environment first"}
                              >
                                {toolInstanceOptions.map((instance) => (
                                  <option key={instance.name} value={instance.name}>
                                    {_toolInstanceLabel(instance)}
                                  </option>
                                ))}
                              </select>
                            ) : (
                              <span className="text-xs text-gray-400">No instances</span>
                            )}
                            {savingTool === tool.name && <span className="text-xs text-blue-600">Saving...</span>}
                          </div>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
        {environments.length === 0 && (
          <p className="mt-3 text-xs text-amber-700">
            Create at least one environment before assigning tools.
          </p>
        )}
      </Card>

      <Card title="Existing environments">
        {environments.length === 0 ? (
          <p className="text-sm text-gray-400">No environments defined yet.</p>
        ) : (
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            {environments.map((environment) => (
              <div key={environment.id} className="rounded-lg border border-gray-200 bg-white p-4">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <div className="font-semibold text-gray-900">{environment.name}</div>
                    <div className="text-xs text-gray-500">{_environmentKindMeta(environment.kind).label}</div>
                  </div>
                  <span className={`text-xs px-2 py-1 rounded-full ${environment.active ? "bg-emerald-100 text-emerald-700" : "bg-gray-100 text-gray-500"}`}>
                    {environment.active ? "active" : "inactive"}
                  </span>
                </div>
                <div className="mt-3 text-sm text-gray-700">{environment.target}</div>
                {environment.notes && <div className="mt-2 text-xs text-gray-500">{environment.notes}</div>}
                <div className="mt-3 flex flex-wrap gap-1">
                  {(environment.tools || []).length > 0 ? (
                    environment.tools.map((toolName) => (
                      <span key={toolName} className="rounded-full bg-blue-50 px-2 py-0.5 text-[11px] text-blue-700">
                        {toolName}
                        {environment.tool_instance_assignments?.[toolName] ? ` · ${environment.tool_instance_assignments[toolName]}` : ""}
                      </span>
                    ))
                  ) : (
                    <span className="text-xs text-gray-400">No tools assigned</span>
                  )}
                </div>
                <div className="mt-4 flex gap-2">
                  <button
                    type="button"
                    onClick={() => handleEdit(environment)}
                    className="rounded bg-gray-100 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-200"
                  >
                    Edit
                  </button>
                  <button
                    type="button"
                    onClick={() => handleDelete(environment)}
                    disabled={savingEnvironment === environment.id}
                    className="rounded bg-red-50 px-3 py-1.5 text-xs text-red-700 hover:bg-red-100 disabled:opacity-50"
                  >
                    Delete
                  </button>
                </div>
              </div>
            ))}
          </div>
        )}
      </Card>

      {error && (
        <div className="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
          {error}
        </div>
      )}
    </div>
  );
}
