import {
  DeleteOutlined,
  HeartFilled,
  HeartOutlined,
  ImportOutlined,
  LeftOutlined,
  PictureOutlined,
  PlusOutlined,
  RightOutlined,
  SearchOutlined,
} from "@ant-design/icons";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import "../../styles/pages/community.css";
import { useDebounce } from "../../hooks/useDebounce";
import { communityClient, type ServerCommunityCase } from "../../api/communityClient";
import WorkspacePageShell from "../../components/WorkspacePageShell";
import OptimizedImage from "../../components/OptimizedImage";
import { EmptyState } from "../../components/EmptyState";
import { cloneWorkflow, createBlankWorkflow } from "../../data/workflows";
import { ossAssets } from "../../data/ossAssets";
import type { WebCanvasWorkflow, WebProjectSummary } from "../../types";
import { getCommunityCaseCover, getWorkflowFromCase, shouldShowInCanvasCommunity } from "./communityCaseUtils";
import { ossThumb } from "../../utils/ossImageOptimize";

interface CommunityPageProps {
  projects: WebProjectSummary[];
  isAuthenticated: boolean;
  onStartCreate: () => void;
  onOpenProject: (project: WebProjectSummary) => void;
  onDeleteProject?: (project: WebProjectSummary) => void;
  onImportWorkflow: (workflow: WebCanvasWorkflow) => void;
  onRequireLogin?: (action: string) => boolean | void;
}

const communityCardImages = ossAssets.community.cardImages;

const SLIDE_INTERVAL = 3000;
const CAROUSEL_VISIBLE_COUNT = 3;
const MANUAL_PAUSE_DURATION = 2000;
const COMMUNITY_CAROUSEL_VIDEOS = ossAssets.community.carouselVideos;

function buildWorkflowFromServerCase(item: ServerCommunityCase, fallback: WebCanvasWorkflow): WebCanvasWorkflow {
  const workflow = getWorkflowFromCase(item);
  if (workflow) {
    return cloneWorkflow(workflow);
  }

  const coverUrl = getCommunityCaseCover(item);
  return {
    ...cloneWorkflow(fallback),
    id: `community-server-${item.id}`,
    title: item.title,
    description: item.description || fallback.description,
    author: item.username || fallback.author,
    source: "community",
    nodes: fallback.nodes.map((node) =>
      node.id === "reference" && coverUrl ? { ...node, previewUrl: coverUrl } : node,
    ),
  };
}

function CommunityPage({ projects, isAuthenticated, onStartCreate, onOpenProject, onDeleteProject, onImportWorkflow, onRequireLogin }: CommunityPageProps) {
  const [serverCases, setServerCases] = useState<ServerCommunityCase[]>([]);
  const [serverNotice, setServerNotice] = useState<string | null>(null);
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 300);
  const [favoriteIds, setFavoriteIds] = useState<string[]>([]);
  const canUseProtectedAction = (action: string) => onRequireLogin?.(action) !== false;

  const handleStartCreate = () => {
    if (!canUseProtectedAction("start-community-project")) return;
    onStartCreate();
  };

  const handleImportWorkflow = (workflow: WebCanvasWorkflow) => {
    if (!canUseProtectedAction("import-community-workflow")) return;
    onImportWorkflow(workflow);
  };

  useEffect(() => {
    let cancelled = false;
    communityClient
      .listApprovedCases()
      .then((items) => {
        if (!cancelled) {
          const canvasItems = items.filter(shouldShowInCanvasCommunity);
          setServerCases(canvasItems);
          setServerNotice(
            canvasItems.length
              ? "已连接服务器画布社区"
              : items.length
                ? "服务器暂无已审核画布案例"
                : "社区暂无模板",
          );
        }
      })
      .catch((error) => {
        if (!cancelled) {
          setServerCases([]);
          setServerNotice(error instanceof Error ? error.message : "社区服务暂时不可用");
        }
      });

    return () => {
      cancelled = true;
    };
  }, []);

  const getProjectTitle = (project: WebProjectSummary, index: number) =>
    project.source === "server" ? project.name : `预览项目 ${index + 1}`;

  const getProjectSummary = (project: WebProjectSummary) => {
    if (project.source === "server") {
      return project.description || "最近更新的项目";
    }
    return "预览数据";
  };

  /* Carousel state */
  const [currentIndex, setCurrentIndex] = useState(0);
  const [carouselTransitionEnabled, setCarouselTransitionEnabled] = useState(true);
  const [isHoverPaused, setIsHoverPaused] = useState(false);
  const [isManualPaused, setIsManualPaused] = useState(false);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const manualPauseTimerRef = useRef<number | null>(null);

  const carouselCases = useMemo(
    () =>
      COMMUNITY_CAROUSEL_VIDEOS.map((videoUrl, index) => ({
        title: `社区视频 ${index + 1}`,
        videoUrl,
      })),
    [],
  );
  const totalSlides = carouselCases.length;
  const visibleCarouselCases = useMemo(
    () => [...carouselCases, ...carouselCases.slice(0, CAROUSEL_VISIBLE_COUNT)],
    [carouselCases],
  );
  const activeCarouselIndex = (currentIndex + 1) % totalSlides;
  const centerCarouselItemIndex = currentIndex + Math.floor(CAROUSEL_VISIBLE_COUNT / 2);
  const isAutoPaused = isHoverPaused || isManualPaused;

  const pauseAutoCarousel = useCallback(() => {
    setIsManualPaused(true);
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
    if (manualPauseTimerRef.current) {
      window.clearTimeout(manualPauseTimerRef.current);
    }
    manualPauseTimerRef.current = window.setTimeout(() => {
      setIsManualPaused(false);
      manualPauseTimerRef.current = null;
    }, MANUAL_PAUSE_DURATION);
  }, []);

  const goNext = useCallback((pause = true) => {
    if (pause) pauseAutoCarousel();
    setCarouselTransitionEnabled(true);
    setCurrentIndex((prev) => prev + 1);
  }, [pauseAutoCarousel]);

  const goPrev = useCallback(() => {
    pauseAutoCarousel();
    setCarouselTransitionEnabled(true);
    setCurrentIndex((prev) => {
      if (prev > 0) return prev - 1;

      setCarouselTransitionEnabled(false);
      window.requestAnimationFrame(() => {
        setCurrentIndex(totalSlides);
        window.requestAnimationFrame(() => {
          setCarouselTransitionEnabled(true);
          setCurrentIndex(totalSlides - 1);
        });
      });
      return prev;
    });
  }, [pauseAutoCarousel, totalSlides]);

  const handlePrevClick = useCallback(() => {
    goPrev();
  }, [goPrev]);

  const handleNextClick = useCallback(() => {
    pauseAutoCarousel();
    goNext(false);
  }, [goNext, pauseAutoCarousel]);

  const goTo = useCallback((index: number) => {
    setCarouselTransitionEnabled(true);
    setCurrentIndex((index - 1 + totalSlides) % totalSlides);
  }, [totalSlides]);

  const handleCarouselTransitionEnd = () => {
    if (currentIndex < totalSlides) return;

    setCarouselTransitionEnabled(false);
    setCurrentIndex(0);
    window.requestAnimationFrame(() => {
      setCarouselTransitionEnabled(true);
    });
  };

  useEffect(() => {
    if (isAutoPaused) return;
    timerRef.current = setInterval(() => goNext(false), SLIDE_INTERVAL);
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
        timerRef.current = null;
      }
    };
  }, [isAutoPaused, goNext]);

  useEffect(() => {
    return () => {
      if (manualPauseTimerRef.current) {
        window.clearTimeout(manualPauseTimerRef.current);
      }
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
    };
  }, []);

  const handleToggleFavorite = async (item: ServerCommunityCase, cardId: string) => {
    const nextActive = !(item.isFavorited || favoriteIds.includes(cardId));
    setFavoriteIds((current) =>
      nextActive ? Array.from(new Set([...current, cardId])) : current.filter((id) => id !== cardId),
    );
    setServerCases((current) =>
      current.map((caseItem) =>
        caseItem.id === item.id
          ? {
              ...caseItem,
              isFavorited: nextActive,
              favoriteCount: Math.max(0, caseItem.favoriteCount + (nextActive ? 1 : -1)),
            }
          : caseItem,
      ),
    );

    if (!isAuthenticated || !serverCases.some((caseItem) => caseItem.id === item.id)) return;
    try {
      const stats = await communityClient.setReaction(item.id, "favorite", nextActive);
      setServerCases((current) =>
        current.map((caseItem) => (caseItem.id === item.id ? { ...caseItem, ...stats } : caseItem)),
      );
    } catch (error) {
      setServerNotice(error instanceof Error ? error.message : "收藏状态同步失败");
    }
  };

  const filteredCases = useMemo(() => {
    const q = debouncedQuery.trim().toLowerCase();
    if (!q) return serverCases;
    return serverCases.filter((c) =>
      (c.title || "").toLowerCase().includes(q) ||
      (c.description || "").toLowerCase().includes(q) ||
      (c.tags || []).some((t: string) => t.toLowerCase().includes(q))
    );
  }, [serverCases, debouncedQuery]);

  const liveCases: ServerCommunityCase[] = filteredCases.slice(0, 12);

  return (
    <WorkspacePageShell title="社区" fullWidth className="community-page page-motion">
      <section className="community-hero">
        <div
          className="community-carousel"
          onMouseEnter={() => setIsHoverPaused(true)}
          onMouseLeave={() => setIsHoverPaused(false)}
          role="region"
          aria-label="示例预览轮播"
        >
          <div
            className={`community-carousel__track${carouselTransitionEnabled ? "" : " is-resetting"}`}
            style={{ transform: `translateX(-${currentIndex * (100 / CAROUSEL_VISIBLE_COUNT)}%)` }}
            onTransitionEnd={handleCarouselTransitionEnd}
          >
            {visibleCarouselCases.map((card, index) => (
              <article
                key={`${card.videoUrl}-${index}`}
                className={`community-carousel__slide community-carousel__slide--video${index === centerCarouselItemIndex ? " is-center" : ""}`}
                aria-hidden={index !== centerCarouselItemIndex}
              >
                <video
                  className="community-carousel__video"
                  src={card.videoUrl}
                  title={card.title}
                  autoPlay
                  muted
                  loop
                  playsInline
                  preload="metadata"
                />
              </article>
            ))}
          </div>

          <button
            type="button"
            className="community-carousel__arrow community-carousel__arrow--prev"
            onClick={handlePrevClick}
            aria-label="上一张"
          >
            <LeftOutlined />
          </button>
          <button
            type="button"
            className="community-carousel__arrow community-carousel__arrow--next"
            onClick={handleNextClick}
            aria-label="下一张"
          >
            <RightOutlined />
          </button>

          <div className="community-carousel__dots" role="tablist" aria-label="幻灯片指示器">
            {carouselCases.map((_, index) => (
              <button
                key={index}
                type="button"
                role="tab"
                aria-selected={index === activeCarouselIndex}
                aria-label={`第 ${index + 1} 张`}
                className={index === activeCarouselIndex ? "is-active" : ""}
                onClick={() => goTo(index)}
              />
            ))}
          </div>
        </div>
      </section>

      <section className="community-section">
        <div className="community-section__head">
          <div>
            <h2>最近项目</h2>
          </div>
          {isAuthenticated && <span className="studio-pill">{projects.length} 个项目</span>}
        </div>
        <div className="project-row">
          <button
            type="button"
            className="project-card project-card--button project-card--new"
            onClick={handleStartCreate}
          >
            <PlusOutlined style={{ fontSize: 28 }} />
            <div className="project-card__meta">
              <strong>新建项目</strong>
            </div>
          </button>
          {isAuthenticated && projects.map((project, index) => (
            <div key={project.id} className="project-card-shell">
              <button
                type="button"
                className="project-card project-card--button"
                onClick={() => onOpenProject(project)}
              >
                {project.thumbnailUrl ? (
                  <OptimizedImage src={ossThumb(project.thumbnailUrl)} alt="" />
                ) : (
                  <span className="project-card__empty project-card__empty--dark">
                    <PictureOutlined />
                  </span>
                )}
                <span className="project-card__caption">{getProjectSummary(project)}</span>
                <div className="project-card__meta">
                  <strong>{getProjectTitle(project, index)}</strong>
                </div>
              </button>
              {onDeleteProject ? (
                <button
                  type="button"
                  className="project-card__delete"
                  aria-label={`删除项目 ${project.name}`}
                  onClick={() => onDeleteProject(project)}
                >
                  <DeleteOutlined />
                </button>
              ) : null}
            </div>
          ))}
        </div>
      </section>

      <section className="community-section">
        <div className="community-section__head">
          <div>
            <h2>社区精选</h2>
          </div>
          <label className="asset-search">
            <SearchOutlined />
            <input
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="搜索案例..."
            />
            {query ? <button type="button" className="asset-search__clear" onClick={() => setQuery("")} aria-label="清除搜索">×</button> : null}
          </label>
          {serverNotice ? <span className="studio-pill">{serverNotice}</span> : null}
        </div>
        {liveCases.length ? (
          <div className="community-case-grid community-case-grid--mosaic motion-stagger">
            {liveCases.map((item, index) => {
            const fallbackWorkflow = createBlankWorkflow(item.title);
            const workflow = buildWorkflowFromServerCase(item, fallbackWorkflow);
            const cardId = `case-${item.id}`;
            const isFavorite = item.isFavorited || favoriteIds.includes(cardId);
            const imageUrl = getCommunityCaseCover(item) || communityCardImages[index % communityCardImages.length] || fallbackWorkflow.nodes.find((node) => node.previewUrl)?.previewUrl || "";
            return (
              <article
                key={cardId}
                className={`community-case-card community-case-card--mosaic community-case-card--tile-${index % 8}`}
                onClick={() => handleImportWorkflow(workflow)}
                onKeyDown={(event) => {
                  if (event.key === "Enter" || event.key === " ") {
                    event.preventDefault();
                    handleImportWorkflow(workflow);
                  }
                }}
                tabIndex={0}
              >
                <button
                  type="button"
                  className="community-case-card__preview"
                  onClick={(event) => {
                    event.stopPropagation();
                    handleImportWorkflow(workflow);
                  }}
                  aria-label={`导入 ${item.title} 工作流`}
                >
                  <OptimizedImage src={ossThumb(imageUrl)} alt={item.title} />
                </button>
                <p className="community-case-card__caption">{item.description || "可一键导入工作流继续创作。"}</p>
                <div
                  className="community-case-card__body"
                  role="button"
                  tabIndex={0}
                  onClick={() => handleImportWorkflow(workflow)}
                  onKeyDown={(event) => {
                    if (event.key === "Enter" || event.key === " ") {
                      event.preventDefault();
                      handleImportWorkflow(workflow);
                    }
                  }}
                >
                  <div className="community-case-card__author">
                    <span>{item.username || "OmniAI"}</span>
                    <span>{item.tags[0] || item.status}</span>
                  </div>
                  <strong>{item.title}</strong>
                  <p>{item.description || "Import this workflow and continue creating."}</p>
                  <div className="community-card-actions">
                    <button
                      type="button"
                      className={isFavorite ? "is-active heart-animate" : ""}
                      aria-pressed={isFavorite}
                      key={isFavorite ? `fav-${cardId}` : `unfav-${cardId}`}
                      onClick={(event) => {
                        event.stopPropagation();
                        void handleToggleFavorite(item, cardId);
                      }}
                    >
                      {isFavorite ? <HeartFilled /> : <HeartOutlined />}
                      {isFavorite ? "已收藏" : `收藏${item.favoriteCount ? ` ${item.favoriteCount}` : ""}`}
                    </button>
                    <button
                      type="button"
                      onClick={(event) => {
                        event.stopPropagation();
                        handleImportWorkflow(workflow);
                      }}
                    >
                      <ImportOutlined />
                      导入工作流
                    </button>
                  </div>
                </div>
              </article>
            );
            })}
          </div>
        ) : (
          <EmptyState
            icon={<ImportOutlined style={{ fontSize: 48 }} />}
            title={debouncedQuery ? "无匹配结果" : "社区暂无模板"}
            description={debouncedQuery ? "尝试其他关键词，或清除搜索查看全部案例" : "管理员审核通过后，画布社区案例会显示在这里。"}
          />
        )}
      </section>

      <section className="community-section community-section--browse-more">
        <button type="button" onClick={handleStartCreate}>
          新建空白画布 <RightOutlined />
        </button>
      </section>
    </WorkspacePageShell>
  );
}

export default CommunityPage;
