import { useState, useEffect, useCallback, useRef } from "react";
import type { LocalServerStatus } from "../types";

interface DeployPageProps {
  project?: string;
  agentName?: string;
  sourceFile?: string;
  isWorkspace?: boolean;
  onToast: (msg: string) => void;
  onDeployWithAssistant?: (message: string) => void;
}

export default function DeployPage({ project, agentName, sourceFile, onToast, onDeployWithAssistant }: DeployPageProps) {
  // --- Local server state ---
  const [localStatus, setLocalStatus] = useState<LocalServerStatus>({
    running: false,
    port: null,
    pid: null,
    url: null,
  });
  const [localLoading, setLocalLoading] = useState(true);
  const [localActing, setLocalActing] = useState(false);
  const [copiedKey, setCopiedKey] = useState<string | null>(null);

  const qs = project ? `?project=${encodeURIComponent(project)}` : "";

  // Fetch local server status (silent = no loading flash)
  const fetchLocalStatus = useCallback(async (silent = false) => {
    if (!silent) setLocalLoading(true);
    try {
      const res = await fetch(`/api/local-server/status${qs}`);
      if (!res.ok) return;
      const data = await res.json();
      setLocalStatus(data);
    } catch {
      // Server may not support this endpoint yet
    } finally {
      if (!silent) setLocalLoading(false);
    }
  }, [qs]);

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

  // Poll while the server is starting
  const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const wasStartingRef = useRef(false);
  const startTimeRef = useRef<number | null>(null);
  const STARTUP_TIMEOUT_MS = 60_000;

  useEffect(() => {
    if (localStatus.starting) {
      if (!wasStartingRef.current) startTimeRef.current = Date.now();
      wasStartingRef.current = true;

      pollingRef.current = setInterval(() => {
        if (startTimeRef.current && Date.now() - startTimeRef.current > STARTUP_TIMEOUT_MS) {
          onToast("Server is taking too long to start. Check the logs.");
          clearInterval(pollingRef.current!);
          pollingRef.current = null;
          setLocalStatus((s) => ({ ...s, starting: false }));
          wasStartingRef.current = false;
          startTimeRef.current = null;
          return;
        }
        fetchLocalStatus(true);
      }, 2000);
    } else {
      // Detect crash: was starting but now neither starting nor running
      if (wasStartingRef.current && !localStatus.running) {
        onToast("Server failed to start. Check the logs.");
      } else if (wasStartingRef.current && localStatus.running) {
        onToast("Server started");
      }
      wasStartingRef.current = false;
      startTimeRef.current = null;

      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
    }
    return () => {
      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
    };
  }, [localStatus.starting, localStatus.running, fetchLocalStatus, onToast]);

  const handleStartServer = async () => {
    setLocalActing(true);
    try {
      const res = await fetch(`/api/local-server/start${qs}`, {
        method: "POST",
      });
      const data = await res.json();
      if (data.ok) {
        // Toast will be shown when polling detects the final state
        // Apply the returned status immediately so the UI shows "starting"
        setLocalStatus({
          running: false,
          starting: true,
          port: data.port,
          pid: data.pid,
          url: data.url,
        });
      } else {
        onToast(`Error: ${data.error}`);
      }
    } catch (err) {
      onToast(`Error: ${String(err)}`);
    } finally {
      setLocalActing(false);
    }
  };

  const handleStopServer = async () => {
    setLocalActing(true);
    try {
      const res = await fetch(`/api/local-server/stop${qs}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });
      const data = await res.json();
      if (data.ok) {
        onToast("Server stopped");
        await fetchLocalStatus();
      } else {
        onToast(`Error: ${data.error || "Failed to stop"}`);
      }
    } catch (err) {
      onToast(`Error: ${String(err)}`);
    } finally {
      setLocalActing(false);
    }
  };

  const handleCopy = (key: string, text: string) => {
    navigator.clipboard.writeText(text);
    setCopiedKey(key);
    setTimeout(() => setCopiedKey(null), 1500);
  };

  const CopyBtn = ({ id, text }: { id: string; text: string }) => (
    <button
      onClick={() => handleCopy(id, text)}
      className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0"
      title="Copy"
    >
      {copiedKey === id ? (
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="w-3.5 h-3.5 text-green-500">
          <path fillRule="evenodd" d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z" clipRule="evenodd" />
        </svg>
      ) : (
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="w-3.5 h-3.5">
          <path d="M7 3.5A1.5 1.5 0 0 1 8.5 2h3.879a1.5 1.5 0 0 1 1.06.44l3.122 3.12A1.5 1.5 0 0 1 17 6.622V12.5a1.5 1.5 0 0 1-1.5 1.5h-1v-3.379a3 3 0 0 0-.879-2.121L10.5 5.379A3 3 0 0 0 8.379 4.5H7v-1Z" />
          <path d="M4.5 6A1.5 1.5 0 0 0 3 7.5v9A1.5 1.5 0 0 0 4.5 18h7a1.5 1.5 0 0 0 1.5-1.5v-5.879a1.5 1.5 0 0 0-.44-1.06L9.44 6.439A1.5 1.5 0 0 0 8.378 6H4.5Z" />
        </svg>
      )}
    </button>
  );

  return (
    <div className="flex-1 min-h-0 overflow-y-auto">
      <div className="px-4 pt-10 pb-6 space-y-6">
        <div className="w-full max-w-2xl mx-auto space-y-6">

          {/* ---- LOCAL SERVER ---- */}
          <div className="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl shadow-sm">
            {/* Header */}
            <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-800 flex items-start justify-between">
              <div>
                <h2 className="text-base font-semibold text-gray-900 dark:text-white">
                  Local Server
                </h2>
                <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                  Run your agent locally as a production server.
                </p>
              </div>
              <a href="https://klisk.productomania.io/docs/guides/deploy.html#local-server" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-400 flex-shrink-0 mt-0.5" title="Documentation">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-4 h-4">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
                </svg>
              </a>
            </div>

            {/* Body */}
            <div className="px-6 py-5">
              {localLoading ? (
                <div className="py-4" />
              ) : localStatus.starting ? (
                /* Starting state */
                <div className="flex items-center gap-2">
                  <span className="w-2.5 h-2.5 rounded-full bg-yellow-400 animate-pulse" />
                  <span className="text-sm font-medium text-gray-900 dark:text-white">
                    Starting on port {localStatus.port}...
                  </span>
                </div>
              ) : localStatus.running ? (
                /* Running state */
                <div className="space-y-4">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <span className="w-2.5 h-2.5 rounded-full bg-green-400 animate-pulse" />
                      <span className="text-sm font-medium text-gray-900 dark:text-white">
                        Running on port {localStatus.port}
                      </span>
                    </div>
                    <button
                      onClick={handleStopServer}
                      disabled={localActing}
                      className="px-3 py-1.5 text-xs font-medium border border-red-300 dark:border-red-700 text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-950 disabled:opacity-50 rounded-lg transition-colors"
                    >
                      {localActing ? "Stopping..." : "Stop"}
                    </button>
                  </div>

                  {/* Endpoints */}
                  <div className="space-y-2">
                    {/* Chat */}
                    <div className="flex items-center gap-3">
                      <span className="text-xs font-medium text-gray-500 dark:text-gray-400 w-12 flex-shrink-0">Chat</span>
                      <code className="text-sm text-blue-600 dark:text-blue-400 font-mono truncate min-w-0">
                        {localStatus.url}
                      </code>
                      <div className="flex items-center gap-1 flex-shrink-0">
                        <a
                          href={localStatus.url!}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
                          title="Open in browser"
                        >
                          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="w-3.5 h-3.5">
                            <path fillRule="evenodd" d="M4.25 5.5a.75.75 0 0 0-.75.75v8.5c0 .414.336.75.75.75h8.5a.75.75 0 0 0 .75-.75v-4a.75.75 0 0 1 1.5 0v4A2.25 2.25 0 0 1 12.75 17h-8.5A2.25 2.25 0 0 1 2 14.75v-8.5A2.25 2.25 0 0 1 4.25 4h5a.75.75 0 0 1 0 1.5h-5Z" clipRule="evenodd" />
                            <path fillRule="evenodd" d="M6.194 12.753a.75.75 0 0 0 1.06.053L16.5 4.44v2.81a.75.75 0 0 0 1.5 0v-4.5a.75.75 0 0 0-.75-.75h-4.5a.75.75 0 0 0 0 1.5h2.553l-9.056 8.194a.75.75 0 0 0-.053 1.06Z" clipRule="evenodd" />
                          </svg>
                        </a>
                        <CopyBtn id="local-chat" text={localStatus.url!} />
                      </div>
                    </div>

                    {/* API */}
                    <div className="flex items-center gap-3">
                      <span className="text-xs font-medium text-gray-500 dark:text-gray-400 w-12 flex-shrink-0">API</span>
                      <code className="text-sm text-gray-700 dark:text-gray-300 font-mono truncate min-w-0">
                        {localStatus.url}/api/chat
                      </code>
                      <CopyBtn id="local-api" text={`${localStatus.url}/api/chat`} />
                    </div>
                  </div>

                  {/* Widget embed */}
                  <div>
                    <span className="text-xs font-medium text-gray-500 dark:text-gray-400">Widget</span>
                    <div className="mt-1.5 relative group">
                      <pre className="bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg px-3 py-2.5 text-xs font-mono text-gray-700 dark:text-gray-300 overflow-x-auto">
{`<script src="${localStatus.url}/widget.js"></script>`}
                      </pre>
                      <div className="absolute top-1.5 right-1.5">
                        <CopyBtn id="local-widget" text={`<script src="${localStatus.url}/widget.js"></script>`} />
                      </div>
                    </div>
                  </div>
                </div>
              ) : (
                /* Not running state */
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <span className="w-2.5 h-2.5 rounded-full bg-gray-300 dark:bg-gray-600" />
                    <span className="text-sm text-gray-500 dark:text-gray-400">
                      Not running
                    </span>
                  </div>
                  <button
                    onClick={handleStartServer}
                    disabled={localActing}
                    className="px-4 py-1.5 text-xs font-medium bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white rounded-lg transition-colors"
                  >
                    {localActing ? "Starting..." : "Start Server"}
                  </button>
                </div>
              )}
            </div>
          </div>

          {/* ---- DEPLOY TO PRODUCTION ---- */}
          <div className="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl shadow-sm">
            {/* Header */}
            <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-800 flex items-start justify-between">
              <div>
                <h2 className="text-base font-semibold text-gray-900 dark:text-white">
                  Deploy to Production
                </h2>
                <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                  Deploy your agent to any cloud platform.
                </p>
              </div>
              <a href="https://klisk.productomania.io/docs/guides/deploy.html#deploy-to-the-cloud" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-400 flex-shrink-0 mt-0.5" title="Documentation">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="w-4 h-4">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
                </svg>
              </a>
            </div>

            {/* Body */}
            <div className="px-6 py-5 space-y-5">
              <p className="text-sm text-gray-600 dark:text-gray-400">
                The assistant will guide you step by step to deploy your agent to the platform of your choice, including Google Cloud Run, AWS, Railway, Fly.io, and more.
              </p>

              {/* Deploy action */}
              {onDeployWithAssistant && (
                <div className="flex items-center justify-between">
                  <span className="text-sm text-gray-500 dark:text-gray-400">
                    The assistant will guide you through the process.
                  </span>
                  <button
                    onClick={() => {
                      let msg = `Help me deploy the agent "${agentName || "my agent"}" to production.`;
                      if (project) msg += `\nThe agent belongs to the project directory: ${project}`;
                      if (sourceFile) msg += `\nThe agent is defined in: ${sourceFile}`;
                      onDeployWithAssistant(msg);
                    }}
                    className="px-4 py-1.5 text-xs font-medium bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors flex-shrink-0"
                  >
                    Deploy Agent
                  </button>
                </div>
              )}
            </div>
          </div>

        </div>
      </div>
    </div>
  );
}
