import { useEffect, useMemo, useState, useRef, useCallback } from "react";
import useSWR from "swr";
import api from "@/shared/api/axios";
import { ApiResponse, unwrap } from "@/shared/api/types";
import { formatDate, getApiBaseUrl, isAbsoluteUrl, resolveMediaUrl } from "@/shared/lib/media";
import { clampTitle } from "@/shared/lib/title";
import { useTitleInput } from "@/shared/hooks/useTitleInput";
import { useAuth } from "@/shared/contexts/AuthContext";
import { useTask } from "@/shared/contexts/TaskContext";
import { toast } from "sonner";
import { usePublishPrefetch } from "@/shared/hooks/usePublishPrefetch";
import {
  PublishAccount as Account,
  PublishVideo as Video,
  PublishResult,
} from "@/shared/types/publish";

const fetcher = (url: string) =>
  api.get<ApiResponse<{ success?: boolean; face_verify_qr?: string }>>(url).then((res) => unwrap(res.data));

export const usePublishController = () => {
  const apiBase = getApiBaseUrl();

  const [accounts, setAccounts] = useState<Account[]>([]);
  const [videos, setVideos] = useState<Video[]>([]);
  const [isAccountsLoading, setIsAccountsLoading] = useState(true);
  const [isVideosLoading, setIsVideosLoading] = useState(true);
  const [selectedVideo, setSelectedVideo] = useState<string>("");
  const [videoFilter, setVideoFilter] = useState<string>("");
  const [previewVideoUrl, setPreviewVideoUrl] = useState<string | null>(null);
  const [selectedPlatforms, setSelectedPlatforms] = useState<string[]>([]);
  const [title, setTitle] = useState<string>("");
  const [tags, setTags] = useState<string>("");
  const [isPublishing, setIsPublishing] = useState(false);
  const [publishResults, setPublishResults] = useState<PublishResult[]>([]);
  const [qrCodeImage, setQrCodeImage] = useState<string | null>(null);
  const [qrPlatform, setQrPlatform] = useState<string | null>(null);
  const [isLoadingQR, setIsLoadingQR] = useState(false);
  const [faceVerifyQr, setFaceVerifyQr] = useState<string | null>(null);

  const { userId, isLoading: isAuthLoading } = useAuth();
  const { isGenerating } = useTask();
  const prevIsGenerating = useRef(isGenerating);
  const { readPrefetch, updatePrefetch } = usePublishPrefetch();

  // ---- 视频选择持久化：用 ref 而非 state，彻底避免 effect 竞态 ----
  const videoRestoredRef = useRef(false);
  const titleRestoredRef = useRef(false);

  const getStorageKey = useCallback(() => userId || "guest", [userId]);

  const titleInput = useTitleInput({
    value: title,
    onChange: setTitle,
  });

  // ---- 数据加载 ----

  const fetchAccounts = async () => {
    try {
      const { data: res } = await api.get<ApiResponse<{ accounts: Account[] }>>(
        "/api/publish/accounts"
      );
      const payload = unwrap(res);
      setAccounts(payload.accounts || []);
      updatePrefetch({ accounts: payload.accounts || [] });
    } catch (error) {
      console.error("获取账号失败:", error);
    }
  };

  const fetchVideos = async (autoSelectLatest = false) => {
    try {
      const { data: res } = await api.get<ApiResponse<{ videos: any[] }>>(
        "/api/videos/generated"
      );
      const payload = unwrap(res);
      const nextVideos = (payload.videos || []).map((v: any) => ({
        id: v.id as string,
        name: formatDate(v.created_at) + ` (${v.size_mb.toFixed(1)}MB)`,
        path: v.path.startsWith("/") ? v.path.slice(1) : v.path,
      }));
      setVideos(nextVideos);
      if (nextVideos.length > 0 && autoSelectLatest) {
        setSelectedVideo(nextVideos[0].id);
        // 写入跨页面共享标记，让首页也能感知最新生成的视频
        localStorage.setItem(`vigent_${getStorageKey()}_latestGeneratedVideoId`, nextVideos[0].id);
      }
      updatePrefetch({ videos: nextVideos });
    } catch (error) {
      console.error("获取视频失败:", error);
    }
  };

  // 初始加载
  useEffect(() => {
    const cache = readPrefetch();
    if (cache?.accounts) { setAccounts(cache.accounts); setIsAccountsLoading(false); }
    if (cache?.videos) { setVideos(cache.videos); setIsVideosLoading(false); }
    if (!cache?.accounts) setIsAccountsLoading(true);
    if (!cache?.videos) setIsVideosLoading(true);

    let active = true;
    void Promise.allSettled([fetchAccounts(), fetchVideos(false)]).finally(() => {
      if (!active) return;
      setIsAccountsLoading(false);
      setIsVideosLoading(false);
    });
    return () => { active = false; };
  }, []);

  // ---- 视频选择恢复（唯一一个 effect，条件极简） ----
  // 等 auth 完成 + videos 有数据 → 恢复一次，之后再也不跑
  // 优先检查跨页面共享标记（最新生成的视频），其次恢复上次选择
  useEffect(() => {
    if (isAuthLoading || videos.length === 0 || videoRestoredRef.current) return;
    videoRestoredRef.current = true;

    const key = getStorageKey();
    const latestId = localStorage.getItem(`vigent_${key}_latestGeneratedVideoId`);
    if (latestId && videos.some(v => v.id === latestId)) {
      setSelectedVideo(latestId);
      localStorage.removeItem(`vigent_${key}_latestGeneratedVideoId`);
    } else {
      const saved = localStorage.getItem(`vigent_${key}_publish_selected_video`);
      if (saved && videos.some(v => v.id === saved)) {
        setSelectedVideo(saved);
      } else {
        setSelectedVideo(videos[0].id);
      }
    }
  }, [isAuthLoading, videos, getStorageKey]);

  // ---- 视频选择保存 ----
  useEffect(() => {
    if (!videoRestoredRef.current || !selectedVideo || isAuthLoading) return;
    localStorage.setItem(`vigent_${getStorageKey()}_publish_selected_video`, selectedVideo);
  }, [selectedVideo, isAuthLoading, getStorageKey]);

  // ---- 任务完成 → 自动选中最新 ----
  useEffect(() => {
    if (prevIsGenerating.current && !isGenerating) {
      void fetchVideos(true);
    }
    prevIsGenerating.current = isGenerating;
  }, [isGenerating]);

  // ---- 标题/标签恢复与保存 ----
  useEffect(() => {
    if (isAuthLoading || titleRestoredRef.current) return;
    titleRestoredRef.current = true;

    const key = getStorageKey();
    const savedTitle = localStorage.getItem(`vigent_${key}_publish_title`);
    const savedTags = localStorage.getItem(`vigent_${key}_publish_tags`);
    if (savedTitle) setTitle(clampTitle(savedTitle));
    if (savedTags) {
      try {
        const parsed = JSON.parse(savedTags);
        setTags(Array.isArray(parsed) ? parsed.join(", ") : savedTags);
      } catch { setTags(savedTags); }
    }
  }, [isAuthLoading, getStorageKey]);

  useEffect(() => {
    if (!titleRestoredRef.current || isAuthLoading) return;
    const key = getStorageKey();
    const t = setTimeout(() => localStorage.setItem(`vigent_${key}_publish_title`, title), 300);
    return () => clearTimeout(t);
  }, [title, isAuthLoading, getStorageKey]);

  useEffect(() => {
    if (!titleRestoredRef.current || isAuthLoading) return;
    const key = getStorageKey();
    const t = setTimeout(() => localStorage.setItem(`vigent_${key}_publish_tags`, tags), 300);
    return () => clearTimeout(t);
  }, [tags, isAuthLoading, getStorageKey]);

  // ---- 页面滚动 ----
  useEffect(() => {
    if (typeof window === "undefined") return;
    if ("scrollRestoration" in window.history) window.history.scrollRestoration = "manual";
    window.scrollTo({ top: 0, left: 0, behavior: "auto" });
  }, []);

  // ---- 发布防误操作 ----
  useEffect(() => {
    if (!isPublishing) return;
    const handleBeforeUnload = (event: BeforeUnloadEvent) => {
      event.preventDefault();
      event.returnValue = "发布进行中，请勿刷新页面";
    };
    window.addEventListener("beforeunload", handleBeforeUnload);
    return () => window.removeEventListener("beforeunload", handleBeforeUnload);
  }, [isPublishing]);

  // ---- SWR Polling for Login Status ----
  useSWR(
    qrPlatform ? `${apiBase}/api/publish/login/status/${qrPlatform}` : null,
    fetcher,
    {
      refreshInterval: 2000,
      onSuccess: (data) => {
        if (data.success) {
          setQrCodeImage(null);
          setQrPlatform(null);
          setFaceVerifyQr(null);
          toast.success("✅ 登录成功！");
          fetchAccounts();
        } else if (data.face_verify_qr && !faceVerifyQr) {
          // 刷脸验证：后端捕获了新二维码页面截图
          setFaceVerifyQr(data.face_verify_qr);
        }
      },
    }
  );

  useEffect(() => {
    let timer: NodeJS.Timeout;
    if (qrPlatform) {
      timer = setTimeout(() => {
        if (qrPlatform) {
          setQrPlatform(null);
          setQrCodeImage(null);
          toast.error("登录超时，请重试");
        }
      }, 180000);
    }
    return () => clearTimeout(timer);
  }, [qrPlatform]);

  // ---- 操作函数 ----

  const runWithConcurrency = async <T,>(
    taskFactories: Array<() => Promise<T>>,
    concurrency: number
  ): Promise<T[]> => {
    if (taskFactories.length === 0) return [];

    const results: T[] = new Array(taskFactories.length);
    let nextIndex = 0;

    const worker = async () => {
      while (true) {
        const currentIndex = nextIndex;
        nextIndex += 1;
        if (currentIndex >= taskFactories.length) return;
        results[currentIndex] = await taskFactories[currentIndex]();
      }
    };

    const workerCount = Math.min(Math.max(concurrency, 1), taskFactories.length);
    await Promise.all(Array.from({ length: workerCount }, () => worker()));
    return results;
  };

  const togglePlatform = (platform: string) => {
    if (selectedPlatforms.includes(platform)) {
      setSelectedPlatforms(selectedPlatforms.filter((p) => p !== platform));
    } else {
      setSelectedPlatforms([...selectedPlatforms, platform]);
    }
  };

  const handlePublish = async () => {
    if (!selectedVideo || !title || selectedPlatforms.length === 0) {
      toast.error("请选择视频、填写标题并选择至少一个平台");
      return;
    }
    const video = videos.find(v => v.id === selectedVideo);
    if (!video) {
      toast.error("未找到选中的视频");
      return;
    }
    setIsPublishing(true);
    setPublishResults([]);
    const tagList = tags.split(/[,，\s]+/).filter((t) => t.trim());

    const publishOnePlatform = async (platform: string): Promise<PublishResult> => {
      try {
        const { data: res } = await api.post<ApiResponse<any>>("/api/publish", {
          video_path: video.path, platform, title, tags: tagList, description: "",
        });
        const result = unwrap(res);
        const screenshotUrl = typeof result.screenshot_url === "string"
          ? resolveMediaUrl(result.screenshot_url) || result.screenshot_url : undefined;
        return {
          platform: result.platform || platform,
          success: Boolean(result.success),
          message: result.message || "",
          url: result.url,
          screenshot_url: screenshotUrl,
        };
      } catch (error: any) {
        const message = error.response?.data?.message || String(error);
        return { platform, success: false, message };
      }
    };

    try {
      const taskFactories = selectedPlatforms.map((platform) => () => publishOnePlatform(platform));
      const results = await runWithConcurrency(taskFactories, 2);
      setPublishResults(results);
    } finally {
      setIsPublishing(false);
    }
  };

  const handleLogin = async (platform: string) => {
    setIsLoadingQR(true);
    setQrPlatform(platform);
    setQrCodeImage(null);
    try {
      const { data: res } = await api.post<ApiResponse<any>>(`/api/publish/login/${platform}`);
      const result = unwrap(res);
      if (result.success && result.qr_code) {
        setQrCodeImage(result.qr_code);
      } else {
        setQrPlatform(null);
        toast.error(result.message || "登录失败");
      }
    } catch (error: any) {
      setQrPlatform(null);
      toast.error(`登录失败: ${error.response?.data?.message || error.message}`);
    } finally {
      setIsLoadingQR(false);
    }
  };

  const handleLogout = async (platform: string) => {
    if (!confirm("确定要注销登录吗？")) return;
    try {
      const { data: res } = await api.post<ApiResponse<any>>(`/api/publish/logout/${platform}`);
      const result = unwrap(res);
      if (result.success) { toast.success("已注销"); fetchAccounts(); }
      else { toast.error(result.message || "注销失败"); }
    } catch (error: any) {
      toast.error(`注销失败: ${error.response?.data?.message || error.message}`);
    }
  };

  const platformIcons: Record<string, { src: string; alt: string }> = {
    douyin: { src: "/platforms/douyin.svg", alt: "抖音" },
    weixin: { src: "/platforms/wechat.svg", alt: "微信视频号" },
    bilibili: { src: "/platforms/bilibili.svg", alt: "B站" },
    xiaohongshu: { src: "/platforms/xiaohongshu.svg", alt: "小红书" },
  };

  const filteredVideos = useMemo(() => {
    const query = videoFilter.trim().toLowerCase();
    if (!query) return videos;
    return videos.filter((v) => v.name.toLowerCase().includes(query));
  }, [videos, videoFilter]);

  const handlePreviewVideo = (videoId: string) => {
    const video = videos.find(v => v.id === videoId);
    if (!video) return;
    const previewPath = isAbsoluteUrl(video.path) ? video.path : video.path.startsWith("/") ? video.path : `/${video.path}`;
    setPreviewVideoUrl(resolveMediaUrl(previewPath) || previewPath);
  };

  const closeQrModal = () => {
    setQrCodeImage(null);
    setQrPlatform(null);
    setFaceVerifyQr(null);
  };

  return {
    apiBase, accounts, videos, isAccountsLoading, isVideosLoading,
    selectedVideo, setSelectedVideo, videoFilter, setVideoFilter,
    previewVideoUrl, setPreviewVideoUrl, selectedPlatforms,
    title, titleInput, tags, setTags,
    isPublishing, publishResults, qrCodeImage, qrPlatform, isLoadingQR, faceVerifyQr,
    fetchAccounts, fetchVideos, togglePlatform, handlePublish,
    handleLogin, handleLogout, platformIcons, filteredVideos,
    handlePreviewVideo, closeQrModal,
  };
};
