/**
 * 素材选择器 — V21 设计系统
 * 支持批量选择、拖拽排序、预览缩略图、质量分筛选、视图切换
 *
 * 功能：
 * - 批量选择：checkbox 多选 + 全选/反选 + Shift 连选
 * - 拖拽排序：HTML5 DnD，已选素材可拖拽调整顺序
 * - 预览缩略图：悬浮放大预览（视频显示时长角标）
 * - 筛选增强：类型筛选 + 质量分筛选
 * - 视图切换：网格视图 / 列表视图
 */
import React, {
  useState,
  useMemo,
  useCallback,
  useRef,
  useEffect,
} from "react";
import "./AssetSelector.css";
import { Input, Select, Button } from "@/components/ui";
import type { MediaAsset } from "@/api/editPlans";
import {
  MATERIAL_TYPE_LABELS,
  MATERIAL_TYPE_ICONS,
  QUALITY_OPTIONS,
} from "@/api/editPlans";

/* ──────────── 类型 ──────────── */

export interface AssetSelectorProps {
  assets: MediaAsset[];
  selectedIds?: string[];
  onSelectionChange?: (ids: string[]) => void;
  onAssetDragStart?: (asset: MediaAsset) => void;
  onReorder?: (fromIdx: number, toIdx: number) => void;
  showQualityFilter?: boolean;
  showBatchSelect?: boolean;
  compact?: boolean;
}

type ViewMode = "grid" | "list";

/* ──────────── 工具函数 ──────────── */

/** 格式化文件大小 */
const formatSize = (bytes?: number): string => {
  if (!bytes) return "";
  if (bytes < 1024) return `${bytes}B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
};

/** 格式化时长 */
const formatDuration = (seconds?: number): string => {
  if (!seconds) return "";
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return m > 0 ? `${m}:${s.toString().padStart(2, "0")}` : `${s}s`;
};

/** 获取质量分等级 */
const getQualityLevel = (score?: number): string => {
  if (score == null) return "none";
  if (score >= 90) return "excellent";
  if (score >= 70) return "good";
  if (score >= 50) return "fair";
  return "poor";
};

/** 质量分颜色 */
const getQualityColor = (score?: number): string => {
  if (score == null) return "var(--text-secondary)";
  if (score >= 90) return "var(--success-color, #10b981)";
  if (score >= 70) return "var(--primary-color, #6366f1)";
  if (score >= 50) return "var(--warning-color, #f59e0b)";
  return "var(--error-color, #ef4444)";
};

/* ──────────── 类型筛选选项 ──────────── */

const TYPE_OPTIONS = [
  { value: "", label: "全部类型" },
  { value: "video", label: "🎬 视频" },
  { value: "image", label: "🖼️ 图片" },
  { value: "audio", label: "🎵 音频" },
];

/* ──────────── 组件 ──────────── */

const AssetSelector: React.FC<AssetSelectorProps> = ({
  assets,
  selectedIds = [],
  onSelectionChange,
  onAssetDragStart,
  onReorder,
  showQualityFilter = true,
  showBatchSelect = true,
  compact = false,
}) => {
  /* ── 搜索 & 筛选 ── */
  const [searchText, setSearchText] = useState("");
  const [filterType, setFilterType] = useState("");
  const [filterQuality, setFilterQuality] = useState("");
  const [viewMode, setViewMode] = useState<ViewMode>("grid");

  /* ── 拖拽状态 ── */
  const [dragIdx, setDragIdx] = useState<number | null>(null);
  const [dragOverIdx, setDragOverIdx] = useState<number | null>(null);

  /* ── 悬浮预览 ── */
  const [previewAsset, setPreviewAsset] = useState<MediaAsset | null>(null);
  const [previewPos, setPreviewPos] = useState({ x: 0, y: 0 });
  const previewTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  /* ── Shift 连选 ── */
  const lastClickedIdx = useRef<number | null>(null);

  /* ── 过滤后的素材列表 ── */
  const filteredAssets = useMemo(() => {
    let list = assets;
    if (searchText) {
      const q = searchText.toLowerCase();
      list = list.filter(
        (a) =>
          a.name.toLowerCase().includes(q) ||
          a.tags.some((t) => t.toLowerCase().includes(q)),
      );
    }
    if (filterType) {
      list = list.filter((a) => a.type === filterType);
    }
    if (filterQuality) {
      const opt = QUALITY_OPTIONS.find((o) => o.value === filterQuality);
      if (opt?.min != null && opt?.max != null) {
        list = list.filter(
          (a) =>
            a.quality_score != null &&
            a.quality_score >= opt.min! &&
            a.quality_score <= opt.max!,
        );
      }
    }
    return list;
  }, [assets, searchText, filterType, filterQuality]);

  /* ── 选中状态 ── */
  const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);

  /* ── 选择操作 ── */
  const toggleSelect = useCallback(
    (asset: MediaAsset, idx: number, shiftKey: boolean) => {
      if (!onSelectionChange) return;

      if (shiftKey && lastClickedIdx.current !== null) {
        // Shift 连选
        const start = Math.min(lastClickedIdx.current, idx);
        const end = Math.max(lastClickedIdx.current, idx);
        const rangeIds = filteredAssets.slice(start, end + 1).map((a) => a.id);
        const newSet = new Set(selectedIds);
        rangeIds.forEach((id) => newSet.add(id));
        onSelectionChange(Array.from(newSet));
      } else {
        const newSet = new Set(selectedIds);
        if (newSet.has(asset.id)) {
          newSet.delete(asset.id);
        } else {
          newSet.add(asset.id);
        }
        onSelectionChange(Array.from(newSet));
      }
      lastClickedIdx.current = idx;
    },
    [onSelectionChange, selectedIds, filteredAssets],
  );

  const clearSelection = useCallback(() => {
    onSelectionChange?.([]);
  }, [onSelectionChange]);

  /* ── 拖拽排序 ── */
  const handleDragStart = useCallback(
    (e: React.DragEvent, idx: number) => {
      setDragIdx(idx);
      e.dataTransfer.effectAllowed = "move";
      e.dataTransfer.setData("text/plain", String(idx));
      // 设置素材数据，供 TimelinePanel 接收（P1-2 修复）
      e.dataTransfer.setData(
        "application/x-media-asset",
        JSON.stringify(filteredAssets[idx]),
      );
      // 批量拖拽：如果有多个选中素材，一起携带
      if (
        selectedIds.length > 1 &&
        selectedIds.includes(filteredAssets[idx].id)
      ) {
        const batchAssets = filteredAssets.filter((a) =>
          selectedIds.includes(a.id),
        );
        e.dataTransfer.setData(
          "application/x-media-assets",
          JSON.stringify(batchAssets),
        );
      }
      // 通知父组件素材拖拽开始
      if (onAssetDragStart) {
        onAssetDragStart(filteredAssets[idx]);
      }
    },
    [filteredAssets, selectedIds, onAssetDragStart],
  );

  const handleDragOver = useCallback(
    (e: React.DragEvent, idx: number) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "move";
      if (dragIdx === null || dragIdx === idx) return;
      setDragOverIdx(idx);
    },
    [dragIdx],
  );

  const handleDrop = useCallback(
    (e: React.DragEvent, toIdx: number) => {
      e.preventDefault();
      if (dragIdx !== null && dragIdx !== toIdx && onReorder) {
        onReorder(dragIdx, toIdx);
      }
      setDragIdx(null);
      setDragOverIdx(null);
    },
    [dragIdx, onReorder],
  );

  const handleDragEnd = useCallback(() => {
    setDragIdx(null);
    setDragOverIdx(null);
  }, []);

  /* ── 悬浮预览 ── */
  const handleMouseEnter = useCallback(
    (asset: MediaAsset, e: React.MouseEvent) => {
      if (previewTimer.current) clearTimeout(previewTimer.current);
      previewTimer.current = setTimeout(() => {
        const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
        setPreviewAsset(asset);
        setPreviewPos({
          x: rect.right + 12,
          y: Math.max(8, rect.top - 20),
        });
      }, 400);
    },
    [],
  );

  const handleMouseLeave = useCallback(() => {
    if (previewTimer.current) {
      clearTimeout(previewTimer.current);
      previewTimer.current = null;
    }
    setPreviewAsset(null);
  }, []);

  // 清理定时器
  useEffect(() => {
    return () => {
      if (previewTimer.current) clearTimeout(previewTimer.current);
    };
  }, []);

  /* ── 点击卡片 ── */
  const handleCardClick = useCallback(
    (asset: MediaAsset, idx: number, e: React.MouseEvent) => {
      // 如果点击的是 checkbox 区域，不触发卡片点击
      const target = e.target as HTMLElement;
      if (target.closest("[data-checkbox]")) return;
      toggleSelect(asset, idx, e.shiftKey);
    },
    [toggleSelect],
  );

  /* ──────────── 渲染 ──────────── */

  const hasSelection = selectedIds.length > 0;

  return (
    <div className="as-container">
      {/* ═══ 工具栏 ═══ */}
      <div className="as-toolbar">
        <div className="as-toolbar-left">
          <div className="as-search">
            <Input
              placeholder="搜索素材..."
              value={searchText}
              onChange={(e) => setSearchText(e.target.value)}
              prefix="🔍"
            />
          </div>
          <Select
            value={filterType}
            onChange={(v: string) => setFilterType(v)}
            options={TYPE_OPTIONS}
          />
          {showQualityFilter && (
            <Select
              value={filterQuality}
              onChange={(v: string) => setFilterQuality(v)}
              options={QUALITY_OPTIONS}
            />
          )}
        </div>
        <div className="as-toolbar-right">
          <button
            className={`as-view-btn${viewMode === "grid" ? " active" : ""}`}
            onClick={() => setViewMode("grid")}
            title="网格视图"
          >
            ⊞
          </button>
          <button
            className={`as-view-btn${viewMode === "list" ? " active" : ""}`}
            onClick={() => setViewMode("list")}
            title="列表视图"
          >
            ☰
          </button>
        </div>
      </div>

      {/* ═══ 批量操作栏 ═══ */}
      {showBatchSelect && hasSelection && (
        <div className="as-batch-bar">
          <span className="as-batch-bar-count">
            已选 {selectedIds.length} 项
          </span>
          <div className="as-batch-bar-actions">
            <Button buttonType="ghost" buttonSize="sm" onClick={clearSelection}>
              取消选择
            </Button>
          </div>
        </div>
      )}

      {/* ═══ 素材列表 ═══ */}
      <div className="as-body">
        {filteredAssets.length === 0 ? (
          <div className="as-empty">
            <div className="as-empty-icon">📂</div>
            <p>暂无素材</p>
          </div>
        ) : viewMode === "grid" ? (
          /* ── 网格视图 ── */
          <div className={`as-grid${compact ? " compact" : ""}`}>
            {filteredAssets.map((asset, idx) => {
              const isSelected = selectedSet.has(asset.id);
              const isDragging = dragIdx === idx;
              const isDragOver = dragOverIdx === idx;
              const qualityLevel = getQualityLevel(asset.quality_score);

              return (
                <div
                  key={asset.id}
                  className={[
                    "as-card",
                    isSelected ? "selected" : "",
                    isDragging ? "dragging" : "",
                    isDragOver ? "drag-over" : "",
                    showBatchSelect ? "has-checkbox" : "",
                  ]
                    .filter(Boolean)
                    .join(" ")}
                  draggable
                  onDragStart={(e) => handleDragStart(e, idx)}
                  onDragOver={(e) => handleDragOver(e, idx)}
                  onDrop={(e) => handleDrop(e, idx)}
                  onDragEnd={handleDragEnd}
                  onClick={(e) => handleCardClick(asset, idx, e)}
                  onMouseEnter={(e) => handleMouseEnter(asset, e)}
                  onMouseLeave={handleMouseLeave}
                >
                  {/* 缩略图 */}
                  <div className="as-card-thumb">
                    {asset.thumbnail_url ? (
                      <img
                        src={asset.thumbnail_url}
                        alt={asset.name}
                        loading="lazy"
                      />
                    ) : (
                      <span className="as-card-thumb-icon">
                        {MATERIAL_TYPE_ICONS[asset.type]}
                      </span>
                    )}

                    {/* Checkbox */}
                    {showBatchSelect && (
                      <span
                        data-checkbox
                        className={`as-card-checkbox${isSelected ? " checked" : ""}`}
                        onClick={(e) => {
                          e.stopPropagation();
                          toggleSelect(asset, idx, e.shiftKey);
                        }}
                      />
                    )}

                    {/* 类型角标 */}
                    <span className="as-card-type-badge">
                      {MATERIAL_TYPE_LABELS[asset.type]}
                    </span>

                    {/* 时长角标 */}
                    {asset.duration != null && (
                      <span className="as-card-duration">
                        {formatDuration(asset.duration)}
                      </span>
                    )}

                    {/* 质量分角标 */}
                    {asset.quality_score != null && (
                      <span
                        className={`as-card-quality ${qualityLevel}`}
                        title={`质量分: ${asset.quality_score}`}
                      >
                        {asset.quality_score}
                      </span>
                    )}
                  </div>

                  {/* 信息 */}
                  <div className="as-card-info">
                    <p className="as-card-name" title={asset.name}>
                      {asset.name}
                    </p>
                    <div className="as-card-meta">{formatSize(asset.size)}</div>
                  </div>
                </div>
              );
            })}
          </div>
        ) : (
          /* ── 列表视图 ── */
          <div className="as-list">
            {filteredAssets.map((asset, idx) => {
              const isSelected = selectedSet.has(asset.id);
              const isDragging = dragIdx === idx;
              const isDragOver = dragOverIdx === idx;

              return (
                <div
                  key={asset.id}
                  className={[
                    "as-list-item",
                    isSelected ? "selected" : "",
                    isDragging ? "dragging" : "",
                    isDragOver ? "drag-over" : "",
                  ]
                    .filter(Boolean)
                    .join(" ")}
                  draggable
                  onDragStart={(e) => handleDragStart(e, idx)}
                  onDragOver={(e) => handleDragOver(e, idx)}
                  onDrop={(e) => handleDrop(e, idx)}
                  onDragEnd={handleDragEnd}
                  onClick={(e) => handleCardClick(asset, idx, e)}
                  onMouseEnter={(e) => handleMouseEnter(asset, e)}
                  onMouseLeave={handleMouseLeave}
                >
                  {/* 拖拽手柄 */}
                  <span className="as-list-item-drag" title="拖拽排序">
                    ⠿
                  </span>

                  {/* Checkbox */}
                  {showBatchSelect && (
                    <span
                      data-checkbox
                      className={`as-list-item-checkbox${isSelected ? " checked" : ""}`}
                      onClick={(e) => {
                        e.stopPropagation();
                        toggleSelect(asset, idx, e.shiftKey);
                      }}
                    />
                  )}

                  {/* 图标 */}
                  <span className="as-list-item-icon">
                    {MATERIAL_TYPE_ICONS[asset.type]}
                  </span>

                  {/* 信息 */}
                  <div className="as-list-item-info">
                    <div className="as-list-item-name">{asset.name}</div>
                    <div className="as-list-item-meta">
                      {MATERIAL_TYPE_LABELS[asset.type]}
                      {asset.duration != null &&
                        ` · ${formatDuration(asset.duration)}`}
                      {asset.size != null && ` · ${formatSize(asset.size)}`}
                    </div>
                  </div>

                  {/* 质量分 */}
                  {asset.quality_score != null && (
                    <span
                      className="as-list-item-quality"
                      style={{ color: getQualityColor(asset.quality_score) }}
                    >
                      {asset.quality_score}分
                    </span>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* ═══ 悬浮预览 ═══ */}
      {previewAsset && (
        <div
          className="as-preview-overlay"
          style={{ left: previewPos.x, top: previewPos.y }}
        >
          <div className="as-preview-overlay-thumb">
            {previewAsset.thumbnail_url ? (
              <img src={previewAsset.thumbnail_url} alt={previewAsset.name} />
            ) : (
              <span className="as-preview-overlay-thumb-icon">
                {MATERIAL_TYPE_ICONS[previewAsset.type]}
              </span>
            )}
          </div>
          <p className="as-preview-overlay-name">{previewAsset.name}</p>
          <div className="as-preview-overlay-meta">
            <span>类型: {MATERIAL_TYPE_LABELS[previewAsset.type]}</span>
            {previewAsset.duration != null && (
              <span>时长: {formatDuration(previewAsset.duration)}</span>
            )}
            {previewAsset.size != null && (
              <span>大小: {formatSize(previewAsset.size)}</span>
            )}
            {previewAsset.quality_score != null && (
              <span>质量分: {previewAsset.quality_score}</span>
            )}
            {previewAsset.tags.length > 0 && (
              <span>标签: {previewAsset.tags.join(", ")}</span>
            )}
          </div>
        </div>
      )}
    </div>
  );
};

export default AssetSelector;
