import {
  ArrowLeftOutlined,
  CheckCircleOutlined,
  DeleteOutlined,
  PlayCircleOutlined,
  SearchOutlined,
  ShoppingOutlined,
  TagsOutlined,
} from "@ant-design/icons";
import { useCallback, useEffect, useMemo, useRef, useState, type CSSProperties } from "react";
import "../../styles/pages/more-tools.css";
import "../../styles/pages/image-workbench.css";
import "../../styles/pages/ecommerce.css";
import "../../styles/pages/local-theme-parity.css";
import type { WebProjectSummary } from "../../types";
import { useDebounce } from "../../hooks/useDebounce";
import { templateCarouselCases, templateCases, templateCategories, type TemplateCase } from "./ecommerceTemplates";

interface EcommerceTemplatesPageProps {
  projects: WebProjectSummary[];
  onOpenMore?: () => void;
  onOpenEcommerce?: () => void;
  onSelectTemplate?: (template: TemplateCase) => void;
  onStartCreate?: () => void;
  onOpenProject: (project: WebProjectSummary) => void;
  onDeleteProject?: (project: WebProjectSummary) => void;
}

const APPLE_CAROUSEL_SLOTS = [-4, -3, -2, -1, 0, 1, 2, 3, 4];
const APPLE_CAROUSEL_TRANSITION_MS = 760;

interface AppleCarouselMotion {
  direction: number;
  progress: 0 | 1;
}

function getPositiveModulo(value: number, length: number) {
  return ((value % length) + length) % length;
}

function getAppleCarouselCardStyle(offset: number): CSSProperties {
  const depth = Math.abs(offset);
  const direction = Math.sign(offset);
  const isActive = depth === 0;
  const xByDepth = [0, 286, 456, 610, 735, 840];
  const yByDepth = [8, -2, -8, -13, -18, -24];
  const rotateByDepth = [0, 0, 0, 0, 0];
  const scaleByDepth = [1, 0.98, 0.94, 0.91, 0.88, 0.84];
  const x = direction * (xByDepth[depth] ?? xByDepth[xByDepth.length - 1]!);
  const y = yByDepth[depth] ?? yByDepth[yByDepth.length - 1]!;
  const z = isActive ? 90 : 28 - depth;
  const rotateY = 0;
  const rotateZ = direction * (rotateByDepth[depth] ?? rotateByDepth[rotateByDepth.length - 1]!);
  const scale = scaleByDepth[depth] ?? scaleByDepth[scaleByDepth.length - 1]!;

  return {
    "--apple-card-offset": offset,
    "--apple-card-depth": depth,
    "--apple-card-z": 80 - depth,
    "--apple-card-x": `${x}px`,
    "--apple-card-y": `${y}px`,
    "--apple-card-z-offset": `${z}px`,
    "--apple-card-rotate-y": `${rotateY}deg`,
    "--apple-card-rotate-z": `${rotateZ}deg`,
    "--apple-card-scale": String(scale),
    "--apple-card-opacity": String(depth > 4 ? 0 : 1),
  } as CSSProperties;
}

function EcommerceTemplatesPage({
  projects,
  onOpenMore,
  onOpenEcommerce,
  onSelectTemplate,
  onStartCreate,
  onOpenProject,
  onDeleteProject,
}: EcommerceTemplatesPageProps) {
  const [activeTemplateCategory, setActiveTemplateCategory] = useState("全部");
  const [templateSearch, setTemplateSearch] = useState("");
  const debouncedSearch = useDebounce(templateSearch, 300);
  const [carouselIndex, setCarouselIndex] = useState(0);
  const [carouselMotion, setCarouselMotion] = useState<AppleCarouselMotion | null>(null);
  const [carouselIsResetting, setCarouselIsResetting] = useState(false);
  const carouselFrameRef = useRef<number | null>(null);
  const carouselResetFrameRef = useRef<number | null>(null);
  const carouselTimerRef = useRef<number | null>(null);

  const filteredTemplates = useMemo(() => {
    const keyword = debouncedSearch.trim();
    return templateCases.filter((item) => {
      const categoryMatches = activeTemplateCategory === "全部" || item.category === activeTemplateCategory;
      const keywordMatches =
        !keyword || item.title.includes(keyword) || item.summary.includes(keyword) || item.category.includes(keyword);
      return categoryMatches && keywordMatches;
    });
  }, [activeTemplateCategory, debouncedSearch]);
  const carouselItems = useMemo(() => templateCarouselCases.slice(0, 5), []);
  const carouselSlotOffsets = useMemo(() => {
    const direction = carouselMotion?.direction ?? 0;
    const minSlot = APPLE_CAROUSEL_SLOTS[0]! + Math.min(direction, 0);
    const maxSlot = APPLE_CAROUSEL_SLOTS[APPLE_CAROUSEL_SLOTS.length - 1]! + Math.max(direction, 0);
    return Array.from({ length: maxSlot - minSlot + 1 }, (_, index) => minSlot + index);
  }, [carouselMotion?.direction]);

  const startCarouselShift = useCallback(
    (rawDirection: number) => {
      const direction = Math.sign(rawDirection);
      if (!direction || carouselItems.length <= 1 || carouselMotion) return;

      if (carouselFrameRef.current !== null) {
        window.cancelAnimationFrame(carouselFrameRef.current);
      }
      if (carouselTimerRef.current !== null) {
        window.clearTimeout(carouselTimerRef.current);
      }
      if (carouselResetFrameRef.current !== null) {
        window.cancelAnimationFrame(carouselResetFrameRef.current);
      }

      setCarouselIsResetting(false);
      setCarouselMotion({ direction, progress: 0 });
      carouselFrameRef.current = window.requestAnimationFrame(() => {
        carouselFrameRef.current = window.requestAnimationFrame(() => {
          setCarouselMotion((current) => (current?.direction === direction ? { direction, progress: 1 } : current));
        });
      });
      carouselTimerRef.current = window.setTimeout(() => {
        setCarouselIsResetting(true);
        setCarouselIndex((current) => getPositiveModulo(current + direction, carouselItems.length));
        setCarouselMotion(null);
        carouselResetFrameRef.current = window.requestAnimationFrame(() => {
          carouselResetFrameRef.current = window.requestAnimationFrame(() => {
            setCarouselIsResetting(false);
          });
        });
      }, APPLE_CAROUSEL_TRANSITION_MS);
    },
    [carouselItems.length, carouselMotion],
  );

  useEffect(() => {
    if (carouselItems.length <= 1) return undefined;
    const intervalId = window.setInterval(() => {
      startCarouselShift(-1);
    }, 2200);
    return () => window.clearInterval(intervalId);
  }, [carouselItems.length, startCarouselShift]);

  useEffect(
    () => () => {
      if (carouselFrameRef.current !== null) {
        window.cancelAnimationFrame(carouselFrameRef.current);
      }
      if (carouselTimerRef.current !== null) {
        window.clearTimeout(carouselTimerRef.current);
      }
      if (carouselResetFrameRef.current !== null) {
        window.cancelAnimationFrame(carouselResetFrameRef.current);
      }
    },
    [],
  );

  return (
    <section className="image-workbench-page ecommerce-template-page" aria-label="示例模板">
      <header className="image-workbench-topbar">
        <button type="button" className="image-workbench-back-to-more" onClick={onOpenMore}>
          工具盒
        </button>
        <div className="image-workbench-tool-strip" aria-label="电商工具入口">
          <button type="button" onClick={onOpenEcommerce}>
            <ShoppingOutlined />
            电商生成
          </button>
          <button type="button" className="is-active">
            <TagsOutlined />
            示例模板
          </button>
        </div>
      </header>

      <div className="image-workbench-subbar">
        <button type="button" className="image-workbench-icon-btn" aria-label="返回工具盒" onClick={onOpenMore}>
          <ArrowLeftOutlined />
        </button>
        <strong>示例模板</strong>
        <div className="image-workbench-camera-summary" aria-label="模板数量">
          <strong>{filteredTemplates.length} 个模板</strong>
          <span>最近项目 {projects.length}</span>
        </div>
      </div>

      <main className="ecommerce-template-page__scroll omni-commerce-page">
        <section className={`ecommerce-template-apple-carousel${carouselIsResetting ? " is-resetting" : ""}`} aria-label="苹果卡片式模板轮播">
          <div className="ecommerce-template-apple-carousel__stage" aria-roledescription="carousel">
            <div className="ecommerce-template-apple-carousel__deck">
              {carouselSlotOffsets.map((slotOffset) => {
                const itemIndex = getPositiveModulo(carouselIndex + slotOffset, carouselItems.length);
                const item = carouselItems[itemIndex];
                const visualOffset = slotOffset - (carouselMotion?.direction ?? 0) * (carouselMotion?.progress ?? 0);
                const isActive = visualOffset === 0;

                if (!item) return null;

                return (
                  <button
                    key={slotOffset}
                    type="button"
                    className={`ecommerce-template-apple-card${isActive ? " is-active" : ""}`}
                    style={getAppleCarouselCardStyle(visualOffset)}
                    aria-label={`套用模板：${item.title}`}
                    aria-pressed={isActive}
                    onClick={() => {
                      if (isActive) {
                        onSelectTemplate?.(item);
                        return;
                      }
                      startCarouselShift(slotOffset);
                    }}
                  >
                    <img src={item.imageUrl} alt="" />
                  </button>
                );
              })}
            </div>
          </div>
        </section>

        <section className="omni-commerce-band ecommerce-template-page__band" aria-labelledby="commerce-template-title">
          <div className="omni-commerce-section-head">
            <div>
              <span>
                <TagsOutlined />
                示例模板
              </span>
              <h2 id="commerce-template-title">常用电商场景</h2>
            </div>
            <label className="omni-commerce-search">
              <SearchOutlined />
              <input value={templateSearch} placeholder="搜索模板" onChange={(event) => setTemplateSearch(event.target.value)} />
            </label>
          </div>

          <div className="omni-commerce-filter" role="tablist" aria-label="模板分类">
            {templateCategories.map((category) => (
              <button
                key={category}
                type="button"
                role="tab"
                aria-selected={activeTemplateCategory === category}
                className={activeTemplateCategory === category ? "is-active" : ""}
                onClick={() => setActiveTemplateCategory(category)}
              >
                {category}
              </button>
            ))}
          </div>

          <div className="omni-commerce-template-grid motion-stagger">
            {filteredTemplates.map((item) => (
              <article key={item.title} className="omni-commerce-template">
                <button type="button" className="omni-commerce-template__select" onClick={() => onSelectTemplate?.(item)}>
                  <img src={item.imageUrl} alt={item.title} />
                  <div>
                    <span>{item.category}</span>
                    <strong>{item.title}</strong>
                    <p>{item.summary}</p>
                    <em>选择此场景</em>
                  </div>
                </button>
              </article>
            ))}
          </div>
        </section>

        <section className="omni-commerce-band ecommerce-template-page__band omni-commerce-band--projects" aria-labelledby="commerce-project-title">
          <div className="omni-commerce-section-head">
            <div>
              <span>
                <CheckCircleOutlined />
                最近处理
              </span>
              <h2 id="commerce-project-title">最近项目</h2>
            </div>
            <button type="button" className="omni-commerce-text-button" onClick={onStartCreate}>
              新建项目
            </button>
          </div>

          {projects.length ? (
            <div className="omni-commerce-project-grid motion-stagger">
              {projects.slice(0, 4).map((project, index) => (
                <article key={project.id} className="omni-commerce-project">
                  <button type="button" onClick={() => onOpenProject(project)}>
                    <img src={project.thumbnailUrl || templateCases[index % templateCases.length]!.imageUrl} alt="" />
                    <span>{project.description || "最近更新的电商项目"}</span>
                    <strong>{project.name || `预览项目 ${index + 1}`}</strong>
                  </button>
                  {onDeleteProject ? (
                    <button type="button" className="omni-commerce-project__delete" aria-label={`删除项目 ${project.name}`} onClick={() => onDeleteProject(project)}>
                      <DeleteOutlined />
                    </button>
                  ) : null}
                </article>
              ))}
            </div>
          ) : (
            <div className="omni-commerce-empty">
              <PlayCircleOutlined />
              <strong>还没有最近项目</strong>
              <span>完成一次生成后，这里会显示最近处理的商品内容。</span>
            </div>
          )}
        </section>
      </main>

      <footer className="image-workbench-status">
        <span>模板</span>
        <p>选择模板后会回到电商生成并自动套用场景。</p>
        <em>{activeTemplateCategory}</em>
      </footer>
    </section>
  );
}

export default EcommerceTemplatesPage;
