import { type ChangeEvent, type MouseEvent, useCallback, useMemo, useRef, useState } from "react";
import { Upload, RefreshCw, Eye, Trash2, X, Pencil, Check, Search, ChevronDown } from "lucide-react";
import type { Material } from "@/shared/types/material";
import { SelectPopover } from "@/shared/ui/SelectPopover";

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 [materialFilter, setMaterialFilter] = useState("");
  const materialListContainerRef = useRef<HTMLDivElement | null>(null);
  const selectedSet = useMemo(() => new Set(selectedMaterials), [selectedMaterials]);
  const isFull = selectedMaterials.length >= 4;
  const selectedMaterialItems = useMemo(
    () => selectedMaterials.map((id) => materials.find((m) => m.id === id)).filter((m): m is Material => Boolean(m)),
    [materials, selectedMaterials],
  );
  const filteredMaterials = useMemo(() => {
    const query = materialFilter.trim().toLowerCase();
    if (!query) return materials;
    return materials.filter((m) => (m.scene || m.name).toLowerCase().includes(query));
  }, [materialFilter, materials]);

  const selectedSummary = useMemo(() => {
    if (selectedMaterialItems.length === 0) {
      return "请选择素材（最多4个）";
    }
    const names = selectedMaterialItems
      .slice(0, 2)
      .map((m) => m.scene || m.name)
      .join("、");
    if (selectedMaterialItems.length > 2) {
      return `${names} +${selectedMaterialItems.length - 2}`;
    }
    return names;
  }, [selectedMaterialItems]);

  const handleOpenMaterialPopover = useCallback(() => {
    setMaterialFilter("");

    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        const container = materialListContainerRef.current;
        if (!container) return;
        const selectedRow = container.querySelector<HTMLElement>("[data-material-selected='true']");
        selectedRow?.scrollIntoView({ block: "nearest", behavior: "auto" });
      });
    });
  }, []);

  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>
      ) : (
        <SelectPopover
          sheetTitle="选择视频素材"
          onOpen={handleOpenMaterialPopover}
          trigger={({ open, toggle }) => (
            <button
              type="button"
              onClick={toggle}
              className="w-full rounded-xl border border-white/10 bg-black/25 px-3 py-2.5 text-left transition-colors hover:border-white/30"
            >
              <span className="flex items-center justify-between gap-3">
                <span className="min-w-0">
                  <span className="block text-xs text-gray-400">已选 {selectedMaterials.length}/4 个素材</span>
                  <span className="mt-0.5 block truncate text-sm text-white">{selectedSummary}</span>
                </span>
                <ChevronDown className={`h-4 w-4 text-gray-300 transition-transform ${open ? "rotate-180" : ""}`} />
              </span>
            </button>
          )}
        >
          {() => (
            <div className="space-y-2">
              <div className="rounded-lg border border-white/10 bg-black/30 px-3 py-2">
                <div className="flex items-center gap-2">
                  <Search className="h-4 w-4 text-gray-400" />
                  <input
                    type="text"
                    value={materialFilter}
                    onChange={(e) => setMaterialFilter(e.target.value)}
                    placeholder="搜索素材名称..."
                    className="w-full bg-transparent text-sm text-white placeholder-gray-500 outline-none"
                  />
                </div>
              </div>

              {filteredMaterials.length === 0 ? (
                <div className="py-6 text-center text-sm text-gray-400">没有匹配的素材</div>
              ) : (
                <div
                  ref={materialListContainerRef}
                  className="space-y-1"
                  style={{ contentVisibility: "auto" }}
                >
                  {filteredMaterials.map((m) => {
                    const isSelected = selectedSet.has(m.id);

                    return (
                      <div
                        key={m.id}
                        ref={(el) => registerMaterialRef(m.id, el)}
                        data-popover-selected={isSelected ? "true" : undefined}
                        data-material-selected={isSelected ? "true" : "false"}
                        className={`flex items-center justify-between gap-2 rounded-lg border px-3 py-2 transition-colors ${isSelected
                          ? "border-purple-500 bg-purple-500/20"
                          : isFull
                            ? "border-white/5 bg-white/[0.02] opacity-50"
                            : "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 rounded-md border border-white/20 bg-black/40 px-2 py-1 text-xs text-white"
                              autoFocus
                            />
                            <button
                              type="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
                              type="button"
                              onClick={onCancelEditing}
                              className="p-1 text-gray-400 hover:text-white"
                              title="取消"
                            >
                              <X className="h-4 w-4" />
                            </button>
                          </div>
                        ) : (
                          <button
                            type="button"
                            onClick={() => onToggleMaterial(m.id)}
                            disabled={isFull && !isSelected}
                            className="min-w-0 flex-1 text-left"
                          >
                            <span className="block truncate text-sm text-white">{m.scene || m.name}</span>
                            <span className="mt-0.5 block text-xs text-gray-400">{m.size_mb.toFixed(1)} MB</span>
                          </button>
                        )}

                        <div className="flex items-center gap-2 pl-2">
                          <button
                            type="button"
                            onClick={(e) => {
                              e.stopPropagation();
                              if (m.path) {
                                onPreviewMaterial(m.path);
                              }
                            }}
                            className="p-1 text-gray-400 hover:text-purple-300"
                            title="预览视频"
                          >
                            <Eye className="h-4 w-4" />
                          </button>
                          {editingMaterialId !== m.id && (
                            <button
                              type="button"
                              onClick={(e) => onStartEditing(m, e)}
                              className="p-1 text-gray-400 hover:text-white"
                              title="重命名"
                            >
                              <Pencil className="h-4 w-4" />
                            </button>
                          )}
                          <button
                            type="button"
                            onClick={(e) => {
                              e.stopPropagation();
                              onDeleteMaterial(m.id);
                            }}
                            className="p-1 text-gray-400 hover:text-red-400"
                            title="删除素材"
                          >
                            <Trash2 className="h-4 w-4" />
                          </button>
                          {isSelected && <Check className="h-4 w-4 text-purple-300" />}
                        </div>
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          )}
        </SelectPopover>
      )}
    </>
  );

  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>
  );
}
