import { useState, useEffect, useRef, useCallback } from "react";
import { Editor as ReactMonacoEditor } from "@monaco-editor/react";
import { api } from "../services/api";
import { useWebSocket } from "../hooks/useWebSocket";

type ServerState = "running" | "exited" | "not created" | string;

function StatusBadge({ label, state }: { label: string; state: ServerState }) {
  const color =
    state === "running"
      ? "bg-green-500/20 text-green-400"
      : state === "exited"
        ? "bg-red-500/20 text-red-400"
        : "bg-gray-500/20 text-gray-400";

  return (
    <div className="flex items-center gap-2">
      <span className="text-sm font-medium" style={{ color: "var(--forge-text)" }}>
        {label}:
      </span>
      <span className={`rounded-full px-2 py-0.5 text-xs font-medium ${color}`}>
        {state}
      </span>
    </div>
  );
}

function ControlsPanel() {
  const [status, setStatus] = useState<{ nwserver: string; mariadb: string }>({
    nwserver: "unknown",
    mariadb: "unknown",
  });
  const [loading, setLoading] = useState<string | null>(null);

  const fetchStatus = useCallback(async () => {
    try {
      const s = await api.server.status();
      setStatus(s);
    } catch {
      /* server might not be reachable */
    }
  }, []);

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

  const handleAction = async (action: string) => {
    setLoading(action);
    try {
      if (action === "start") await api.server.start();
      else if (action === "stop") await api.server.stop();
      else if (action === "restart") await api.server.restart();
      else if (action === "config") await api.server.generateConfig();
      await fetchStatus();
    } catch {
      /* error handled by status refresh */
    }
    setLoading(null);
  };

  return (
    <section
      className="rounded-lg border p-4"
      style={{
        backgroundColor: "var(--forge-surface)",
        borderColor: "var(--forge-border)",
      }}
    >
      <h3 className="mb-3 text-lg font-semibold" style={{ color: "var(--forge-text)" }}>
        Server Controls
      </h3>
      <div className="mb-4 flex gap-4">
        <StatusBadge label="NWN Server" state={status.nwserver} />
        <StatusBadge label="MariaDB" state={status.mariadb} />
      </div>
      <div className="flex flex-wrap gap-2">
        {(["start", "stop", "restart", "config"] as const).map((action) => (
          <button
            key={action}
            onClick={() => handleAction(action)}
            disabled={loading !== null}
            className="rounded border px-3 py-1.5 text-sm font-medium transition-opacity disabled:cursor-not-allowed disabled:opacity-50"
            style={{
              backgroundColor:
                action === "start"
                  ? "var(--forge-accent)"
                  : action === "stop"
                    ? "#991b1b"
                    : "var(--forge-surface)",
              borderColor:
                action === "start"
                  ? "var(--forge-accent)"
                  : action === "stop"
                    ? "#dc2626"
                    : "var(--forge-border)",
              color: action === "start" || action === "stop" ? "#fff" : "var(--forge-text)",
            }}
          >
            {loading === action
              ? "..."
              : action === "config"
                ? "Generate Config"
                : action.charAt(0).toUpperCase() + action.slice(1)}
          </button>
        ))}
      </div>
    </section>
  );
}

function LogViewer() {
  const { subscribe } = useWebSocket();
  const [lines, setLines] = useState<string[]>([]);
  const [autoScroll, setAutoScroll] = useState(true);
  const [filter, setFilter] = useState("");
  const scrollRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    return subscribe("log:server", (event) => {
      const data = event.data as { text?: string };
      if (!data?.text) return;
      setLines((prev) => [
        ...prev,
        ...data.text!.split("\n").filter(Boolean),
      ]);
    });
  }, [subscribe]);

  useEffect(() => {
    if (autoScroll && scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [lines, autoScroll]);

  const filteredLines = filter
    ? lines.filter((l) => l.toLowerCase().includes(filter.toLowerCase()))
    : lines;

  return (
    <section
      className="flex flex-col rounded-lg border"
      style={{
        backgroundColor: "var(--forge-surface)",
        borderColor: "var(--forge-border)",
        height: "350px",
      }}
    >
      <div
        className="flex shrink-0 items-center gap-2 px-4 py-2"
        style={{ borderBottom: "1px solid var(--forge-border)" }}
      >
        <h3 className="text-lg font-semibold" style={{ color: "var(--forge-text)" }}>
          Server Logs
        </h3>
        <div className="flex-1" />
        <input
          type="text"
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
          placeholder="Filter logs..."
          className="rounded border px-2 py-1 text-xs"
          style={{
            backgroundColor: "var(--forge-bg)",
            borderColor: "var(--forge-border)",
            color: "var(--forge-text)",
            width: "200px",
          }}
        />
        <button
          onClick={() => setAutoScroll((v) => !v)}
          className="rounded border px-2 py-1 text-xs"
          style={{
            backgroundColor: autoScroll ? "var(--forge-accent)" : "var(--forge-bg)",
            borderColor: "var(--forge-border)",
            color: autoScroll ? "#fff" : "var(--forge-text-secondary)",
          }}
        >
          Auto-scroll
        </button>
        <button
          onClick={() => setLines([])}
          className="rounded border px-2 py-1 text-xs"
          style={{
            backgroundColor: "var(--forge-bg)",
            borderColor: "var(--forge-border)",
            color: "var(--forge-text-secondary)",
          }}
        >
          Clear
        </button>
      </div>
      <div
        ref={scrollRef}
        className="flex-1 overflow-auto p-3"
        style={{
          backgroundColor: "#0d1117",
          fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
          fontSize: "12px",
          lineHeight: "1.5",
        }}
      >
        {filteredLines.length === 0 ? (
          <span style={{ color: "var(--forge-text-secondary)" }}>
            Waiting for log output...
          </span>
        ) : (
          filteredLines.map((line, i) => (
            <div key={i} style={{ color: "#c9d1d9" }}>
              {line}
            </div>
          ))
        )}
      </div>
    </section>
  );
}

function SQLConsole() {
  const [query, setQuery] = useState("SELECT * FROM player_tracking LIMIT 10;");
  const [result, setResult] = useState<{
    columns: string[];
    rows: Record<string, string>[];
  } | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [history, setHistory] = useState<string[]>([]);

  const execute = async () => {
    if (!query.trim()) return;
    setLoading(true);
    setError(null);
    try {
      const res = await api.server.sql(query);
      setResult(res);
      setHistory((prev) => [query, ...prev.filter((q) => q !== query)].slice(0, 10));
    } catch (err: any) {
      setError(err.message);
      setResult(null);
    }
    setLoading(false);
  };

  return (
    <section
      className="flex flex-col rounded-lg border"
      style={{
        backgroundColor: "var(--forge-surface)",
        borderColor: "var(--forge-border)",
      }}
    >
      <div
        className="flex shrink-0 items-center gap-2 px-4 py-2"
        style={{ borderBottom: "1px solid var(--forge-border)" }}
      >
        <h3 className="text-lg font-semibold" style={{ color: "var(--forge-text)" }}>
          SQL Console
        </h3>
        <div className="flex-1" />
        {history.length > 0 && (
          <select
            onChange={(e) => setQuery(e.target.value)}
            className="rounded border px-2 py-1 text-xs"
            style={{
              backgroundColor: "var(--forge-bg)",
              borderColor: "var(--forge-border)",
              color: "var(--forge-text-secondary)",
              maxWidth: "200px",
            }}
            value=""
          >
            <option value="" disabled>
              History ({history.length})
            </option>
            {history.map((q, i) => (
              <option key={i} value={q}>
                {q.length > 60 ? q.slice(0, 60) + "..." : q}
              </option>
            ))}
          </select>
        )}
        <button
          onClick={execute}
          disabled={loading || !query.trim()}
          className="rounded border px-3 py-1 text-sm font-medium transition-opacity disabled:cursor-not-allowed disabled:opacity-50"
          style={{
            backgroundColor: "var(--forge-accent)",
            borderColor: "var(--forge-accent)",
            color: "#fff",
          }}
        >
          {loading ? "Running..." : "Execute"}
        </button>
      </div>

      <div style={{ height: "100px" }}>
        <ReactMonacoEditor
          value={query}
          language="sql"
          theme="vs-dark"
          onChange={(v) => setQuery(v ?? "")}
          options={{
            minimap: { enabled: false },
            fontSize: 13,
            lineNumbers: "off",
            scrollBeyondLastLine: false,
            automaticLayout: true,
            wordWrap: "on",
            padding: { top: 4, bottom: 4 },
            renderLineHighlight: "none",
            overviewRulerLanes: 0,
            hideCursorInOverviewRuler: true,
            scrollbar: { vertical: "hidden", horizontal: "hidden" },
          }}
        />
      </div>

      {error && (
        <div
          className="px-4 py-2 text-sm"
          style={{ color: "#ef4444", borderTop: "1px solid var(--forge-border)" }}
        >
          {error}
        </div>
      )}

      {result && (
        <div
          className="max-h-64 overflow-auto"
          style={{ borderTop: "1px solid var(--forge-border)" }}
        >
          {result.columns.length === 0 ? (
            <div className="px-4 py-3 text-sm" style={{ color: "var(--forge-text-secondary)" }}>
              Query executed successfully (no results)
            </div>
          ) : (
            <table className="w-full text-left text-xs">
              <thead>
                <tr>
                  {result.columns.map((col) => (
                    <th
                      key={col}
                      className="sticky top-0 px-3 py-2 font-medium"
                      style={{
                        backgroundColor: "var(--forge-surface)",
                        borderBottom: "1px solid var(--forge-border)",
                        color: "var(--forge-accent)",
                        fontFamily: "'JetBrains Mono', monospace",
                      }}
                    >
                      {col}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {result.rows.map((row, i) => (
                  <tr
                    key={i}
                    className="transition-colors hover:bg-white/5"
                    style={{
                      borderBottom: "1px solid var(--forge-border)",
                    }}
                  >
                    {result.columns.map((col) => (
                      <td
                        key={col}
                        className="px-3 py-1.5"
                        style={{
                          color: "var(--forge-text)",
                          fontFamily: "'JetBrains Mono', monospace",
                        }}
                      >
                        {row[col]}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            </table>
          )}
          <div
            className="px-3 py-1 text-xs"
            style={{ color: "var(--forge-text-secondary)" }}
          >
            {result.rows.length} row{result.rows.length !== 1 ? "s" : ""}
          </div>
        </div>
      )}
    </section>
  );
}

export function Server() {
  return (
    <div className="h-full overflow-auto p-6" style={{ color: "var(--forge-text)" }}>
      <h2 className="mb-6 text-2xl font-bold" style={{ color: "var(--forge-accent)" }}>
        Server Management
      </h2>
      <div className="flex flex-col gap-6">
        <ControlsPanel />
        <LogViewer />
        <SQLConsole />
      </div>
    </div>
  );
}
