import { type RefObject, type MouseEvent, useCallback, useMemo, useState } from "react";
import { RefreshCw, Play, Pause, ChevronDown, Check, Search } from "lucide-react";
import { SelectPopover } from "@/shared/ui/SelectPopover";

interface BgmItem {
  id: string;
  name: string;
  ext?: string;
}

interface BgmPanelProps {
  bgmList: BgmItem[];
  bgmLoading: boolean;
  bgmError: string;
  enableBgm: boolean;
  onToggleEnable: (value: boolean) => void;
  onRefresh: () => void;
  selectedBgmId: string;
  onSelectBgm: (id: string) => void;
  playingBgmId: string | null;
  onTogglePreview: (bgm: BgmItem, event: MouseEvent) => void;
  bgmListContainerRef: RefObject<HTMLDivElement | null>;
  registerBgmItemRef: (id: string, element: HTMLDivElement | null) => void;
}

export function BgmPanel({
  bgmList,
  bgmLoading,
  bgmError,
  enableBgm,
  onToggleEnable,
  onRefresh,
  selectedBgmId,
  onSelectBgm,
  playingBgmId,
  onTogglePreview,
  bgmListContainerRef,
  registerBgmItemRef,
}: BgmPanelProps) {
  const [bgmFilter, setBgmFilter] = useState("");
  const selectedBgm = bgmList.find((item) => item.id === selectedBgmId) || null;
  const canSelectBgm = enableBgm && !bgmLoading && !bgmError && bgmList.length > 0;
  const filteredBgmList = useMemo(() => {
    const query = bgmFilter.trim().toLowerCase();
    if (!query) return bgmList;
    return bgmList.filter((bgm) => bgm.name.toLowerCase().includes(query));
  }, [bgmFilter, bgmList]);

  const handleOpenBgmPopover = useCallback(() => {
    setBgmFilter("");

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

  return (
    <div className="bg-white/5 rounded-2xl p-6 border border-white/10 backdrop-blur-sm">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-semibold text-white flex items-center gap-2">五、背景音乐</h2>
        <div className="flex items-center gap-2">
          <button
            onClick={onRefresh}
            className="px-2 py-1 text-xs bg-white/10 hover:bg-white/20 rounded text-gray-300 flex items-center gap-1"
          >
            <RefreshCw className="h-3.5 w-3.5" />
            刷新
          </button>
          <label className="relative inline-flex items-center cursor-pointer">
            <input
              type="checkbox"
              checked={enableBgm}
              onChange={(e) => onToggleEnable(e.target.checked)}
              className="sr-only peer"
            />
            <div className="w-11 h-6 bg-gray-600 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
          </label>
        </div>
      </div>

      {bgmLoading ? (
        <div className="text-center py-4 text-gray-400 text-sm">正在加载背景音乐...</div>
      ) : bgmError ? (
        <div className="text-center py-4 text-red-300 text-sm">
          加载失败：{bgmError}
          <button
            onClick={onRefresh}
            className="ml-2 px-2 py-1 text-xs bg-white/10 hover:bg-white/20 rounded text-gray-300"
          >
            重试
          </button>
        </div>
      ) : bgmList.length === 0 ? (
        <div className="text-center py-4 text-gray-500 text-sm">暂无背景音乐，请先导入素材</div>
      ) : (
        <div className={!enableBgm ? "opacity-70" : ""}>
          <p className="mb-2 text-xs text-gray-400">曲目选择</p>
          <SelectPopover
            sheetTitle="选择背景音乐"
            disabled={!canSelectBgm}
            onOpen={handleOpenBgmPopover}
            trigger={({ open, toggle }) => (
              <button
                type="button"
                onClick={toggle}
                disabled={!canSelectBgm}
                className={`w-full rounded-xl border px-3 py-2.5 text-left transition-colors ${canSelectBgm
                  ? "border-white/10 bg-black/25 hover:border-white/30"
                  : "border-white/10 bg-black/20 text-gray-500 cursor-not-allowed"
                  }`}
              >
                <span className="flex items-center justify-between gap-3">
                  <span className="min-w-0">
                    <span className="block truncate text-sm text-white">
                      {selectedBgm?.name || "请选择背景音乐"}
                    </span>
                    <span className="mt-0.5 block text-xs text-gray-400">
                      {selectedBgm ? `.${selectedBgm.ext || "audio"}` : "未选择"}
                    </span>
                  </span>
                  <ChevronDown className={`h-4 w-4 text-gray-300 transition-transform ${open ? "rotate-180" : ""}`} />
                </span>
              </button>
            )}
          >
            {({ close }) => (
              <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={bgmFilter}
                      onChange={(e) => setBgmFilter(e.target.value)}
                      placeholder="搜索背景音乐..."
                      className="w-full bg-transparent text-sm text-white placeholder-gray-500 outline-none"
                    />
                  </div>
                </div>

                {filteredBgmList.length === 0 ? (
                  <div className="py-6 text-center text-sm text-gray-400">没有匹配的背景音乐</div>
                ) : (
                  <div
                    ref={bgmListContainerRef}
                    className="space-y-1"
                    style={{ contentVisibility: "auto" }}
                  >
                    {filteredBgmList.map((bgm) => {
                      const isSelected = selectedBgmId === bgm.id;

                      return (
                        <div
                          key={bgm.id}
                          ref={(el) => registerBgmItemRef(bgm.id, el)}
                          data-popover-selected={isSelected ? "true" : undefined}
                          data-bgm-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"
                            : "border-white/10 bg-white/5 hover:border-white/30"
                            }`}
                        >
                          <button
                            type="button"
                            onClick={() => {
                              onSelectBgm(bgm.id);
                              close();
                            }}
                            className="min-w-0 flex-1 text-left"
                          >
                            <span className="block truncate text-sm text-white">{bgm.name}</span>
                            <span className="mt-0.5 block text-xs text-gray-400">.{bgm.ext || "audio"}</span>
                          </button>

                          <div className="flex items-center gap-2 pl-2">
                            <button
                              type="button"
                              onClick={(e) => onTogglePreview(bgm, e)}
                              className="p-1 text-gray-400 hover:text-purple-300 transition-colors"
                              title="试听"
                            >
                              {playingBgmId === bgm.id ? (
                                <Pause className="h-4 w-4" />
                              ) : (
                                <Play className="h-4 w-4" />
                              )}
                            </button>
                            {isSelected && <Check className="h-4 w-4 text-purple-300" />}
                          </div>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            )}
          </SelectPopover>
        </div>
      )}
    </div>
  );
}
