import { type ChangeEvent, type MouseEvent, useMemo } from "react";
import { Upload, RefreshCw, Eye, Trash2, X, Pencil, Check } from "lucide-react";
import type { Material } from "@/shared/types/material";

interface MaterialSelectorProps {
  materials: Material[];
  selectedMaterials: string[];
  isFetching: boolean;
  lastMaterialCount: number;
  editingMaterialId: string | null;
  editMaterialName: string;
  isUploading: boolean;
  uploadProgress: number;
  uploadError: string | null;
  fetchError: string | null;
  apiBase: string;
  onUploadChange: (event: ChangeEvent<HTMLInputElement>) => void;
  onRefresh: () => void;
  onToggleMaterial: (id: string) => void;
  onPreviewMaterial: (path: string) => void;
  onStartEditing: (material: Material, event: MouseEvent) => void;
  onEditNameChange: (value: string) => void;
  onSaveEditing: (materialId: string, event: MouseEvent) => void;
  onCancelEditing: (event: MouseEvent) => void;
  onDeleteMaterial: (id: string) => void;
  onClearUploadError: () => void;
  registerMaterialRef: (id: string, element: HTMLDivElement | null) => void;
  embedded?: boolean;
}

export function MaterialSelector({
  materials,
  selectedMaterials,
  isFetching,
  lastMaterialCount,
  editingMaterialId,
  editMaterialName,
  isUploading,
  uploadProgress,
  uploadError,
  fetchError,
  apiBase,
  onUploadChange,
  onRefresh,
  onToggleMaterial,
  onPreviewMaterial,
  onStartEditing,
  onEditNameChange,
  onSaveEditing,
  onCancelEditing,
  onDeleteMaterial,
  onClearUploadError,
  registerMaterialRef,
  embedded = false,
}: MaterialSelectorProps) {
  const selectedSet = useMemo(() => new Set(selectedMaterials), [selectedMaterials]);
  const isFull = selectedMaterials.length >= 4;

  const content = (
    <>
      <div className="flex justify-between items-center gap-2 mb-4">
        {!embedded ? (
          <h2 className="text-base sm:text-lg font-semibold text-white flex items-center gap-2 min-w-0">
            <span className="shrink-0">视频素材</span>
            <span className="text-[11px] sm:text-xs text-gray-400/90 font-normal truncate">
              (上传自拍视频，最多可选4个)
            </span>
          </h2>
        ) : (
          <h3 className="text-sm font-medium text-gray-400 min-w-0">
            <span className="shrink-0">视频素材</span>
            <span className="ml-1 text-[11px] text-gray-400/90 font-normal hidden sm:inline">(上传自拍视频，最多可选4个)</span>
          </h3>
        )}
        <div className="flex gap-1.5">
          <input
            type="file"
            id="video-upload"
            accept="video/*"
            onChange={onUploadChange}
            className="hidden"
          />
          <label
            htmlFor="video-upload"
            className={`px-2 py-1 text-xs rounded cursor-pointer transition-all whitespace-nowrap flex items-center gap-1 ${isUploading
              ? "bg-gray-600 cursor-not-allowed text-gray-400"
              : "bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white"
              }`}
          >
            <Upload className="h-3.5 w-3.5" />
            上传
          </label>
          <button
            onClick={onRefresh}
            className="px-2 py-1 text-xs bg-white/10 hover:bg-white/20 rounded text-gray-300 whitespace-nowrap flex items-center gap-1"
          >
            <RefreshCw className="h-3.5 w-3.5" />
            刷新
          </button>
        </div>
      </div>

      {isUploading && (
        <div className="mb-4 p-4 bg-purple-500/10 rounded-xl border border-purple-500/30">
          <div className="flex justify-between text-sm text-purple-300 mb-2">
            <span>上传中...</span>
            <span>{uploadProgress}%</span>
          </div>
          <div className="h-2 bg-black/30 rounded-full overflow-hidden">
            <div
              className="h-full bg-gradient-to-r from-purple-500 to-pink-500 transition-all duration-300"
              style={{ width: `${uploadProgress}%` }}
            />
          </div>
        </div>
      )}

      {uploadError && (
        <div className="mb-4 p-4 bg-red-500/20 text-red-200 rounded-xl text-sm flex justify-between items-center">
          <span>{uploadError}</span>
          <button onClick={onClearUploadError} className="text-red-300 hover:text-white">
            <X className="h-3.5 w-3.5" />
          </button>
        </div>
      )}

      {fetchError ? (
        <div className="p-4 bg-red-500/20 text-red-200 rounded-xl text-sm mb-4">
          获取素材失败: {fetchError}
          <br />
          API: {apiBase}/api/materials/
        </div>
      ) : isFetching && materials.length === 0 ? (
        <div className="space-y-2 max-h-48 sm:max-h-64 overflow-y-auto hide-scrollbar" style={{ contentVisibility: 'auto' }}>
          {Array.from({ length: Math.min(4, Math.max(1, lastMaterialCount || 1)) }).map((_, index) => (
            <div
              key={`material-skeleton-${index}`}
              className="p-3 rounded-lg border border-white/10 bg-white/5 animate-pulse"
            >
              <div className="h-4 w-40 bg-white/10 rounded" />
              <div className="h-3 w-20 bg-white/5 rounded mt-2" />
            </div>
          ))}
        </div>
      ) : materials.length === 0 ? (
        <div className="text-center py-8 text-gray-400">
          <div className="text-5xl mb-4">📁</div>
          <p>暂无视频素材</p>
          <p className="text-sm mt-2">
            点击上方「上传」按钮添加视频素材
          </p>
        </div>
      ) : (
        <div
          className="space-y-2 max-h-48 sm:max-h-64 overflow-y-auto hide-scrollbar"
          style={{ contentVisibility: 'auto' }}
        >
          {materials.map((m) => {
            const isSelected = selectedSet.has(m.id);
            return (
              <div
                key={m.id}
                ref={(el) => registerMaterialRef(m.id, el)}
                className={`p-3 rounded-lg border transition-all flex items-center justify-between group ${isSelected
                  ? "border-purple-500 bg-purple-500/20"
                  : isFull
                    ? "border-white/5 bg-white/[0.02] opacity-50 cursor-not-allowed"
                    : "border-white/10 bg-white/5 hover:border-white/30"
                  }`}
              >
                {editingMaterialId === m.id ? (
                  <div className="flex-1 flex items-center gap-2" onClick={(e) => e.stopPropagation()}>
                    <input
                      value={editMaterialName}
                      onChange={(e) => onEditNameChange(e.target.value)}
                      className="flex-1 bg-black/40 border border-white/20 rounded-md px-2 py-1 text-xs text-white"
                      autoFocus
                    />
                    <button
                      onClick={(e) => onSaveEditing(m.id, e)}
                      className="p-1 text-green-400 hover:text-green-300"
                      title="保存"
                    >
                      <Check className="h-4 w-4" />
                    </button>
                    <button
                      onClick={onCancelEditing}
                      className="p-1 text-gray-400 hover:text-white"
                      title="取消"
                    >
                      <X className="h-4 w-4" />
                    </button>
                  </div>
                ) : (
                  <button onClick={() => onToggleMaterial(m.id)} disabled={isFull && !isSelected} className="flex-1 text-left flex items-center gap-2">
                    {/* 复选框 */}
                    <span
                      className={`flex-shrink-0 w-4 h-4 rounded border flex items-center justify-center text-[10px] ${isSelected
                        ? "border-purple-500 bg-purple-500 text-white"
                        : "border-white/30 text-transparent"
                        }`}
                    >
                      {isSelected ? "✓" : ""}
                    </span>
                    <div className="min-w-0">
                      <div className="text-white text-sm truncate">{m.scene || m.name}</div>
                      <div className="text-gray-400 text-xs">{m.size_mb.toFixed(1)} MB</div>
                    </div>
                  </button>
                )}
                <div className="flex items-center gap-2 pl-2">
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      if (m.path) {
                        onPreviewMaterial(m.path);
                      }
                    }}
                    className="p-1 text-gray-500 hover:text-white opacity-40 group-hover:opacity-100 transition-opacity"
                    title="预览视频"
                  >
                    <Eye className="h-4 w-4" />
                  </button>
                  {editingMaterialId !== m.id && (
                    <button
                      onClick={(e) => onStartEditing(m, e)}
                      className="p-1 text-gray-500 hover:text-white opacity-40 group-hover:opacity-100 transition-opacity"
                      title="重命名"
                    >
                      <Pencil className="h-4 w-4" />
                    </button>
                  )}
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      onDeleteMaterial(m.id);
                    }}
                    className="p-1 text-gray-500 hover:text-red-400 opacity-40 group-hover:opacity-100 transition-opacity"
                    title="删除素材"
                  >
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </>
  );

  if (embedded) return content;

  return (
    <div className="bg-white/5 rounded-2xl p-4 sm:p-6 border border-white/10 backdrop-blur-sm">
      {content}
    </div>
  );
}
