'use client'

import React from 'react'

import { Suspense } from 'react'

import { auth } from '@/auth'
import { clearChats } from '@/app/actions'
import { Sidebar } from '@/components/sidebar'
import { SidebarList } from '@/components/sidebar-list'
import { IconSeparator } from '@/components/ui/icons'
import { SidebarFooter } from '@/components/sidebar-footer'
import { ClearHistory } from '@/components/clear-history'
import { UserMenu, UserData } from '@/components/user-menu'
import { LoginButton } from '@/components/login-button'
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger
} from '@/components/ui/tooltip'
import { Badge } from '@/components/ui/badge'
import { ConnectButton } from '@/components/connect-button'
import { SettingsDropDown } from './settings-drop-down'


import { useLocalStorage } from '@/lib/hooks/use-local-storage'
import { Button } from './ui/button'

import Image from 'next/image';
import logoImage from '@/components/images/logo.png';
import { useRouter } from 'next/navigation'

import { Flex, Text } from '@radix-ui/themes';
import Link from 'next/link'
import { useTranslation } from 'react-i18next'
import { message } from 'antd'
import { LogoAI } from '@/components/chat'

import { useState, useRef, } from "react";

import { Trash2, CloudDownload } from "lucide-react";

import { useEffect } from "react";

import {
  BadgeInfo,
  Tags,
  CalendarClock,
  Building2
} from "lucide-react";


export function Header() {
  
  const router = useRouter();
  const { t } = useTranslation();

  const [userData, setUserData] = useLocalStorage(
    'UserData',
    {
      auth_token: "",
      id: 1,
      login_ip: "",
      login_time: 0,
      role: "",
      user_name: "",
      version: ""
    } as UserData
  )

  const soonFunc = () => {
    message.info(t("soon"))
  }

  return (
    <header className="sticky top-0 z-50 flex shrink-0 items-center justify-between  bg-background px-4 py-[1.5rem] w-[80%]  mx-auto">

      <a href="/">
      <LogoAI className="flex text-center ml-0" />
      </a>

      <div className="flex items-center justify-between ">
        <div className="flex items-center ">
          {(!!userData && !!userData.user_name) ? (
            <div className='flex text-[#1A1A1A]'>
              <UserMenu user={userData} />
            </div>

          ) : (
            <div className='flex gap-4 grid-cols-2 text-[#1A1A1A]'>
              <Button variant="ghost" className='text-base bg-[#f4f4f5] hover:bg-[#e5e7eb]'>
                <Link href="/#subscribe-target"
                >
                  {t('subscribe.subscribe')}
                </Link>
              </Button>


              <LoginButton
                variant="ghost"
                // variant="link"
                showGithubIcon={true}
                text={t('login')}
                className="-ml-2 text-base bg-[#f4f4f5] hover:bg-[#e5e7eb]"
              />
            </div>


          )}
        </div>
      </div>

    </header>
  )
}

import { getRuntimeEnv } from "@/lib/ipconfig";

export async function getWsBase() {
  let ip = await getRuntimeEnv("SUPABASE_URL");
  if (!ip) throw new Error("SUPABASE_URL 获取失败，无法构建 wsBase");

  let wsProtocol = "ws";

  if (typeof window !== "undefined") {
    // ✅ 客户端环境（浏览器执行）
    if (window.location.protocol === "https:") {
      wsProtocol = "wss";
      ip = window.location.hostname; // ✅ 用 hostname 避免 HTTPS + IP 的 TLS 报错
    }
  } else {
    // ✅ SSR 环境，延迟导入 headers（不能放顶层）
    const { headers } = await import("next/headers");
    const hdrs = headers();

    const forwardedProto = hdrs.get("x-forwarded-proto");
    const hostHeader = hdrs.get("host");

    if (forwardedProto === "https") {
      wsProtocol = "wss";
    }

    if (hostHeader) {
      // ✅ host 可能带端口，需处理
      ip = hostHeader.includes(":") ? hostHeader.split(":")[0] : hostHeader;
    }
  }

  const finalUrl = `${wsProtocol}://${ip}/api/v1/deploy/ws`;
  console.log("✅ [WebSocket] Final URL:", finalUrl);
  return finalUrl;
}

function getApiBaseUrl(): string {
  if (typeof window === "undefined" || !window.location) {
    if (process.env.NODE_ENV === "development") {
      console.error("❌ getApiBaseUrl 被错误地调用于非浏览器环境");
    }
    throw new Error("❌ getApiBaseUrl 必须在浏览器端调用");
  }

  return `${window.location.protocol}//${window.location.host}`;
}
export function DetailPageHeader({ data }: { data: any }) {
  const [loading, setLoading] = useState(false);
  const [statusText, setStatusText] = useState(data?.statusText || "加载中...");
  const [progress, setProgress] = useState(data?.progress || "0%");
  const [progressBarColor, setProgressBarColor] = useState("bg-blue-500"); // ✅ 默认蓝色
  const [showProgressBar, setShowProgressBar] = useState(false);
  const [showDelete, setShowDelete] = useState(false);
  const [hasWSConnected, setHasWSConnected] = useState(false);
  const [statusLoaded, setStatusLoaded] = useState(false);
  const [canDeploy, setCanDeploy] = useState(true);

  const [currentStatus, setCurrentStatus] = useState(""); // 当前部署状态：running / stopped
  const [switchLoading, setSwitchLoading] = useState(false); // 控制按钮 loading 状态

  const [downloadPercent, setDownloadPercent] = useState("0"); // 下载百分比（0 ~ 100）
  const [showDownloadBar, setShowDownloadBar] = useState(false);

  const [newVersionLoading, setNewVersionLoading] = useState(false);

  const socketRef = useRef<WebSocket | null>(null);

  const { t } = useTranslation();

  console.log("...........model_parameter =", data?.model_parameter);

  // const hasNonEmptyExtraData = data?.extra_data && typeof data.extra_data === 'object' && !Array.isArray(data.extra_data) && Object.keys(data.extra_data).length > 0 data?.model_parameter !== 0 &&
  // data?.model_parameter !== "";
  const hasNonEmptyExtraData =
  data?.extra_data &&
  typeof data.extra_data === 'object' &&
  !Array.isArray(data.extra_data) &&
  Object.keys(data.extra_data).length > 0 &&
  data?.model_parameter !== 0 &&
  data?.model_parameter !== "";


  const initWebSocket = async (userName: string, id: number) => {
    if (socketRef.current) socketRef.current.close();


    //const wsBase = process.env.NEXT_PUBLIC_CLIENT_BASE_WS;
    const wsBase = await getWsBase();
    const socket = new WebSocket(`${wsBase}/status/${userName}/${id}`);
    socketRef.current = socket;

    socket.onopen = () => console.log("WebSocket 已连接");

    socket.onmessage = (event) => {
      const msg = event.data;
      console.log("收到进度信息：", msg);
      setStatusText(msg);

      const percentMatch = msg.match(/(\d+)%/);
      if (percentMatch && percentMatch[1]) {
        setProgress(percentMatch[1] + "%");

        if (percentMatch[1] === "100") {
          console.log("部署完成 ✅，重新拉取状态！");
          fetchDeployStatus();
        }
      }


      setProgressBarColor("bg-blue-500"); // 保持默认颜色
    };

    socket.onerror = (err) => {
      console.error("WebSocket 出错：", err);
      setStatusText(t("deploy.ws_error"));
    };

    socket.onclose = () => {
      console.log("🔌 WebSocket 已关闭");
      setHasWSConnected(false);
      socketRef.current = null;
    };

    setHasWSConnected(true);
  };

  const handleClick = async (source: "icon" | "info") => {
    setLoading(true);
    setStatusText(source === "icon" ? "正在处理图标操作..." : "正在处理信息操作...");
    setShowProgressBar(true)

    try {
      const userData = JSON.parse(localStorage.getItem("UserData") || "null");
      if (!userData?.user_name) {
        setStatusText("未登录，跳转中...");
        window.location.href = "/auth/sign-in/";
        return;
      }

      const userName = userData.user_name;
      const id = data?.id;
      if (!id) {
        setStatusText("缺少组件 ID");
        return;
      }

      const res = await fetch("/api/v1/deploy/deploy", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id, user_name: userName }),
      });

      const json = await res.json();
      if (json?.header?.code === 0) {
        setStatusText("部署已启动，监听中...");
        setProgressBarColor("bg-blue-500");
        initWebSocket(userName, id);
      } else {
        setStatusText(json.header.message || "操作失败（后端）");
      }
    } catch (err) {
      console.error("请求出错：", err);
      setStatusText("请求失败");
    } finally {
      setLoading(false);
    }
  };

  const handleDelete = async () => {
    if (loading) return;
  
    const confirmed = window.confirm(t("deploy.confirm_delete"));
    if (!confirmed) return;
  
    setLoading(true);
    setStatusText(t("deploy.deleting"));
    setProgressBarColor("bg-gray-400");
  
    try {
      const userData = JSON.parse(localStorage.getItem("UserData") || "null");
      const userName = userData?.user_name;
      const id = data?.id;
  
      if (!userName || !id) {
        setStatusText(t("deploy.missing_user_or_id"));
        return;
      }
  
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 60_000); // ⏰ 60秒超时
  
      const res = await fetch("/api/v1/deploy/delete", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        signal: controller.signal,
        body: JSON.stringify({ user_name: userName, n_id: id }),
      });
  
      clearTimeout(timeoutId); // ✅ 成功返回前清除 timeout
  
      if (!res.ok) {
        throw new Error(`HTTP 请求失败: ${res.status}`);
      }
  
      const json = await res.json();
      if (json?.header?.code === 0) {
        setStatusText(t("deploy.deletion_success"));
        setProgress("0%");
        setShowDelete(false); // 删除成功后隐藏按钮
        await fetchDeployStatus();  // ✅ 删除后刷新真实状态
      } else {
        setStatusText(json?.header?.message || "删除失败（后端返回错误）");
      }
    } catch (err) {
      if ((err as any).name === "AbortError") {
        setStatusText(t("deploy.timeout"));
      } else {
        console.error("删除请求出错：", err);
        setStatusText(t("deploy.deletion_failed_network"));
      }
    } finally {
      setLoading(false);
    }
  };
  
  const fetchDeployStatus = async () => {
    try {
      const result = await fetch("/api/v1/deploy/status", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: data?.id }),
      }).then((res) => res.json());
  
      console.log("====> deploy status result:", result);
      setStatusLoaded(true);
  
      if (!result) {
        setStatusText(t("deploy.empty_response"));
        setShowDelete(false);
        return;
      }
  
      const code = result?.header?.code;
      const status = result?.data?.data?.status;
      setCurrentStatus(status || "");   //...............................................
      const userData = JSON.parse(localStorage.getItem("UserData") || "null");
      const userName = userData?.user_name;
      const id = data?.id;
  
      console.log("🟡 状态码 code =", code, "状态 status =", status);
  
      if (code === 1006) {
        setStatusText(t("deploy.not_deployed"));
        setShowDelete(false);
        setProgress("0%");
        setShowProgressBar(false);
        setCanDeploy(true); // ✅ 允许部署
        return;
      }
  
      if (status === "deploying" && userName && id && !hasWSConnected) {
        setStatusText(t("deploy.connecting"));
        initWebSocket(userName, id);
        setShowProgressBar(true);
        setCanDeploy(false); // ✅ 正在部署中，禁止点击
      }
  
      if (status === "running" || status === "stopped") {
        console.log("✅ 允许删除（status =", status, ")");
        setShowDelete(true);
        setProgress("100%");
        setShowProgressBar(true);
        setCanDeploy(false); // ✅ 已部署/已停止，不允许再次 deploy
  
        if (status === "running") {
          setStatusText(t("deploy.running"));
          setProgressBarColor("bg-green-500");
        } else if (status === "stopped") {
          setStatusText(t("deploy.stopped"));
          setProgressBarColor("bg-gray-400");
        }
      } else {
        console.log("❌ 不允许删除（status =", status, ")");
        setShowDelete(false);
        setProgressBarColor("bg-blue-500");
      }
    } catch (err) {
      console.error("获取状态失败：", err);
      setStatusText(t("deploy.fetch_failed"));
      setShowDelete(false);
    }
  };


  const handleSwitchStatus = async () => {
    if (!data?.id) return;

    setSwitchLoading(true);
    const userData = JSON.parse(localStorage.getItem("UserData") || "null");
    const userName = userData?.user_name;

    const id = data?.id;

    if (!userName || !id) {
      setStatusText("缺少组件 ID 或用户信息");
      return;
    }

    if (!userName) {
      setStatusText("未登录，跳转中...");
      window.location.href = "/auth/sign-in/";
      return;
    }

    const endpoint = currentStatus === "running" ? "/api/v1/deploy/stop" : "/api/v1/deploy/start";

    try {
      const res = await fetch(endpoint, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ user_name: userName, n_id: id }),
      });

      const json = await res.json();
      if (json?.header?.code === 0) {
        setStatusText(currentStatus === "running" ? "已停止" : "已启动");
        fetchDeployStatus(); // ✅ 状态切换成功后刷新
      } else {
        setStatusText(json?.header?.message || "操作失败（后端）");
      }
    } catch (err) {
      console.error("切换请求失败：", err);
      setStatusText("网络异常");
    } finally {
      setSwitchLoading(false);
    }
  };

  //软件更新
  const handleDownloadNewVersion = async () => {
    const download_url = data?.extra_data?.download_url;
    let callback_url = data?.extra_data?.callback_url;
    const digest       = data?.extra_data?.digest;
    const version      = data?.extra_data?.version;
    const size         = data?.extra_data?.size;
    const date1        = data?.extra_data?.date;
    const id           = data?.org_id;

    if (!download_url || !size || !id) {
      message.warning("缺少必要的下载参数");
      return;
    }

    setNewVersionLoading(true);
    setShowDownloadBar(true);         // 复用原进度条

    try {
      const apiHost = getApiBaseUrl(); // ✅ 会自动校验是否在客户端
      //这个值是固定的，没有必要从其他渠道传过来，而且这个调用是服务器完成调用的
      callback_url = "http://127.0.0.1:8083/api/v1/cloud/newversioncallback";
      // const res = await fetch("https://ai.szaiai.com/api/v1/cloud/newversion", {
      const res = await fetch(`${apiHost}/api/v1/cloud/newversion`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          date: String(date1),
          url: download_url,
          callback_url,
          digest,
          version,
          size,
          id,
        }),
      });

      const result = await res.json();

      if (result?.header?.code === 0) {
        const percent = (parseFloat(result?.data?.percent ?? "0") * 100).toFixed(1);
        setDownloadPercent(percent);
        message.success(`📦 更新进度：${percent}%`);
        if (percent === "100.0") message.success("🎉 新版本下载完成！");
      } else {
        message.warning(`❌ 更新失败：${result?.header?.message || "未知错误"}`);
      }
    } catch (err) {
      console.error(err);
      message.error("请求出错，无法更新");
    } finally {
      setNewVersionLoading(false);
    }
  };


  useEffect(() => {
    fetchDeployStatus();
  }, [data?.id]);

  useEffect(() => {
    return () => {
      if (socketRef.current) {
        socketRef.current.close();
      }
    };
  }, []);

  const isImagePath =
    typeof data?.icon === "string" &&
    (data.icon.startsWith("http") || data.icon.startsWith("/"));

  const resolvedIconSrc =
    isImagePath && !data.icon.startsWith("http")
      ? process.env.NEXT_PUBLIC_CLIENT_IMAGE_URL + data.icon
      : data.icon;

  return (
    <div className="sticky top-0 z-30 bg-white">
      <div className="mt-4 mb-1 px-6 lg:px-8 w-11/12 lg:w-2/3 xl:w-3/5 mx-auto">
        <div className="flex items-start space-x-6">
          <button
            // className="group flex items-center justify-center w-24 h-24 md:w-32 md:h-32 border transition"
            className={`group flex items-center justify-center w-24 h-24 md:w-32 md:h-32 border transition ${(!data?.model_parameter) ? 'opacity-50 cursor-not-allowed' : ''}`}
            onClick={() => handleClick("icon")}
            disabled={loading || !canDeploy || !data?.model_parameter}
          >
            {isImagePath ? (
              <img
                src={resolvedIconSrc}
                alt="icon"
                className="w-full h-full object-contain transition-all duration-200 group-hover:border-2 group-hover:border-blue-500 group-active:border-2 group-active:border-green-500 group-hover:scale-105 group-active:scale-95"
              />
            ) : (
              data?.icon || "Deploy"
            )}
          </button>

          <div className="flex justify-between flex-1 items-end">
            <div className="text-sm leading-7 space-y-1.5">
              <div className="flex items-center gap-2">
                <BadgeInfo size={16} /> {data?.name || "未命名组件"}
              </div>
              <div className="flex items-center gap-2">
                <Tags size={16} /> {data?.category || "未知"}
              </div>
              <div className="flex items-center gap-2">
                <CalendarClock size={16} /> {data?.updated_at || "未提供"}
              </div>
              <div className="flex items-center gap-2">
                <Building2 size={16} /> {data?.company || "未知公司"}
              </div>
            </div>

            <div className="flex items-center gap-[5px] self-end">
              {hasNonEmptyExtraData && (
                // <button
                //   onClick={() => {
                //     console.log("🟢 点击了更新按钮，extra_data = ", data.extra_data);
                //     // TODO: 后续处理逻辑写在这里
                //   }}
                //   className="hover:text-gray-700 transition self-end text-sm border border-gray-300 rounded px-2 py-1 bg-white"
                //   title="更新"
                // >
                //   🔄 更新
                // </button>
                <div className="flex flex-col items-center gap-[2px]">
                  <button
                    onClick={handleDownloadNewVersion}
                    disabled={newVersionLoading || loading}
                    className="hover:text-gray-700 transition self-end text-sm border border-gray-300 rounded px-2 py-1 bg-white mt-1"
                    title="下载并安装新版本"
                  >
                    {newVersionLoading ? "处理中..." : "⬇️ 更新"}
                  </button>

                  {showDownloadBar && (
                    <div className="w-full h-[4px] bg-gray-200 rounded overflow-hidden mt-1">
                      <div
                        className="h-full bg-blue-500 transition-all duration-300"
                        style={{ width: `${downloadPercent}%` }}
                      />
                    </div>
                  )}
                </div>                 
              )}

              {statusLoaded && (currentStatus === "running" || currentStatus === "stopped") && (
                <button
                  onClick={handleSwitchStatus}
                  disabled={switchLoading || loading}
                  className="hover:text-gray-700 transition self-end text-sm border border-gray-300 rounded px-2 py-1 bg-white"
                  title={currentStatus === "running" ? "停止运行" : "启动运行"}
                >
                  {switchLoading
                    ? "处理中..."
                    : currentStatus === "running"
                    ? "⏹ 停止"
                    : "▶️ 启动"}
                </button>
              )}

              {statusLoaded && showDelete && (
                <button
                  onClick={handleDelete}
                  className="hover:text-gray-700 transition self-end"
                  disabled={loading}
                  title="删除"
                >
                  <Trash2 size={20} />
                </button>
              )}

              {!data?.model_parameter && (
                <div className="flex flex-col items-center gap-[2px]">
                  <button
                    onClick={async () => {
                      try {
                        const download_url = data?.extra_data?.download_url;
                        let callback_url = data?.extra_data?.callback_url;
                        const digest = data?.extra_data?.digest;
                        const version = data?.extra_data?.version;
                        const size = data?.extra_data?.size;
                        const date1 = data?.extra_data?.date;
                        const id = data?.org_id;


                        if (!download_url || !size || !id) {
                          message.warning("缺少必要的下载参数");
                          return;
                        }

                        
                        console.log("📥 调用下载接口...", { url: download_url, size, id });
                        const apiHost = getApiBaseUrl(); // ✅ 会自动校验是否在客户端
                        //const res = await fetch("https://ai.szaiai.com/api/v1/cloud/download", {
                        callback_url = "http://127.0.0.1:8083/api/v1/cloud/callback";
                        const res = await fetch(`${apiHost}/api/v1/cloud/download`, {
                          method: "POST",
                          headers: {
                            "Content-Type": "application/json",
                          },
                          body: JSON.stringify({
                            date: String(date1),
                            url: download_url,
                            callback_url: callback_url,
                            digest: digest,
                            version: version,
                            size: size,
                            id: id,
                          }),
                        });

                        const result = await res.json();
                        console.log("✅ 下载接口返回：", result);

                        if (result?.header?.code === 0) {
                          const percentStr = result?.data?.percent ?? "0";
                          const percentNum = parseFloat(percentStr);
                          const percent = (percentNum * 100).toFixed(1);

                          setDownloadPercent(percent);
                          setShowDownloadBar(true);

                          message.success(`📦 下载进度：${percent}%`);
                        } else {
                          message.warning(`❌ 下载失败：${result?.header?.message || "未知错误"}`);
                        }
                      } catch (err) {
                        console.error("❌ 下载请求异常：", err);
                        message.error("请求出错，无法下载");
                      }
                    }}
                    className="hover:text-gray-700 transition self-end"
                    title="下载模型文件"
                  >
                    <CloudDownload size={20} />
                  </button>


                  {showDownloadBar && (
                    <div className="w-[20px] h-[4px] bg-gray-200 rounded overflow-hidden">
                      <div
                        className="h-full bg-blue-500 transition-all duration-300"
                        style={{ width: `${downloadPercent}%` }}
                      />
                    </div>
                  )}
                  
                </div>
              )}

            </div>

          </div>
        </div>

        {showProgressBar && (progress !== "0%" || statusText) && (
          <div className="relative w-full bg-gray-200 h-6 rounded overflow-hidden">
            {/* 蓝色进度条 */}
            <div
              className={`${progressBarColor} h-full transition-all duration-300`}
              style={{ width: typeof progress === "string" ? progress : `${progress}%` }}
            />

            {/* 浮动在中间的文字层 */}
            <div className="absolute inset-0 flex items-center justify-center text-sm font-medium text-white">
              {loading ? t("deploy.processing") : statusText}
            </div>
          </div>

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

export function NavBack() {


  const router = useRouter();
  const { t } = useTranslation();

  // const query = router.query; // 假设页面 URL 是 /mypage?id=123

  console.log("query", router)
  return (
    <nav className="fixed top-[1rem] container flex items-center justify-between " >
      <Link href="/">
        {t("home")}
      </Link>
    </nav>
  )
}

export function TimeP({
  date,
}: {
  date: string
}) {


  const router = useRouter();
  const { t } = useTranslation();


  return (
    <p className=" text-left text-[1rem]   text-[#808080]">{date}  {t("JellyAI")}</p>
  )
}




