import { useState } from "react";
import { api } from "../api/client";
import type { CreativeAsset, AssetDef } from "../types";
import styles from "./AssetUploader.module.css";

const BASE = `${import.meta.env.BASE_URL}api/v1`.replace(/\/+$/, "");

// 可展示缩略图的图片后缀
const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"]);

function isImageFile(fileName: string): boolean {
  const ext = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
  return IMAGE_EXTENSIONS.has(ext);
}

interface Props {
  creativeId: string;
  assets: CreativeAsset[];
  assetDefs: { required: AssetDef[]; optional: AssetDef[] };
  onUpdated: () => void;
}

type ImportMode = "file" | "url";

export default function AssetUploader({ creativeId, assets, assetDefs, onUpdated }: Props) {
  const [mode, setMode] = useState<ImportMode>("file");
  const [uploading, setUploading] = useState(false);
  const [url, setUrl] = useState("");
  const [uploadResult, setUploadResult] = useState<{
    files: Array<{ key: string; fileName: string; fileSize: number; valid: boolean }>;
    warnings: string[];
  } | null>(null);
  const [error, setError] = useState("");

  // === 文件上传 ===
  async function handleFileUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;

    setUploading(true);
    setError("");
    setUploadResult(null);

    try {
      const res = await api.uploadAssets(creativeId, file);
      setUploadResult(res.data);
      onUpdated();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setUploading(false);
      e.target.value = "";
    }
  }

  // === URL 导入 ===
  async function handleUrlImport() {
    if (!url.trim()) return;

    setUploading(true);
    setError("");
    setUploadResult(null);

    try {
      const res = await api.importFromUrl(creativeId, url.trim());
      setUploadResult(res.data);
      onUpdated();
    } catch (err: any) {
      setError(err.message);
    } finally {
      setUploading(false);
    }
  }

  async function handleClear() {
    if (!confirm("确认清除所有素材？")) return;
    try {
      await api.clearAssets(creativeId);
      setUploadResult(null);
      setUrl("");
      onUpdated();
    } catch (err: any) {
      setError(err.message);
    }
  }

  const allDefs = [...assetDefs.required, ...assetDefs.optional];
  const hasAllRequired = assetDefs.required.every((def) =>
    assets.some((a) => a.key === def.key)
  );

  return (
    <div className={styles.wrapper}>
      {/* 模式切换 */}
      <div className={styles.tabs}>
        <button
          className={`${styles.tab} ${mode === "file" ? styles.tabActive : ""}`}
          onClick={() => setMode("file")}
        >
          上传 ZIP
        </button>
        <button
          className={`${styles.tab} ${mode === "url" ? styles.tabActive : ""}`}
          onClick={() => setMode("url")}
        >
          素材 URL
        </button>
      </div>

      {/* 文件上传 */}
      {mode === "file" && (
        <label className={styles.dropZone}>
          <input
            type="file"
            accept=".zip"
            onChange={handleFileUpload}
            disabled={uploading}
            className={styles.fileInput}
          />
          <span className={styles.dropIcon}>📦</span>
          <span className={styles.dropText}>
            {uploading ? "解压中…" : "拖拽或点击上传素材 zip"}
          </span>
          <span className={styles.dropHint}>
            包含 config.json + page.png + map.png ± special.jpeg
          </span>
        </label>
      )}

      {/* URL 导入 */}
      {mode === "url" && (
        <div className={styles.urlRow}>
          <input
            type="url"
            className={styles.urlInput}
            placeholder="https://color2.jccytech.cn/app/zh/pages/detail/6a15..."
            value={url}
            onChange={(e) => setUrl(e.target.value)}
            disabled={uploading}
          />
          <button
            onClick={handleUrlImport}
            disabled={!url.trim() || uploading}
            className={styles.urlBtn}
          >
            {uploading ? "获取中…" : "导入"}
          </button>
        </div>
      )}

      {/* 上传结果 */}
      {uploadResult && uploadResult.warnings.length > 0 && (
        <div className={styles.warnings}>
          {uploadResult.warnings.map((w, i) => (
            <p key={i}>⚠️ {w}</p>
          ))}
        </div>
      )}

      {error && <p className={styles.error}>{error}</p>}

      {/* 文件列表 */}
      {assets.length > 0 && (
        <div className={styles.fileList}>
          <div className={styles.fileListHeader}>
            <span>
              已上传文件 ({assets.filter((a) => a.isRequired).length}/{assetDefs.required.length} 必填)
            </span>
            <button onClick={handleClear} className={styles.clearBtn}>
              清除素材
            </button>
          </div>
          {allDefs.map((def) => {
            const asset = assets.find((a) => a.key === def.key);
            const isRequired = assetDefs.required.some((r) => r.key === def.key);
            const showThumb = asset && isImageFile(def.file);
            return (
              <div key={def.key} className={styles.fileItem}>
                {showThumb ? (
                  <img
                    className={styles.thumb}
                    src={`${BASE}/creatives/${creativeId}/assets/${def.key}`}
                    alt={def.label}
                  />
                ) : (
                  <span className={asset ? styles.fileOk : styles.fileMissing}>
                    {asset ? "✅" : isRequired ? "❌" : "⬜"}
                  </span>
                )}
                <span className={styles.fileName}>{def.file}</span>
                <span className={styles.fileLabel}>
                  {def.label} {!isRequired && "(选填)"}
                </span>
                {asset && (
                  <span className={styles.fileSize}>
                    {(asset.fileSize / 1024).toFixed(0)} KB
                  </span>
                )}
              </div>
            );
          })}
        </div>
      )}

      {!hasAllRequired && assets.length > 0 && (
        <p className={styles.hint}>请上传包含所有必填文件的 zip 包</p>
      )}
    </div>
  );
}
