import {
  CloudUploadOutlined,
  CloseOutlined,
  FileImageOutlined,
  LoadingOutlined,
  QuestionCircleOutlined,
  ReloadOutlined,
  SettingOutlined,
} from "@ant-design/icons";
import { createPortal } from "react-dom";
import type { CSSProperties, ChangeEvent, DragEvent, MutableRefObject, RefObject } from "react";
import { useState } from "react";

type ProductSetOutputKey = "set" | "detail" | "model" | "video";
type CloneOutputKey = ProductSetOutputKey | "hot";
type CloneSetCountKey = "selling" | "white" | "scene";
type CloneModelPanelTab = "scene" | "model";
type CloneReferenceMode = "upload" | "link";
type CloneReplicateLevelKey = "style" | "high";
type CloneVideoQualityKey = "standard" | "high" | "ultra";
type CloneBasicSelectKey = "platform" | "market" | "language" | "ratio";
type CloneModelSelectKey = "gender" | "age" | "ethnicity" | "body";

interface CloneImageItem {
  id: string;
  src: string;
  name: string;
}

interface CloneBasicSelectItem {
  key: CloneBasicSelectKey;
  label: string;
  value: string;
  options: string[];
  onChange: (value: string) => void;
}

interface CloneModelSelectItem {
  key: CloneModelSelectKey;
  label: string;
  value: string;
  options: string[];
  onChange: (value: string) => void;
}

interface CloneSetCountOption {
  key: CloneSetCountKey;
  title: string;
  desc: string;
}

interface CloneOutputOption {
  key: CloneOutputKey;
  label: string;
}

interface CloneReplicateLevelOption {
  key: CloneReplicateLevelKey;
  title: string;
  desc: string;
}

interface CloneVideoQualityOption {
  key: CloneVideoQualityKey;
  label: string;
  desc: string;
}

interface CloneDetailModule {
  id: string;
  title: string;
  desc: string;
}

interface EcommerceClonePanelProps {
  productInputRef: RefObject<HTMLInputElement>;
  cloneReferenceInputRef: RefObject<HTMLInputElement>;
  productImages: CloneImageItem[];
  isProductUploadDragging: boolean;
  cloneOutput: CloneOutputKey;
  cloneOutputOptions: CloneOutputOption[];
  cloneBasicSelects: CloneBasicSelectItem[];
  openCloneBasicSelect: CloneBasicSelectKey | null;
  cloneReferenceMode: CloneReferenceMode;
  cloneReferenceImages: CloneImageItem[];
  maxCloneReferenceImages: number;
  cloneReplicateLevel: CloneReplicateLevelKey;
  cloneReplicateLevelOptions: CloneReplicateLevelOption[];
  cloneSetCounts: Record<CloneSetCountKey, number>;
  cloneSetCountOptions: CloneSetCountOption[];
  cloneSetTotal: number;
  minCloneSetTotal: number;
  maxCloneSetTotal: number;
  selectedCloneDetailModules: string[];
  cloneDetailModules: CloneDetailModule[];
  cloneModelPanelTab: CloneModelPanelTab;
  tryOnScenes: string[];
  selectedCloneModelScenes: string[];
  cloneModelCustomScene: string;
  cloneModelSelects: CloneModelSelectItem[];
  openCloneModelSelect: CloneModelSelectKey | null;
  cloneModelSelectDropUp: boolean;
  cloneVideoQuality: CloneVideoQualityKey;
  cloneVideoQualityOptions: CloneVideoQualityOption[];
  cloneVideoDuration: number;
  cloneVideoDurationMin: number;
  cloneVideoDurationMax: number;
  cloneVideoDurationStyle: CSSProperties;
  cloneVideoSmart: boolean;
  canGenerate: boolean;
  status: string;
  lastFailedActionRef: MutableRefObject<(() => void) | null>;
  setIsProductUploadDragging: (value: boolean) => void;
  handleProductDrop: (event: DragEvent<HTMLDivElement>) => void;
  removeProductImage: (id: string) => void;
  handleProductUpload: (event: ChangeEvent<HTMLInputElement>) => void;
  handleCloneOutputChange: (value: CloneOutputKey) => void;
  setOpenCloneBasicSelect: (value: CloneBasicSelectKey | null) => void;
  setCloneReferenceMode: (value: CloneReferenceMode) => void;
  handleCloneReferenceUpload: (event: ChangeEvent<HTMLInputElement>) => void;
  isCloneReferenceDragging: boolean;
  handleCloneReferenceDragOver: (event: DragEvent<HTMLButtonElement>) => void;
  handleCloneReferenceDragLeave: (event: DragEvent<HTMLButtonElement>) => void;
  handleCloneReferenceDrop: (event: DragEvent<HTMLButtonElement>) => void;
  setCloneReplicateLevel: (value: CloneReplicateLevelKey) => void;
  startCloneSetCountHold: (key: CloneSetCountKey, delta: -1 | 1, disabled: boolean) => void;
  clearCloneSetCountHold: () => void;
  toggleCloneDetailModule: (id: string) => void;
  setCloneModelPanelTab: (value: CloneModelPanelTab) => void;
  toggleCloneModelScene: (scene: string) => void;
  setCloneModelCustomScene: (value: string) => void;
  setOpenCloneModelSelect: (value: CloneModelSelectKey | null) => void;
  setCloneModelSelectDropUp: (value: boolean) => void;
  setCloneVideoQuality: (value: CloneVideoQualityKey) => void;
  setCloneVideoDuration: (value: number) => void;
  clampCloneVideoDuration: (value: number) => number;
  setCloneVideoSmart: (updater: (current: boolean) => boolean) => void;
  handleGenerate: () => void;
  onCancelGenerate: () => void;
  formatRatioDisplayValue: (value: string) => string;
  onStartVideoPlan?: () => void;
}

export default function EcommerceClonePanel({
  productInputRef,
  cloneReferenceInputRef,
  productImages,
  isProductUploadDragging,
  cloneOutput,
  cloneOutputOptions,
  cloneBasicSelects,
  openCloneBasicSelect,
  cloneReferenceMode,
  cloneReferenceImages,
  maxCloneReferenceImages,
  cloneReplicateLevel,
  cloneReplicateLevelOptions,
  cloneSetCounts,
  cloneSetCountOptions,
  cloneSetTotal,
  minCloneSetTotal,
  maxCloneSetTotal,
  selectedCloneDetailModules,
  cloneDetailModules,
  cloneModelPanelTab,
  tryOnScenes,
  selectedCloneModelScenes,
  cloneModelCustomScene,
  cloneModelSelects,
  openCloneModelSelect,
  cloneModelSelectDropUp,
  cloneVideoQuality,
  cloneVideoQualityOptions,
  cloneVideoDuration,
  cloneVideoDurationMin,
  cloneVideoDurationMax,
  cloneVideoDurationStyle,
  cloneVideoSmart,
  canGenerate,
  status,
  lastFailedActionRef,
  setIsProductUploadDragging,
  handleProductDrop,
  removeProductImage,
  handleProductUpload,
  handleCloneOutputChange,
  setOpenCloneBasicSelect,
  setCloneReferenceMode,
  handleCloneReferenceUpload,
  isCloneReferenceDragging,
  handleCloneReferenceDragOver,
  handleCloneReferenceDragLeave,
  handleCloneReferenceDrop,
  setCloneReplicateLevel,
  startCloneSetCountHold,
  clearCloneSetCountHold,
  toggleCloneDetailModule,
  setCloneModelPanelTab,
  toggleCloneModelScene,
  setCloneModelCustomScene,
  setOpenCloneModelSelect,
  setCloneModelSelectDropUp,
  setCloneVideoQuality,
  setCloneVideoDuration,
  clampCloneVideoDuration,
  setCloneVideoSmart,
  handleGenerate,
  onCancelGenerate,
  formatRatioDisplayValue,
  onStartVideoPlan,
}: EcommerceClonePanelProps) {
  const [zoomImage, setZoomImage] = useState<{ src: string; x: number; y: number } | null>(null);

  const handleFileMouseEnter = (src: string, event: React.MouseEvent<HTMLElement>) => {
    const rect = event.currentTarget.getBoundingClientRect();
    setZoomImage({ src, x: rect.left + rect.width / 2, y: rect.top });
  };

  const handleFileMouseLeave = () => setZoomImage(null);
  const platformSelect = cloneBasicSelects.find((item) => item.key === "platform");
  const languageSelects = cloneBasicSelects.filter((item) => item.key === "market" || item.key === "language");
  const ratioSelect = cloneBasicSelects.find((item) => item.key === "ratio");

  const renderBasicSelect = (item: CloneBasicSelectItem) => {
    const hasMultipleOptions = item.options.length > 1;
    const isOpen = hasMultipleOptions && openCloneBasicSelect === item.key;
    return (
      <div key={item.key} className="clone-ai-basic-select" data-clone-basic-select>
        <button
          type="button"
          className={`${isOpen ? "is-open" : ""}${hasMultipleOptions ? "" : " is-static"}`}
          aria-expanded={hasMultipleOptions ? isOpen : undefined}
          aria-haspopup={hasMultipleOptions ? "listbox" : undefined}
          aria-controls={hasMultipleOptions ? `clone-basic-select-${item.key}` : undefined}
          onClick={() => setOpenCloneBasicSelect(hasMultipleOptions ? (isOpen ? null : item.key) : null)}
        >
          <span>{item.label}</span>
          <strong>{item.key === "ratio" ? formatRatioDisplayValue(item.value) : item.value}</strong>
          {hasMultipleOptions ? <i aria-hidden="true" /> : null}
        </button>
        {hasMultipleOptions && isOpen ? (
          <div id={`clone-basic-select-${item.key}`} className="clone-ai-basic-select__menu" role="listbox">
            {item.options.map((option) => (
              <button
                key={option}
                type="button"
                className={item.value === option ? "is-active" : ""}
                role="option"
                aria-selected={item.value === option}
                onClick={() => {
                  item.onChange(option);
                  setOpenCloneBasicSelect(null);
                }}
              >
                {item.key === "ratio" ? formatRatioDisplayValue(option) : option}
              </button>
            ))}
          </div>
        ) : null}
      </div>
    );
  };

  return (
    <>
      <div className="product-clone-panel__scroll clone-ai-panel">
        <header className="clone-ai-logo">
          <span className="clone-ai-logo__mark">AI</span>
          <strong>电商生成</strong>
        </header>

        <section className="clone-ai-card">
          <h2>
            <CloudUploadOutlined />
            上传商品原图
          </h2>
          <div
            role="button"
            tabIndex={0}
            className={`clone-ai-upload-zone${isProductUploadDragging ? " is-dragging" : ""}`}
            onClick={() => productInputRef.current?.click()}
            onKeyDown={(event) => {
              if (event.target !== event.currentTarget) return;
              if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                productInputRef.current?.click();
              }
            }}
            onDragEnter={(event) => {
              event.preventDefault();
              setIsProductUploadDragging(true);
            }}
            onDragOver={(event) => event.preventDefault()}
            onDragLeave={() => setIsProductUploadDragging(false)}
            onDrop={handleProductDrop}
          >
            <div className="clone-ai-upload-main">
              <span className="clone-ai-upload-icon">
                <FileImageOutlined />
              </span>
              <span className="clone-ai-upload-title">拖拽或点击上传</span>
              <strong>
                <span aria-hidden="true">+</span>
                上传图片
              </strong>
              <span className="clone-ai-upload-hint">同一产品，最多 7 张</span>
            </div>
            {productImages.length ? (
              <div className="clone-ai-uploaded-files" aria-label="已上传商品原图">
                {productImages.map((item) => (
                  <figure key={item.id} className="clone-ai-uploaded-file">
                    <img src={item.src} alt={item.name} />
                    <span className="uploaded-image-zoom" aria-hidden="true">
                      <img src={item.src} alt="" />
                    </span>
                    <button
                      type="button"
                      onClick={(event) => {
                        event.stopPropagation();
                        removeProductImage(item.id);
                      }}
                      aria-label={`删除${item.name}`}
                    >
                      <CloseOutlined />
                    </button>
                  </figure>
                ))}
              </div>
            ) : null}
          </div>
          <input ref={productInputRef} type="file" accept="image/*" multiple onChange={handleProductUpload} aria-label="上传商品图片" />
        </section>

        <section className="clone-ai-card clone-ai-settings-card clone-ai-settings-card--mode">
          <h2>
            <SettingOutlined />
            生成设置
          </h2>
          <div className="clone-ai-settings-section">
            <span className="clone-ai-settings-label">生成内容</span>
            <div className="clone-ai-tag-group" role="toolbar" aria-label="生成内容">
              {cloneOutputOptions.map((option) => (
                <button
                  key={option.key}
                  type="button"
                  className={cloneOutput === option.key ? "is-active" : ""}
                  aria-pressed={cloneOutput === option.key}
                  onClick={() => handleCloneOutputChange(option.key)}
                >
                  {option.label}
                </button>
              ))}
            </div>
          </div>
        </section>

        {platformSelect ? (
          <section className="clone-ai-card clone-ai-settings-card clone-ai-settings-card--platform">
            <span className="clone-ai-settings-label">平台</span>
            <div className="clone-ai-select-group clone-ai-select-group--single">
              {renderBasicSelect(platformSelect)}
            </div>
          </section>
        ) : null}

        {languageSelects.length ? (
          <section className="clone-ai-card clone-ai-settings-card clone-ai-settings-card--language">
            <span className="clone-ai-settings-label">语种</span>
            <div className="clone-ai-select-group clone-ai-select-group--language">
              {languageSelects.map(renderBasicSelect)}
            </div>
          </section>
        ) : null}

        {ratioSelect ? (
          <section className="clone-ai-card clone-ai-settings-card clone-ai-settings-card--ratio">
            <span className="clone-ai-settings-label">尺寸比例</span>
            <div className="clone-ai-select-group clone-ai-select-group--single">
              {renderBasicSelect(ratioSelect)}
            </div>
          </section>
        ) : null}

        {cloneOutput === "set" ? (
          <section className="clone-ai-count-panel" aria-label="套图图片数量">
            <div className="clone-ai-dynamic-head">
              <strong>套图分类设置</strong>
              <span>按类型分配图片张数</span>
            </div>
            <p>可自由调整各类型图片数量，总数 1-16 张</p>
            <div className="clone-ai-count-list">
              {cloneSetCountOptions.map((item) => {
                const count = cloneSetCounts[item.key];
                const decrementDisabled = count <= 0 || cloneSetTotal <= minCloneSetTotal;
                const incrementDisabled = cloneSetTotal >= maxCloneSetTotal;
                return (
                  <div key={item.key} className="clone-ai-count-row">
                    <div className="clone-ai-count-copy">
                      <strong>{item.title}</strong>
                      <span>{item.desc}</span>
                    </div>
                    <div className="clone-ai-count-stepper" aria-label={`${item.title}数量`}>
                      <button
                        type="button"
                        disabled={decrementDisabled}
                        onPointerDown={(event) => {
                          event.preventDefault();
                          startCloneSetCountHold(item.key, -1, decrementDisabled);
                        }}
                        onPointerUp={clearCloneSetCountHold}
                        onPointerLeave={clearCloneSetCountHold}
                        onPointerCancel={clearCloneSetCountHold}
                        onBlur={clearCloneSetCountHold}
                        aria-label={`减少${item.title}`}
                      >
                        -
                      </button>
                      <b>{count}</b>
                      <button
                        type="button"
                        disabled={incrementDisabled}
                        onPointerDown={(event) => {
                          event.preventDefault();
                          startCloneSetCountHold(item.key, 1, incrementDisabled);
                        }}
                        onPointerUp={clearCloneSetCountHold}
                        onPointerLeave={clearCloneSetCountHold}
                        onPointerCancel={clearCloneSetCountHold}
                        onBlur={clearCloneSetCountHold}
                        aria-label={`增加${item.title}`}
                      >
                        +
                      </button>
                    </div>
                  </div>
                );
              })}
            </div>
          </section>
        ) : null}

        {cloneOutput === "detail" ? (
          <section className="clone-ai-module-panel" aria-label="详情图包含模块">
            <div className="clone-ai-dynamic-head">
              <strong>详情模块设置</strong>
              <span>选择要生成的详情页内容</span>
            </div>
            <p>
              包含模块（多选）
              <QuestionCircleOutlined />
            </p>
            <div className="clone-ai-module-list">
              {cloneDetailModules.map((module) => {
                const isSelected = selectedCloneDetailModules.includes(module.id);
                return (
                  <button
                    key={module.id}
                    type="button"
                    className={isSelected ? "is-active" : ""}
                    aria-pressed={isSelected}
                    onClick={() => toggleCloneDetailModule(module.id)}
                  >
                    <strong>{module.title}</strong>
                    <span>{module.desc}</span>
                  </button>
                );
              })}
            </div>
          </section>
        ) : null}

        {cloneOutput === "model" ? (
          <section className="clone-ai-model-panel" aria-label="模特图设置">
            <div className="clone-ai-dynamic-head">
              <strong>模特图设置</strong>
              <span>选择场景或模特形象</span>
            </div>
            <div className="clone-ai-model-tabs" role="tablist" aria-label="模特图设置类型">
              <button
                type="button"
                className={cloneModelPanelTab === "scene" ? "is-active" : ""}
                aria-selected={cloneModelPanelTab === "scene"}
                onClick={() => setCloneModelPanelTab("scene")}
              >
                拍摄场景
              </button>
              <button
                type="button"
                className={cloneModelPanelTab === "model" ? "is-active" : ""}
                aria-selected={cloneModelPanelTab === "model"}
                onClick={() => setCloneModelPanelTab("model")}
              >
                模特形象
              </button>
            </div>
            <div className="clone-ai-model-scroll">
              {cloneModelPanelTab === "scene" ? (
                <div className="clone-ai-model-scenes">
                  <div className="clone-ai-model-scene-grid">
                    {tryOnScenes.map((scene) => {
                      const isSelected = selectedCloneModelScenes.includes(scene);
                      return (
                        <button
                          key={scene}
                          type="button"
                          className={isSelected ? "is-active" : ""}
                          aria-pressed={isSelected}
                          onClick={() => toggleCloneModelScene(scene)}
                        >
                          <span aria-hidden="true" />
                          {scene}
                        </button>
                      );
                    })}
                  </div>
                  <label className="clone-ai-model-textarea">
                    <strong>或自定义描述场景（可选）</strong>
                    <textarea
                      value={cloneModelCustomScene}
                      onChange={(event) => setCloneModelCustomScene(event.target.value)}
                      placeholder="描述你想要的场景：如秋季枫叶小径、暖色调午后阳光、模特倚靠树干..."
                    />
                  </label>
                </div>
              ) : (
                <div className="clone-ai-model-profile">
                  <div className="clone-ai-model-select-grid">
                    {cloneModelSelects.map((item) => {
                      const isOpen = openCloneModelSelect === item.key;
                      return (
                        <div
                          key={item.key}
                          className={`clone-ai-model-select${isOpen ? " is-open" : ""}${
                            isOpen && cloneModelSelectDropUp ? " is-drop-up" : ""
                          }`}
                          data-clone-model-select
                        >
                          <span>{item.label}</span>
                          <button
                            type="button"
                            className={isOpen ? "is-open" : ""}
                            aria-expanded={isOpen}
                            aria-haspopup="listbox"
                            aria-controls={`clone-model-select-${item.key}`}
                            onClick={(event) => {
                              setOpenCloneBasicSelect(null);
                              if (!isOpen) {
                                event.currentTarget.scrollIntoView({ block: "center", inline: "nearest" });
                                const triggerRect = event.currentTarget.getBoundingClientRect();
                                const scrollRect = event.currentTarget.closest(".clone-ai-model-scroll")?.getBoundingClientRect();
                                const lowerBoundary = Math.min(window.innerHeight, scrollRect?.bottom ?? window.innerHeight);
                                const upperBoundary = Math.max(0, scrollRect?.top ?? 0);
                                const estimatedMenuHeight = Math.min(150, item.options.length * 36 + 12);
                                const belowSpace = lowerBoundary - triggerRect.bottom;
                                const aboveSpace = triggerRect.top - upperBoundary;
                                setCloneModelSelectDropUp(belowSpace < estimatedMenuHeight && aboveSpace > belowSpace);
                              } else {
                                setCloneModelSelectDropUp(false);
                              }
                              setOpenCloneModelSelect(isOpen ? null : item.key);
                            }}
                          >
                            <strong>{item.value}</strong>
                            <i aria-hidden="true" />
                          </button>
                          {isOpen ? (
                            <div id={`clone-model-select-${item.key}`} className="clone-ai-model-select__menu" role="listbox">
                              {item.options.map((option) => (
                                <button
                                  key={option}
                                  type="button"
                                  className={item.value === option ? "is-active" : ""}
                                  role="option"
                                  aria-selected={item.value === option}
                                  onClick={() => {
                                    item.onChange(option);
                                    setOpenCloneModelSelect(null);
                                    setCloneModelSelectDropUp(false);
                                  }}
                                >
                                  {option}
                                </button>
                              ))}
                            </div>
                          ) : null}
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
          </section>
        ) : null}

        {cloneOutput === "video" ? (
          <section className="clone-ai-video-panel" aria-label="短视频设置">
            <div className="clone-ai-dynamic-head">
              <strong>短视频设置</strong>
              <span>设置视频质量与时长</span>
            </div>
            <div className="clone-ai-video-section">
              <span className="clone-ai-video-title">视频画质</span>
              <div className="clone-ai-video-options">
                {cloneVideoQualityOptions.map((option) => (
                  <button
                    key={option.key}
                    type="button"
                    className={cloneVideoQuality === option.key ? "is-active" : ""}
                    aria-pressed={cloneVideoQuality === option.key}
                    onClick={() => setCloneVideoQuality(option.key)}
                  >
                    <strong>{option.label}</strong>
                    <span>{option.desc}</span>
                  </button>
                ))}
              </div>
            </div>
            <div className="clone-ai-video-section">
              <div className="clone-ai-video-title-row">
                <span className="clone-ai-video-title">时间设置</span>
                <strong>{cloneVideoDuration}秒</strong>
              </div>
              <div className="clone-ai-duration-control" style={cloneVideoDurationStyle}>
                <input
                  type="range"
                  min={cloneVideoDurationMin}
                  max={cloneVideoDurationMax}
                  step={5}
                  value={cloneVideoDuration}
                  onChange={(event) => setCloneVideoDuration(clampCloneVideoDuration(Number(event.target.value)))}
                  aria-label="短视频时长"
                />
                <div className="clone-ai-duration-scale" aria-hidden="true">
                  <span>5秒</span>
                  <span>15秒</span>
                  <span>30秒</span>
                  <span>45秒</span>
                </div>
              </div>
            </div>
            <button
              type="button"
              className={`clone-ai-video-smart${cloneVideoSmart ? " is-on" : ""}`}
              aria-pressed={cloneVideoSmart}
              onClick={() => setCloneVideoSmart((current) => !current)}
            >
              <span>
                <strong>智能选择</strong>
                <em>根据平台、商品图和尺寸自动匹配推荐参数</em>
              </span>
              <i aria-hidden="true" />
            </button>
          </section>
        ) : null}

        {cloneOutput === "video" && onStartVideoPlan ? (
          <button type="button" className="clone-ai-generate" onClick={onStartVideoPlan}>
            ✦ 一键策划
          </button>
        ) : null}

        <button type="button" className="clone-ai-generate" disabled={!canGenerate || cloneOutput === "video"} onClick={status === "failed" && lastFailedActionRef.current ? lastFailedActionRef.current : handleGenerate} style={cloneOutput === "video" ? { display: "none" } : undefined}>
          {status === "generating" ? <LoadingOutlined /> : status === "failed" ? <ReloadOutlined /> : null}
          {status === "generating" ? "生成中..." : status === "failed" ? "重新生成" : "✦ 开始生成"}
        </button>
        {status === "generating" && cloneOutput !== "video" ? (
          <button type="button" className="clone-ai-generate clone-ai-generate--cancel" onClick={onCancelGenerate}>
            {"\u53d6\u6d88\u751f\u6210"}
          </button>
        ) : null}
      </div>
      {zoomImage
        ? createPortal(
            <div
              className="clone-ai-zoom-portal"
              style={{ left: zoomImage.x, top: zoomImage.y } as CSSProperties}
              onMouseLeave={handleFileMouseLeave}
            >
              <img src={zoomImage.src} alt="" />
            </div>,
            document.body,
          )
        : null}
    </>
  );
}
