import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Server, RefreshCw, Loader2 } from "lucide-react";
import { Button } from "@/components/button.tsx";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/dialog.tsx";
import { RemoteSyncServerPicker } from "./RemoteSyncServerPicker.tsx";
import { ElectronLoginForm } from "@/auth/ElectronLoginForm.tsx";
import { invalidateServerStatusCache } from "@/lib/hosts-request-cache.ts";

interface RemoteSyncConfig {
  serverUrl: string;
  connectedAt: string;
  lastSyncedAt?: string | null;
  lastSyncStatus?: "ok" | "error" | "never";
  lastSyncError?: string | null;
}

interface RemoteSyncStatus {
  connected: boolean;
  syncing: boolean;
  lastSyncedAt: string | null;
  lastError: string | null;
  needsReauth: boolean;
}

type DesktopSettings = { defaultConnectionOrigin: "local" | "remote" };

interface RemoteSyncPanelProps {
  initialServerUrl?: string;
}

export function RemoteSyncPanel({ initialServerUrl }: RemoteSyncPanelProps) {
  const { t } = useTranslation();
  const [config, setConfig] = useState<RemoteSyncConfig | null>(null);
  const [status, setStatus] = useState<RemoteSyncStatus | null>(null);
  const [desktopSettings, setDesktopSettings] = useState<DesktopSettings>({
    defaultConnectionOrigin: "local",
  });
  const [step, setStep] = useState<"idle" | "picker" | "login">("idle");
  const [pendingServerUrl, setPendingServerUrl] = useState("");
  const [syncingNow, setSyncingNow] = useState(false);
  const consumedInitialServerUrl = useRef(false);

  const refresh = useCallback(async () => {
    const [cfg, st, settings] = await Promise.all([
      window.electronAPI?.invoke?.(
        "get-remote-sync-config",
      ) as Promise<RemoteSyncConfig | null>,
      window.electronAPI?.invoke?.(
        "get-remote-sync-status",
      ) as Promise<RemoteSyncStatus | null>,
      window.electronAPI?.invoke?.(
        "get-desktop-settings",
      ) as Promise<DesktopSettings>,
    ]);
    setConfig(cfg ?? null);
    setStatus(st ?? null);
    if (settings) setDesktopSettings(settings);
  }, []);

  useEffect(() => {
    refresh();
    const unsubscribe = window.electronAPI?.onRemoteSyncStatusChanged?.(
      (nextStatus: RemoteSyncStatus) => setStatus(nextStatus),
    );
    return () => unsubscribe?.();
  }, [refresh]);

  useEffect(() => {
    if (consumedInitialServerUrl.current) return;
    if (!initialServerUrl || config?.serverUrl) return;
    consumedInitialServerUrl.current = true;
    setPendingServerUrl(initialServerUrl);
    setStep("picker");
  }, [initialServerUrl, config]);

  const handleConnectClick = () => setStep("picker");

  const handleServerConfigured = (serverUrl: string) => {
    setPendingServerUrl(serverUrl);
    setStep("login");
  };

  const handleAuthSuccess = async () => {
    setStep("idle");
    await refresh();
  };

  const handleDisconnect = async () => {
    await window.electronAPI?.invoke?.("clear-remote-sync-config");
    await refresh();
  };

  const handleSyncNow = async () => {
    setSyncingNow(true);
    try {
      await window.electronAPI?.invoke?.("remote-sync-now");
    } finally {
      setSyncingNow(false);
      await refresh();
    }
  };

  const handleOriginChange = async (origin: "local" | "remote") => {
    const next = { ...desktopSettings, defaultConnectionOrigin: origin };
    setDesktopSettings(next);
    await window.electronAPI?.invoke?.("save-desktop-settings", next);
    invalidateServerStatusCache();
    window.dispatchEvent(new CustomEvent("hosts:refresh"));
  };

  const isConnected = !!config?.serverUrl;
  const connectedToText = config?.serverUrl
    ? t("remoteSync.connectedTo", { url: config.serverUrl })
    : "";
  const connectionSubtitleText = status?.needsReauth
    ? t("remoteSync.needsReauth")
    : status?.lastError
      ? t("remoteSync.syncError", { message: status.lastError })
      : status?.lastSyncedAt
        ? t("remoteSync.lastSynced", {
            time: new Date(status.lastSyncedAt).toLocaleString(),
          })
        : t("remoteSync.neverSynced");

  return (
    <div className="flex flex-col gap-4">
      <div className="border border-border bg-muted/10 p-4 flex flex-col gap-3">
        <div className="flex items-center gap-2">
          <Server className="size-4 text-accent-brand" />
          <p className="font-bold text-sm">{t("remoteSync.title")}</p>
        </div>
        <p className="text-xs text-muted-foreground">
          {t("remoteSync.description")}
        </p>

        <div className="flex flex-col gap-2 border-t border-border pt-3">
          <div className="flex flex-col gap-0.5 min-w-0">
            {isConnected ? (
              <>
                <span
                  className="text-xs font-medium break-all"
                  title={connectedToText}
                >
                  {connectedToText}
                </span>
                <span
                  className="text-[10px] text-muted-foreground break-words"
                  title={connectionSubtitleText}
                >
                  {connectionSubtitleText}
                </span>
              </>
            ) : (
              <span className="text-xs text-muted-foreground">
                {t("remoteSync.notConnected")}
              </span>
            )}
          </div>

          <div className="flex items-center gap-2 flex-wrap">
            {isConnected ? (
              <>
                {status?.needsReauth && (
                  <Button
                    type="button"
                    size="sm"
                    className="text-[10px] h-7"
                    onClick={handleConnectClick}
                  >
                    {t("remoteSync.bannerReconnect")}
                  </Button>
                )}
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="text-[10px] h-7"
                  onClick={handleSyncNow}
                  disabled={syncingNow || status?.syncing}
                >
                  {syncingNow || status?.syncing ? (
                    <Loader2 className="size-3 animate-spin" />
                  ) : (
                    <RefreshCw className="size-3" />
                  )}
                  {t("remoteSync.syncNowButton")}
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="text-[10px] h-7"
                  onClick={handleDisconnect}
                >
                  {t("remoteSync.disconnectButton")}
                </Button>
              </>
            ) : (
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="text-[10px] h-7"
                onClick={handleConnectClick}
              >
                <Server className="size-3" />
                {t("remoteSync.connectButton")}
              </Button>
            )}
          </div>
        </div>
      </div>

      <div className="border border-border bg-muted/10 p-4 flex flex-col gap-3">
        <p className="font-bold text-sm">{t("remoteSync.originTitle")}</p>
        <p className="text-xs text-muted-foreground">
          {t("remoteSync.originDescription")}
        </p>
        <div className="flex border border-border overflow-hidden w-fit">
          <button
            type="button"
            onClick={() => handleOriginChange("local")}
            className={`px-3 py-1.5 text-xs font-bold uppercase tracking-widest transition-colors ${
              desktopSettings.defaultConnectionOrigin === "local"
                ? "bg-accent-brand text-background"
                : "text-muted-foreground hover:text-foreground hover:bg-muted"
            }`}
          >
            {t("remoteSync.originLocal")}
          </button>
          <button
            type="button"
            onClick={() => handleOriginChange("remote")}
            disabled={!isConnected}
            className={`px-3 py-1.5 text-xs font-bold uppercase tracking-widest transition-colors disabled:opacity-40 disabled:cursor-not-allowed ${
              desktopSettings.defaultConnectionOrigin === "remote"
                ? "bg-accent-brand text-background"
                : "text-muted-foreground hover:text-foreground hover:bg-muted"
            }`}
          >
            {t("remoteSync.originRemote")}
          </button>
        </div>
      </div>

      <Dialog
        open={step === "picker"}
        onOpenChange={(open) => !open && setStep("idle")}
      >
        <DialogContent className="bg-card border border-border sm:max-w-md">
          <DialogHeader>
            <DialogTitle className="sr-only">
              {t("remoteSync.title")}
            </DialogTitle>
          </DialogHeader>
          <RemoteSyncServerPicker
            onServerConfigured={handleServerConfigured}
            onCancel={() => setStep("idle")}
            initialServerUrl={initialServerUrl}
          />
        </DialogContent>
      </Dialog>

      <Dialog
        open={step === "login"}
        onOpenChange={(open) => !open && setStep("idle")}
      >
        <DialogContent
          className="bg-card border border-border sm:max-w-4xl h-[80vh] flex flex-col p-0 gap-0"
          // The entire dialog body is a cross-document iframe (the remote
          // server's own login page). Radix's default "outside interaction"
          // dismiss can't attribute clicks inside a different document to
          // this dialog's content tree, so without this it treats a click
          // on the iframe's own login button as an outside click and closes
          // the dialog instantly, before any auth round-trip even starts --
          // this is what looked like the login button silently doing
          // nothing. Escape and the explicit X button still close it.
          onPointerDownOutside={(e) => e.preventDefault()}
          onInteractOutside={(e) => e.preventDefault()}
        >
          <DialogHeader className="sr-only">
            <DialogTitle>
              {t("remoteSync.signInTitle", { url: pendingServerUrl })}
            </DialogTitle>
          </DialogHeader>
          <div className="flex-1 min-h-0">
            <ElectronLoginForm
              serverUrl={pendingServerUrl}
              targetPurpose="remoteSync"
              onAuthSuccess={handleAuthSuccess}
              onChangeServer={() => setStep("picker")}
            />
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
