"use client";

import { ReactNode, useState } from "react";
import { ConvexAuthNextjsProvider } from "@convex-dev/auth/nextjs";
import { ConvexReactClient } from "convex/react";

interface ConvexClientProviderProps {
  children: ReactNode;
}

/**
 * Convex 客户端 Provider（包含 Auth）
 */
export function ConvexClientProvider({ children }: ConvexClientProviderProps) {
  const [convex] = useState(() => {
    // 动态获取 Convex URL，默认优先使用环境变量。
    // 说明：浏览器侧优先用当前 hostname（端口固定 3210），避免通过非 localhost/127 访问前端时出现跨域/白名单不匹配。
    const getConvexUrl = () => {
      const normalize = (url: string) => url.replace(/\/+$/, "");
      const isLocalHost = (host: string) => host === "localhost" || host === "127.0.0.1";
      const convexProxyPath = "/convex";

      // 默认使用环境变量
      const envUrlRaw = (process.env.NEXT_PUBLIC_CONVEX_URL ?? "").trim();
      if (typeof window === "undefined") {
        return normalize(envUrlRaw || "http://127.0.0.1:3210");
      }

      const browserProtocol = window.location.protocol;
      const browserHost = window.location.hostname;
      const shouldUseSameOriginProxy = () => {
        // 说明：
        // - 本项目的 Convex 自托管通常运行在本机 3210 端口；
        // - 通过 FRP/域名访问前端时，通常不会额外暴露 3210；
        // 因此只要不是 localhost/127.0.0.1 访问，就优先走同源 `/convex/*` 反代（由 dev/prod-server.js 处理），
        // 避免登录后因 Convex 连接失败而卡在“无法进入/未同步登录态”的状态。
        return !isLocalHost(browserHost);
      };

      // 浏览器侧：优先尊重 NEXT_PUBLIC_CONVEX_URL（例如生产环境的 https://xxx.convex.cloud）。
      // 仅在 envUrl 是 localhost/127.0.0.1 时，才把 host 改为当前 hostname，避免通过域名访问前端时出现不一致。
      if (envUrlRaw) {
        try {
          const url = new URL(envUrlRaw);

          // 当通过 HTTPS（如 frp/nginx）访问前端时，浏览器不允许从 https 页面发起 ws://（不安全）连接。
          // 若 envUrl 仍是 http://localhost:3210，则走同源反代（由 scripts/dev-server.js 处理 Upgrade）转到本机 3210。
          if (browserProtocol === "https:" && (url.protocol === "http:" || isLocalHost(url.hostname))) {
            return normalize(`${window.location.origin}${convexProxyPath}`);
          }

          if (isLocalHost(url.hostname) && shouldUseSameOriginProxy()) {
            // 说明：HTTP 场景下如果直接改成 `${browserHost}:3210`，通常会因为 3210 未暴露而连接失败。
            // 因此对“域名访问”同样走同源反代。
            return normalize(`${window.location.origin}${convexProxyPath}`);
          }

          return normalize(url.toString());
        } catch {
          // envUrl 不是合法 URL 时，按原值兜底
          return normalize(envUrlRaw);
        }
      }

      // 未配置 env：使用当前主机名，端口固定 3210，并跟随当前页面协议（http/https）。
      // - https 场景下浏览器禁止 ws://，因此默认走同源反代 `/convex`（需要 server 支持 Upgrade 透传）。
      // - 域名/FRP 场景下通常也不会暴露 3210，因此同样走同源反代。
      if (browserProtocol === "https:" || shouldUseSameOriginProxy()) {
        return normalize(`${window.location.origin}${convexProxyPath}`);
      }

      const hostname = window.location.hostname;
      return normalize(`http://${hostname}:3210`);
    };

    const convexUrl = getConvexUrl();
    if (!convexUrl) {
      throw new Error("NEXT_PUBLIC_CONVEX_URL is not defined");
    }
    return new ConvexReactClient(convexUrl);
  });

  return (
    <ConvexAuthNextjsProvider client={convex}>
      {children}
    </ConvexAuthNextjsProvider>
  );
}
