import { Button, SelectControl, FocalPointPicker, TextControl, RangeControl } from "@wordpress/components";
import { __, getLocaleData } from "@wordpress/i18n";
import { MediaUpload, MediaUploadCheck } from "@wordpress/block-editor";
import { useState } from "@wordpress/element";
import { check, image, link, search, trash } from "@wordpress/icons";
import ResponsiveControlV2 from "../../ResponsiveControlV2";
import { useResponsiveTabV2 } from "../../ResponsiveTabContextV2";
import { __experimentalUnitControl as UnitControl } from "@wordpress/components";
import PanelBodyWithSync from "../../PanelBodyWithSync";
import ProFeatureOverlay from "../../ProFeatureOverlay";
import { getEnabledBreakpoints } from "../../../../../core/breakpoints";
import ImageSelector from "../../ImageSelector";
import VideoProviderSelector from "../../VideoProviderSelector";
import { getResolvedPresetImages, presetCategories } from "../../../../../assets/images/presets/backgrounds";
import "./BackgroundImageSettingV7.scss";

const getDefaultBackgroundImage = () => ({
  pc: { url: "", position: "50% 50%", size: "cover", repeat: "no-repeat", customWidth: "100", customWidthUnit: "%", customHeight: "auto", customHeightUnit: "%", rotate: "0" },
  md: { url: "", position: "", size: "", repeat: "", customWidth: "", customWidthUnit: "", customHeight: "", customHeightUnit: "", rotate: "" },
  tb: { url: "", position: "", size: "", repeat: "", customWidth: "", customWidthUnit: "", customHeight: "", customHeightUnit: "", rotate: "" },
  sp: { url: "", position: "", size: "", repeat: "", customWidth: "", customWidthUnit: "", customHeight: "", customHeightUnit: "", rotate: "" },
});

const translateVideoDefaultStateHint = () => {
  const data = getLocaleData("zenblocks") || getLocaleData();
  const rawLocale = String((data && data[""] && data[""].lang) || "").toLowerCase().replace("-", "_");
  const locale =
    rawLocale.startsWith("ja") ? "ja" :
    rawLocale.startsWith("de") ? "de_DE" :
    rawLocale.startsWith("es") ? "es_ES" :
    rawLocale.startsWith("fr") ? "fr_FR" :
    rawLocale.startsWith("id") ? "id_ID" :
    rawLocale.startsWith("it") ? "it_IT" :
    rawLocale.startsWith("ko") ? "ko_KR" :
    rawLocale.startsWith("nl") ? "nl_NL" :
    rawLocale.startsWith("pt") ? "pt_BR" :
    rawLocale.startsWith("zh") ? "zh_TW" :
    "en";
  const messages = {
    ja: "動画背景はデフォルト状態の設定を使用します。",
    de_DE: "Der Video-Hintergrund verwendet die Einstellungen des Standardzustands.",
    es_ES: "El fondo de video usa la configuración del estado predeterminado.",
    fr_FR: "L'arrière-plan vidéo utilise les paramètres de l'état par défaut.",
    id_ID: "Latar belakang video menggunakan pengaturan status default.",
    it_IT: "Lo sfondo video utilizza le impostazioni dello stato predefinito.",
    ko_KR: "비디오 배경은 기본 상태 설정을 사용합니다.",
    nl_NL: "Video-achtergrond gebruikt de instellingen van de standaardstatus.",
    pt_BR: "O plano de fundo de vídeo usa as configurações do estado padrão.",
    zh_TW: "影片背景會使用預設狀態的設定。",
  };
  return messages[locale] || __("Video background uses the default state settings.", "zenblocks");
};

const getBackgroundVideoConfig = (url) => {
  const input = String(url || "").trim();
  if (!input) return { type: "none", embedUrl: "", fileUrl: "", videoId: "" };

  const iframeSrcMatch = input.match(/<iframe[\s\S]*?\ssrc=["']([^"']+)["']/i);
  const raw = (iframeSrcMatch ? iframeSrcMatch[1] : input).replace(/&amp;/g, "&").trim();
  if (!raw) return { type: "none", embedUrl: "", fileUrl: "", videoId: "" };

  let parsed;
  try {
    parsed = new URL(raw);
  } catch (e) {
    return { type: "file", embedUrl: "", fileUrl: raw, videoId: "" };
  }

  const host = parsed.hostname.replace(/^www\./, "");
  const path = parsed.pathname;

  if (host === "youtu.be") {
    const id = path.split("/").filter(Boolean)[0];
    if (id) {
      return {
        type: "youtube",
        embedUrl: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&mute=1&controls=0&loop=1&playlist=${id}&playsinline=1&rel=0&modestbranding=1`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  if (host === "youtube.com" || host === "youtube-nocookie.com" || host.endsWith(".youtube.com")) {
    let id = parsed.searchParams.get("v") || "";
    if (!id) {
      const parts = path.split("/").filter(Boolean);
      if (parts[0] === "embed" || parts[0] === "shorts") {
        id = parts[1] || "";
      }
    }
    if (id) {
      return {
        type: "youtube",
        embedUrl: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&mute=1&controls=0&loop=1&playlist=${id}&playsinline=1&rel=0&modestbranding=1`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  if (host === "vimeo.com" || host.endsWith(".vimeo.com")) {
    let id = "";
    const parts = path.split("/").filter(Boolean);
    if (parts[0] === "video") {
      id = parts[1] || "";
    } else {
      id = parts.find((p) => /^\d+$/.test(p)) || "";
    }
    if (id) {
      return {
        type: "vimeo",
        embedUrl: `https://player.vimeo.com/video/${id}?autoplay=1&muted=1&loop=1&background=1&title=0&byline=0&portrait=0`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  return { type: "file", embedUrl: "", fileUrl: raw, videoId: "" };
};

const getYouTubeThumbnailUrl = (videoUrl) => {
  const config = getBackgroundVideoConfig(videoUrl);
  if (config.type === "youtube" && config.videoId) {
    return `https://img.youtube.com/vi/${config.videoId}/maxresdefault.jpg`;
  }
  return "";
};

const parsePositionToPercent = (position, fallbackX = 50, fallbackY = 50) => {
  const raw = String(position || "").trim();
  if (!raw) return { x: fallbackX, y: fallbackY };
  const parts = raw.split(/\s+/);
  const xRaw = parts[0] || `${fallbackX}%`;
  const yRaw = parts[1] || `${fallbackY}%`;
  const x = parseFloat(String(xRaw).replace("%", ""));
  const y = parseFloat(String(yRaw).replace("%", ""));
  return {
    x: Number.isFinite(x) ? Math.max(0, Math.min(100, x)) : fallbackX,
    y: Number.isFinite(y) ? Math.max(0, Math.min(100, y)) : fallbackY,
  };
};

const BackgroundImageSettingV7 = ({ attributes, setAttributes, title, initialOpen = false, opened, onToggle, onSync, isHoverState = false, supportsHover = true, isPro = false, isVideoPro = false, learnMorePath = "" }) => {
  const effectiveHoverState = supportsHover ? isHoverState : false;
  const attrName = effectiveHoverState ? "backgroundImageV2Hover" : "backgroundImageV2";
  const responsiveAttrName = effectiveHoverState ? "useResponsiveBackgroundImageHover" : "useResponsiveBackgroundImage";
  const responsiveEnabled = attributes[responsiveAttrName] !== undefined ? attributes[responsiveAttrName] : false;
  const { activeTab } = useResponsiveTabV2();
  const enabledBreakpoints = getEnabledBreakpoints();
  const backgroundMediaType = attributes.backgroundMediaType || "image";
  const isVideoMode = backgroundMediaType === "video";
  const [videoUrlInputValue, setVideoUrlInputValue] = useState(attributes.backgroundVideoUrl || "");
  const [activeVideoSourceTab, setActiveVideoSourceTab] = useState("search");
  const [isPosterUrlInputOpen, setIsPosterUrlInputOpen] = useState(false);
  const [posterUrlInputValue, setPosterUrlInputValue] = useState(attributes.backgroundVideoPoster || "");
  const [backgroundImagePreviewStatus, setBackgroundImagePreviewStatus] = useState({});
  const videoConfig = getBackgroundVideoConfig(attributes.backgroundVideoUrl);
  const isEmbedVideo = videoConfig.type === "youtube" || videoConfig.type === "vimeo";
  const videoFit = attributes.backgroundVideoFit || "cover";
  const videoPosX = Number.isFinite(Number(attributes.backgroundVideoPositionX)) ? Number(attributes.backgroundVideoPositionX) : 50;
  const videoPosY = Number.isFinite(Number(attributes.backgroundVideoPositionY)) ? Number(attributes.backgroundVideoPositionY) : 50;
  const posterFit = attributes.backgroundPosterFit || "cover";
  const posterPosX = Number.isFinite(Number(attributes.backgroundPosterPositionX)) ? Number(attributes.backgroundPosterPositionX) : 50;
  const posterPosY = Number.isFinite(Number(attributes.backgroundPosterPositionY)) ? Number(attributes.backgroundPosterPositionY) : 50;
  const videoCustomWidth = attributes.backgroundVideoCustomWidth || "100";
  const videoCustomWidthUnit = attributes.backgroundVideoCustomWidthUnit || "%";
  const videoCustomHeight = attributes.backgroundVideoCustomHeight || "auto";
  const videoCustomHeightUnit = attributes.backgroundVideoCustomHeightUnit || "%";
  const posterCustomWidth = attributes.backgroundPosterCustomWidth || "100";
  const posterCustomWidthUnit = attributes.backgroundPosterCustomWidthUnit || "%";
  const posterCustomHeight = attributes.backgroundPosterCustomHeight || "auto";
  const posterCustomHeightUnit = attributes.backgroundPosterCustomHeightUnit || "%";
  const isVideoWidthAuto = videoCustomWidth === "auto";
  const isVideoHeightAuto = videoCustomHeight === "auto";
  const isPosterWidthAuto = posterCustomWidth === "auto";
  const isPosterHeightAuto = posterCustomHeight === "auto";
  const customSizeUnits = [
    { label: "px", value: "px" },
    { label: "%", value: "%" },
    { label: "vw", value: "vw" },
  ];

  const bgImageData = attributes[attrName] || getDefaultBackgroundImage();

  const handleMediaTypeChange = (value) => {
    if (value !== "video" || backgroundMediaType === "video") {
      setAttributes({ backgroundMediaType: value });
      return;
    }

    const normalImageData = attributes.backgroundImageV2 || getDefaultBackgroundImage();
    const source = normalImageData.pc || {};
    const sourceUrl = source.url || "";
    const sourceSize = source.size || "cover";
    const sourcePosition = source.position || "50% 50%";
    const sourceCustomWidth = source.customWidth || "100";
    const sourceCustomWidthUnit = source.customWidthUnit || "%";
    const sourceCustomHeight = source.customHeight || "auto";
    const sourceCustomHeightUnit = source.customHeightUnit || "%";
    const parsedPos = parsePositionToPercent(sourcePosition, 50, 50);

    const updates = {
      backgroundMediaType: "video",
      backgroundPosterFit: sourceSize,
      backgroundPosterPositionX: parsedPos.x,
      backgroundPosterPositionY: parsedPos.y,
      backgroundPosterCustomWidth: sourceCustomWidth,
      backgroundPosterCustomWidthUnit: sourceCustomWidthUnit,
      backgroundPosterCustomHeight: sourceCustomHeight,
      backgroundPosterCustomHeightUnit: sourceCustomHeightUnit,
    };

    if (sourceUrl && !attributes.backgroundVideoPoster) {
      updates.backgroundVideoPoster = sourceUrl;
      setPosterUrlInputValue(sourceUrl);
    }

    setAttributes(updates);
  };

  const handleChange = (key, value) => {
    const newData = JSON.parse(JSON.stringify(bgImageData));
    if (responsiveEnabled) {
      newData[activeTab][key] = value;
    } else {
      enabledBreakpoints.forEach((bp) => {
        newData[bp][key] = value;
      });
    }
    setAttributes({ [attrName]: newData });
  };

  const handleMultipleChanges = (changes) => {
    const newData = JSON.parse(JSON.stringify(bgImageData));
    if (responsiveEnabled) {
      Object.keys(changes).forEach((key) => {
        newData[activeTab][key] = changes[key];
      });
    } else {
      enabledBreakpoints.forEach((bp) => {
        Object.keys(changes).forEach((key) => {
          newData[bp][key] = changes[key];
        });
      });
    }
    setAttributes({ [attrName]: newData });
  };

  const handleResponsiveToggle = (value) => {
    const updates = {};
    if (!value) {
      const newData = JSON.parse(JSON.stringify(bgImageData));
      const pcData = newData.pc;
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          newData[bp] = { ...pcData };
        }
      });
      updates[responsiveAttrName] = value;
      updates[attrName] = newData;
    } else {
      updates[responsiveAttrName] = value;
    }
    // デフォルト状態でレスポンシブ切替時、ホバー側のURLとレスポンシブ設定も同期
    if (!effectiveHoverState) {
      updates.useResponsiveBackgroundImageHover = value;
      const hoverData = JSON.parse(JSON.stringify(attributes.backgroundImageV2Hover || getDefaultBackgroundImage()));
      if (!value) {
        const pcUrl = hoverData.pc.url;
        enabledBreakpoints.forEach((bp) => {
          if (bp !== "pc") {
            hoverData[bp].url = pcUrl;
          }
        });
      }
      updates.backgroundImageV2Hover = hoverData;
    }
    setAttributes(updates);
  };

  // 内部Sync機能: 通常状態の設定をホバー状態にコピー
  const handleSyncImage = () => {
    if (effectiveHoverState) {
      const normalData = attributes.backgroundImageV2 || getDefaultBackgroundImage();
      const normalResponsive = attributes.useResponsiveBackgroundImage || false;
      setAttributes({
        backgroundImageV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBackgroundImageHover: normalResponsive,
      });
    } else if (onSync) {
      onSync();
    }
  };

  const renderImageControls = (tabName) => {
    const defaultTab = getDefaultBackgroundImage().pc;
    const tabData = bgImageData[tabName] || defaultTab;
    const imageUrl = tabData.url || "";
    const imagePosition = tabData.position || defaultTab.position;
    const imageSize = tabData.size || defaultTab.size;
    const imageRepeat = tabData.repeat || defaultTab.repeat;
    const customWidth = tabData.customWidth || defaultTab.customWidth;
    const customWidthUnit = tabData.customWidthUnit || defaultTab.customWidthUnit;
    const customHeight = tabData.customHeight || defaultTab.customHeight;
    const customHeightUnit = tabData.customHeightUnit || defaultTab.customHeightUnit;
    const imageRotate = tabData.rotate !== undefined && tabData.rotate !== null && tabData.rotate !== "" ? String(tabData.rotate) : defaultTab.rotate;
    const isWidthAuto = customWidth === "auto";
    const isHeightAuto = customHeight === "auto";

    // ホバー時は常に通常状態の画像URLを表示（ホバーでは独自画像アップロードしないため）
    const normalImageData = attributes.backgroundImageV2 || getDefaultBackgroundImage();
    const displayImageUrl = effectiveHoverState
      ? (normalImageData[tabName]?.url || normalImageData.pc?.url || "")
      : imageUrl;
    const previewStatusKey = `${effectiveHoverState ? "hover" : "normal"}-${tabName}`;
    const previewStatus = backgroundImagePreviewStatus[previewStatusKey] || {};
    const isImagePreviewBroken = Boolean(displayImageUrl && previewStatus.url === displayImageUrl && previewStatus.broken);

    // ホバー時のトランジション警告判定
    const normalSize = normalImageData[tabName]?.size || normalImageData.pc?.size || "cover";
    const isNormalKeyword = normalSize === "cover" || normalSize === "contain";
    const isHoverNumeric = imageSize === "fill" || imageSize === "none";
    const showTransitionWarning = effectiveHoverState && isNormalKeyword && isHoverNumeric;

    const positionParts = imagePosition.split(" ");
    const x = parseFloat(positionParts[0]) / 100 || 0.5;
    const y = parseFloat(positionParts[1]) / 100 || 0.5;

    const units = [
      { label: "px", value: "px" },
      { label: "%", value: "%" },
      { label: "vw", value: "vw" },
    ];

    // 画像選択時の処理
    const handleImageSelect = (url) => {
      const defaultTab = getDefaultBackgroundImage().pc;
      const newData = JSON.parse(JSON.stringify(bgImageData));
      if (responsiveEnabled) {
        const currentTabData = newData[activeTab];
        newData[activeTab] = {
          ...currentTabData,
          url: url,
          position: currentTabData.position || defaultTab.position,
          size: currentTabData.size || defaultTab.size,
          repeat: currentTabData.repeat || defaultTab.repeat,
          customWidth: currentTabData.customWidth || defaultTab.customWidth,
          customWidthUnit: currentTabData.customWidthUnit || defaultTab.customWidthUnit,
          customHeight: currentTabData.customHeight || defaultTab.customHeight,
          customHeightUnit: currentTabData.customHeightUnit || defaultTab.customHeightUnit,
          rotate: currentTabData.rotate !== undefined && currentTabData.rotate !== null && currentTabData.rotate !== "" ? currentTabData.rotate : defaultTab.rotate,
        };
      } else {
        enabledBreakpoints.forEach((bp) => {
          const bpData = newData[bp];
          newData[bp] = {
            ...bpData,
            url: url,
            position: bpData.position || defaultTab.position,
            size: bpData.size || defaultTab.size,
            repeat: bpData.repeat || defaultTab.repeat,
            customWidth: bpData.customWidth || defaultTab.customWidth,
            customWidthUnit: bpData.customWidthUnit || defaultTab.customWidthUnit,
            customHeight: bpData.customHeight || defaultTab.customHeight,
            customHeightUnit: bpData.customHeightUnit || defaultTab.customHeightUnit,
            rotate: bpData.rotate !== undefined && bpData.rotate !== null && bpData.rotate !== "" ? bpData.rotate : defaultTab.rotate,
          };
        });
      }
      // デフォルト状態で画像変更時、ホバー側のURLも同期
      if (!effectiveHoverState) {
        const hoverData = JSON.parse(JSON.stringify(attributes.backgroundImageV2Hover || getDefaultBackgroundImage()));
        if (responsiveEnabled) {
          hoverData[activeTab].url = url;
        } else {
          enabledBreakpoints.forEach((bp) => {
            hoverData[bp].url = url;
          });
        }
        setAttributes({ [attrName]: newData, backgroundImageV2Hover: hoverData });
      } else {
        setAttributes({ [attrName]: newData });
      }
    };

    return (
      <>
        {/* 画像セレクター（プリセット・メディア・URL）- ホバー時は非表示 */}
        {!effectiveHoverState && (
          <ImageSelector
            value={imageUrl}
            onChange={handleImageSelect}
            presetImages={getResolvedPresetImages()}
            presetCategories={presetCategories}
            enablePreset={true}
            enableOpenverse={true}
            enableMedia={true}
            enableUrl={true}
            presetLabel={__("Preset", "zenblocks")}
            presetColumns={4}
          />
        )}

        {/* ホバー時は通常設定の画像を使用する旨を表示 */}
        {effectiveHoverState && (
          <p style={{ fontSize: "12px", color: "#757575", marginBottom: "12px", padding: "8px", backgroundColor: "#f0f0f0", borderRadius: "4px" }}>
            {displayImageUrl
              ? __("Uses the default settings image. You can change position, size, and repeat settings.", "zenblocks")
              : __("Set an image in the default settings.", "zenblocks")}
          </p>
        )}

        {displayImageUrl && (
          <img
            src={displayImageUrl}
            alt=""
            style={{ position: "absolute", width: 0, height: 0, opacity: 0, pointerEvents: "none" }}
            onLoad={() => {
              setBackgroundImagePreviewStatus((prev) => ({
                ...prev,
                [previewStatusKey]: { url: displayImageUrl, broken: false },
              }));
            }}
            onError={() => {
              setBackgroundImagePreviewStatus((prev) => ({
                ...prev,
                [previewStatusKey]: { url: displayImageUrl, broken: true },
              }));
            }}
          />
        )}

        {displayImageUrl && !isImagePreviewBroken && (
          <div className="zenblocks-inspector-background-image__settings">
            <FocalPointPicker
              key={displayImageUrl}
              url={displayImageUrl}
              value={{ x, y }}
              onChange={(focalPoint) => {
                const position = `${focalPoint.x * 100}% ${focalPoint.y * 100}%`;
                handleChange("position", position);
              }}
            />

            <SelectControl
              label={__("Repeat", "zenblocks")}
              value={imageRepeat}
              options={[
                { label: __("None", "zenblocks"), value: "no-repeat" },
                { label: __("Repeat", "zenblocks"), value: "repeat" },
                { label: __("Horizontal Only", "zenblocks"), value: "repeat-x" },
                { label: __("Vertical Only", "zenblocks"), value: "repeat-y" },
                { label: __("Space", "zenblocks"), value: "space" },
                { label: __("Round", "zenblocks"), value: "round" },
              ]}
              onChange={(value) => handleChange("repeat", value)}
              className="zenblocks-inspector-background-image__repeat-select"
            />

            <SelectControl
              label={__("Fit Method", "zenblocks")}
              value={imageSize}
              options={[
                { label: __("Cover", "zenblocks"), value: "cover" },
                { label: __("Contain", "zenblocks"), value: "contain" },
                { label: __("Fill", "zenblocks"), value: "fill" },
                { label: __("None", "zenblocks"), value: "none" },
              ]}
              onChange={(value) => handleChange("size", value)}
              className="zenblocks-inspector-background-image__size-select"
            />

            {showTransitionWarning && (
              <p style={{ fontSize: "11px", color: "#757575", marginTop: "8px", marginBottom: "12px", padding: "8px", backgroundColor: "#f0f0f0", borderRadius: "4px" }}>
                {__("* Size transitions do not work when default is set to Cover/Contain.", "zenblocks")}
              </p>
            )}

            {(imageSize === "fill" || imageSize === "none") && (
              <div className="zenblocks-inspector-background-image__custom-size" style={{ marginTop: "10px" }}>
                <div className="zenblocks-inspector-background-image__width-controls" style={{ marginBottom: "12px" }}>
                  <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                    {__("Width", "zenblocks")}
                  </label>
                  <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                    <div style={{ flex: 1, opacity: isWidthAuto ? 0.5 : 1, pointerEvents: isWidthAuto ? "none" : "auto" }}>
                      <UnitControl
                        value={isWidthAuto ? "" : `${customWidth}${customWidthUnit}`}
                        onChange={(value) => {
                          const numValue = parseFloat(value);
                          const unit = value.replace(/[\d.-]/g, "") || customWidthUnit;
                          const changes = {};
                          if (!isNaN(numValue)) changes.customWidth = String(numValue);
                          if (unit) changes.customWidthUnit = unit;
                          if (Object.keys(changes).length > 0) handleMultipleChanges(changes);
                        }}
                        units={units}
                        placeholder={isWidthAuto ? "auto" : ""}
                      />
                    </div>
                    <Button
                      isSmall
                      variant={isWidthAuto ? "primary" : "secondary"}
                      onClick={() => {
                        if (isWidthAuto) {
                          handleMultipleChanges({ customWidth: "100", customWidthUnit: "%" });
                        } else {
                          handleChange("customWidth", "auto");
                        }
                      }}
                      style={{ flexShrink: 0 }}
                    >
                      AUTO
                    </Button>
                  </div>
                </div>
                <div className="zenblocks-inspector-background-image__height-controls">
                  <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                    {__("Height", "zenblocks")}
                  </label>
                  <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                    <div style={{ flex: 1, opacity: isHeightAuto ? 0.5 : 1, pointerEvents: isHeightAuto ? "none" : "auto" }}>
                      <UnitControl
                        value={isHeightAuto ? "" : `${customHeight}${customHeightUnit}`}
                        onChange={(value) => {
                          const numValue = parseFloat(value);
                          const unit = value.replace(/[\d.-]/g, "") || customHeightUnit;
                          const changes = {};
                          if (!isNaN(numValue)) changes.customHeight = String(numValue);
                          if (unit) changes.customHeightUnit = unit;
                          if (Object.keys(changes).length > 0) handleMultipleChanges(changes);
                        }}
                        units={units}
                        placeholder={isHeightAuto ? "auto" : ""}
                      />
                    </div>
                    <Button
                      isSmall
                      variant={isHeightAuto ? "primary" : "secondary"}
                      onClick={() => {
                        if (isHeightAuto) {
                          handleMultipleChanges({ customHeight: "100", customHeightUnit: "%" });
                        } else {
                          handleChange("customHeight", "auto");
                        }
                      }}
                      style={{ flexShrink: 0 }}
                    >
                      AUTO
                    </Button>
                  </div>
                </div>
              </div>
            )}

            <RangeControl
              label={__("Rotation (deg)", "zenblocks")}
              value={Number.parseFloat(imageRotate) || 0}
              onChange={(value) => handleChange("rotate", String(value ?? 0))}
              min={-180}
              max={180}
              step={1}
            />
          </div>
        )}

        {displayImageUrl && isImagePreviewBroken && (
          <div style={{ marginBottom: "12px", padding: "10px", background: "#f6f7f7", borderRadius: "4px" }}>
            <p style={{ margin: 0, fontSize: "12px", color: "#646970", lineHeight: 1.5 }}>
              {__("Cannot load image. The URL may be invalid or the resource has been deleted. Please select a new image.", "zenblocks")}
            </p>
          </div>
        )}
      </>
    );
  };

  const renderVideoSourceTabs = () => (
    <>
      <div className="zenblocks-media-type-tabs zenblocks-image-selector__tabs" role="tablist" aria-label={__("Video source", "zenblocks")}>
        {[
          { id: "search", label: __("Search", "zenblocks"), icon: search },
          { id: "media", label: __("Media", "zenblocks"), icon: image },
          { id: "url", label: __("URL", "zenblocks"), icon: link },
        ].map((item) => (
          <Button
            key={item.id}
            role="tab"
            aria-selected={activeVideoSourceTab === item.id}
            className={`zenblocks-media-type-tabs__button zenblocks-image-selector__tab-button ${activeVideoSourceTab === item.id ? "is-active" : ""}`}
            onClick={() => setActiveVideoSourceTab(item.id)}
            title={item.label}
            aria-label={item.label}
          >
            <span className="zenblocks-image-selector__tab-button-icon">{item.icon}</span>
          </Button>
        ))}
      </div>

      {activeVideoSourceTab === "url" && (
        <p className="zenblocks-image-selector__tab-description">
          {__("Enter a video URL and click the check button to apply.", "zenblocks")}
        </p>
      )}

      <div className="zenblocks-image-selector__panel">
        {activeVideoSourceTab === "search" && (
          <VideoProviderSelector
            showToggle={false}
            initialOpen={true}
            onSelect={(videoUrl, posterUrl) => {
              const effectivePoster = posterUrl || getYouTubeThumbnailUrl(videoUrl) || "";
              setAttributes({
                backgroundVideoUrl: videoUrl || "",
                backgroundVideoPoster: effectivePoster,
              });
              setVideoUrlInputValue(videoUrl || "");
              setPosterUrlInputValue(effectivePoster);
            }}
          />
        )}

        {activeVideoSourceTab === "media" && (
          <div className="zenblocks-image-selector__panel-inner">
            <MediaUploadCheck>
              <MediaUpload
                onSelect={(media) => {
                  setAttributes({ backgroundVideoUrl: media?.url || "", backgroundVideoPoster: "" });
                  setVideoUrlInputValue(media?.url || "");
                  setPosterUrlInputValue("");
                }}
                allowedTypes={["video"]}
                value={attributes.backgroundVideoUrl}
                render={({ open }) => (
                  <Button
                    onClick={open}
                    variant="primary"
                    icon="video-alt3"
                    label={attributes.backgroundVideoUrl ? __("Change Video", "zenblocks") : __("Select Video", "zenblocks")}
                    showTooltip
                    className="zenblocks-image-selector__media-picker-button"
                  />
                )}
              />
            </MediaUploadCheck>
          </div>
        )}

        {activeVideoSourceTab === "url" && (
          <div className="zenblocks-image-selector__panel-inner zenblocks-image-selector__url-input">
            <div className="zenblocks-image-selector__url-row">
              <TextControl
                label={__("Video URL (MP4 / YouTube / Vimeo)", "zenblocks")}
                hideLabelFromVision={true}
                value={videoUrlInputValue}
                onChange={setVideoUrlInputValue}
                placeholder="https://example.com/video.mp4 or https://youtu.be/..."
              />
              <div className="zenblocks-image-selector__url-actions">
                <Button
                  onClick={() => {
                    const autoPoster = getYouTubeThumbnailUrl(videoUrlInputValue) || "";
                    setAttributes({
                      backgroundVideoUrl: videoUrlInputValue,
                      backgroundVideoPoster: autoPoster,
                    });
                    setPosterUrlInputValue(autoPoster);
                  }}
                  variant="primary"
                  disabled={!videoUrlInputValue.trim()}
                  icon={check}
                  label={__("Apply", "zenblocks")}
                  showTooltip
                  className="zenblocks-image-selector__url-apply-button"
                >
                </Button>
              </div>
            </div>
          </div>
        )}
      </div>
    </>
  );

  const content = (
    <div className="zenblocks-inspector-background-image">
      {!effectiveHoverState && (
        <div style={{ marginBottom: "10px" }}>
          <p style={{ margin: "0 0 6px", fontSize: "11px", fontWeight: 600, textTransform: "uppercase", color: "#1e1e1e" }}>
            {__("Media Type", "zenblocks")}
          </p>
          <div className="zenblocks-media-type-tabs" role="tablist" aria-label={__("Media Type", "zenblocks")}>
            <Button
              variant="secondary"
              onClick={() => handleMediaTypeChange("image")}
              className={`zenblocks-media-type-tabs__button${backgroundMediaType === "image" ? " is-active" : ""}`}
              aria-pressed={backgroundMediaType === "image"}
            >
              {__("Image", "zenblocks")}
            </Button>
            <Button
              variant="secondary"
              onClick={() => handleMediaTypeChange("video")}
              className={`zenblocks-media-type-tabs__button${backgroundMediaType === "video" ? " is-active" : ""}`}
              aria-pressed={backgroundMediaType === "video"}
            >
              {__("Video", "zenblocks")}
            </Button>
          </div>
        </div>
      )}

      {isVideoMode ? (
        <div style={{ marginTop: "10px" }}>
          {isVideoPro ? (
            <ProFeatureOverlay featureName="動画背景" learnMorePath={learnMorePath}>
              {effectiveHoverState ? (
                <p style={{ fontSize: "12px", color: "#757575", marginBottom: "12px", padding: "8px", backgroundColor: "#f0f0f0", borderRadius: "4px" }}>
                  {translateVideoDefaultStateHint()}
                </p>
              ) : (
                <>
                  {renderVideoSourceTabs()}

                  <div style={{ marginBottom: "12px", padding: "10px", background: "#f6f7f7", borderRadius: "4px" }}>
                    <div style={{ fontSize: "11px", fontWeight: 600, marginBottom: "6px" }}>{__("Video", "zenblocks")}</div>
                    {attributes.backgroundVideoUrl ? (
                      <div style={{ marginBottom: "8px" }}>
                        {videoConfig.type === "file" ? (
                          <video
                            src={attributes.backgroundVideoUrl}
                            muted
                            playsInline
                            controls
                            style={{ width: "100%", height: "auto", borderRadius: "3px", display: "block", background: "#111" }}
                          />
                        ) : isEmbedVideo ? (
                          <iframe
                            src={videoConfig.embedUrl}
                            title={__("Current background video", "zenblocks")}
                            style={{ width: "100%", aspectRatio: "16 / 9", border: 0, borderRadius: "3px", display: "block", background: "#111" }}
                            allow="autoplay; encrypted-media; fullscreen; picture-in-picture"
                            allowFullScreen
                          />
                        ) : (
                          <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("Unsupported video URL.", "zenblocks")}</p>
                        )}
                      </div>
                    ) : (
                      <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("No video selected.", "zenblocks")}</p>
                    )}

                    {attributes.backgroundVideoUrl && (
                      <div className="zenblocks-image-selector__remove-link-wrap">
                        <button
                          type="button"
                          className="zenblocks-image-selector__remove-link"
                          onClick={() => {
                            setAttributes({ backgroundVideoUrl: "" });
                            setVideoUrlInputValue("");
                          }}
                        >
                          {__("Remove Video", "zenblocks")}
                        </button>
                      </div>
                    )}

                    <div className="zenblocks-bg-video-setting__fit">
                      <SelectControl
                        label={__("Video Fit", "zenblocks")}
                        value={videoFit}
                        options={[
                          { label: __("Cover", "zenblocks"), value: "cover" },
                          { label: __("Contain", "zenblocks"), value: "contain" },
                          { label: __("Fill", "zenblocks"), value: "fill" },
                          { label: __("None", "zenblocks"), value: "none" },
                        ]}
                        onChange={(value) => setAttributes({ backgroundVideoFit: value })}
                      />
                    </div>
                    <div className="zenblocks-bg-video-setting__position-x">
                      <RangeControl
                        label={__("Video Position X", "zenblocks")}
                        value={videoPosX}
                        min={0}
                        max={100}
                        onChange={(value) => setAttributes({ backgroundVideoPositionX: value })}
                      />
                    </div>
                    <div className="zenblocks-bg-video-setting__position-y">
                      <RangeControl
                        label={__("Video Position Y", "zenblocks")}
                        value={videoPosY}
                        min={0}
                        max={100}
                        onChange={(value) => setAttributes({ backgroundVideoPositionY: value })}
                      />
                    </div>
                    {(videoFit === "fill" || videoFit === "none") && (
                      <>
                        <div className="zenblocks-inspector-background-image__width-controls" style={{ marginBottom: "12px" }}>
                          <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                            {__("Width", "zenblocks")}
                          </label>
                          <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                            <div style={{ flex: 1, opacity: isVideoWidthAuto ? 0.5 : 1, pointerEvents: isVideoWidthAuto ? "none" : "auto" }}>
                              <UnitControl
                                value={isVideoWidthAuto ? "" : `${videoCustomWidth}${videoCustomWidthUnit}`}
                                onChange={(value) => {
                                  const numValue = parseFloat(value);
                                  const unit = value.replace(/[\d.-]/g, "") || videoCustomWidthUnit;
                                  const updates = {};
                                  if (!isNaN(numValue)) updates.backgroundVideoCustomWidth = String(numValue);
                                  if (unit) updates.backgroundVideoCustomWidthUnit = unit;
                                  if (Object.keys(updates).length > 0) setAttributes(updates);
                                }}
                                units={customSizeUnits}
                                placeholder={isVideoWidthAuto ? "auto" : ""}
                              />
                            </div>
                            <Button
                              isSmall
                              variant={isVideoWidthAuto ? "primary" : "secondary"}
                              onClick={() => {
                                if (isVideoWidthAuto) {
                                  setAttributes({ backgroundVideoCustomWidth: "100", backgroundVideoCustomWidthUnit: "%" });
                                } else {
                                  setAttributes({ backgroundVideoCustomWidth: "auto" });
                                }
                              }}
                            >
                              AUTO
                            </Button>
                          </div>
                        </div>

                        <div className="zenblocks-inspector-background-image__height-controls" style={{ marginBottom: "12px" }}>
                          <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                            {__("Height", "zenblocks")}
                          </label>
                          <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                            <div style={{ flex: 1, opacity: isVideoHeightAuto ? 0.5 : 1, pointerEvents: isVideoHeightAuto ? "none" : "auto" }}>
                              <UnitControl
                                value={isVideoHeightAuto ? "" : `${videoCustomHeight}${videoCustomHeightUnit}`}
                                onChange={(value) => {
                                  const numValue = parseFloat(value);
                                  const unit = value.replace(/[\d.-]/g, "") || videoCustomHeightUnit;
                                  const updates = {};
                                  if (!isNaN(numValue)) updates.backgroundVideoCustomHeight = String(numValue);
                                  if (unit) updates.backgroundVideoCustomHeightUnit = unit;
                                  if (Object.keys(updates).length > 0) setAttributes(updates);
                                }}
                                units={customSizeUnits}
                                placeholder={isVideoHeightAuto ? "auto" : ""}
                              />
                            </div>
                            <Button
                              isSmall
                              variant={isVideoHeightAuto ? "primary" : "secondary"}
                              onClick={() => {
                                if (isVideoHeightAuto) {
                                  setAttributes({ backgroundVideoCustomHeight: "100", backgroundVideoCustomHeightUnit: "%" });
                                } else {
                                  setAttributes({ backgroundVideoCustomHeight: "auto" });
                                }
                              }}
                            >
                              AUTO
                            </Button>
                          </div>
                        </div>
                      </>
                    )}
                  </div>

                  <div style={{ marginBottom: "12px", padding: "10px", background: "#f6f7f7", borderRadius: "4px" }}>
                    <div style={{ fontSize: "11px", fontWeight: 600, marginBottom: "6px" }}>{__("Current Poster", "zenblocks")}</div>
                    {attributes.backgroundVideoPoster ? (
                      <img
                        src={attributes.backgroundVideoPoster}
                        alt=""
                        style={{ width: "100%", height: "auto", borderRadius: "3px", display: "block", background: "#111", marginBottom: "8px" }}
                      />
                    ) : (
                      <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("No poster selected.", "zenblocks")}</p>
                    )}

                    <div className="zenblocks-image-selector__buttons zenblocks-bg-poster-setting__action-buttons">
                      <MediaUploadCheck>
                        <MediaUpload
                          onSelect={(media) => {
                            setAttributes({ backgroundVideoPoster: media?.url || "" });
                            setPosterUrlInputValue(media?.url || "");
                          }}
                          allowedTypes={["image"]}
                          value={attributes.backgroundVideoPoster}
                          render={({ open }) => (
                            <Button
                              onClick={open}
                              variant="primary"
                              icon={image}
                              className="zenblocks-image-selector__media-button"
                              label={attributes.backgroundVideoPoster ? __("Change Poster", "zenblocks") : __("Select Poster", "zenblocks")}
                              showTooltip
                            />
                          )}
                        />
                      </MediaUploadCheck>
                      <Button
                        onClick={() => setIsPosterUrlInputOpen(!isPosterUrlInputOpen)}
                        variant={isPosterUrlInputOpen ? "primary" : "secondary"}
                        icon={link}
                        className="zenblocks-image-selector__url-button"
                        label={__("Poster URL", "zenblocks")}
                        showTooltip
                      />
                      {attributes.backgroundVideoPoster && (
                        <Button
                          variant="secondary"
                          isDestructive
                          onClick={() => {
                            setAttributes({ backgroundVideoPoster: "" });
                            setPosterUrlInputValue("");
                          }}
                          icon={trash}
                          className="zenblocks-image-selector__remove-button"
                          label={__("Remove Poster", "zenblocks")}
                        />
                      )}
                    </div>

                    {isPosterUrlInputOpen && (
                      <div className="zenblocks-image-selector__url-input">
                        <TextControl
                          label={__("Poster Image URL", "zenblocks")}
                          value={posterUrlInputValue}
                          onChange={setPosterUrlInputValue}
                          placeholder="https://example.com/poster.jpg"
                        />
                        <div className="zenblocks-image-selector__url-actions">
                          <Button
                            onClick={() => {
                              setAttributes({ backgroundVideoPoster: posterUrlInputValue });
                              setIsPosterUrlInputOpen(false);
                            }}
                            variant="primary"
                            disabled={!posterUrlInputValue.trim()}
                          >
                            {__("Apply", "zenblocks")}
                          </Button>
                          <Button
                            onClick={() => {
                              setIsPosterUrlInputOpen(false);
                              setPosterUrlInputValue(attributes.backgroundVideoPoster || "");
                            }}
                            variant="secondary"
                          >
                            {__("Cancel", "zenblocks")}
                          </Button>
                        </div>
                      </div>
                    )}

                    <div className="zenblocks-bg-poster-setting__fit">
                      <SelectControl
                        label={__("Poster Fit", "zenblocks")}
                        value={posterFit}
                        options={[
                          { label: __("Cover", "zenblocks"), value: "cover" },
                          { label: __("Contain", "zenblocks"), value: "contain" },
                          { label: __("Fill", "zenblocks"), value: "fill" },
                          { label: __("None", "zenblocks"), value: "none" },
                        ]}
                        onChange={(value) => setAttributes({ backgroundPosterFit: value })}
                      />
                    </div>
                    <div className="zenblocks-bg-poster-setting__position-x">
                      <RangeControl
                        label={__("Poster Position X", "zenblocks")}
                        value={posterPosX}
                        min={0}
                        max={100}
                        onChange={(value) => setAttributes({ backgroundPosterPositionX: value })}
                      />
                    </div>
                    <div className="zenblocks-bg-poster-setting__position-y">
                      <RangeControl
                        label={__("Poster Position Y", "zenblocks")}
                        value={posterPosY}
                        min={0}
                        max={100}
                        onChange={(value) => setAttributes({ backgroundPosterPositionY: value })}
                      />
                    </div>
                    {(posterFit === "fill" || posterFit === "none") && (
                      <div style={{ marginTop: "12px" }}>
                        <div className="zenblocks-inspector-background-image__width-controls" style={{ marginBottom: "12px" }}>
                          <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                            {__("Width", "zenblocks")}
                          </label>
                          <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                            <div style={{ flex: 1, opacity: isPosterWidthAuto ? 0.5 : 1, pointerEvents: isPosterWidthAuto ? "none" : "auto" }}>
                              <UnitControl
                                value={isPosterWidthAuto ? "" : `${posterCustomWidth}${posterCustomWidthUnit}`}
                                onChange={(value) => {
                                  const numValue = parseFloat(value);
                                  const unit = value.replace(/[\d.-]/g, "") || posterCustomWidthUnit;
                                  const updates = {};
                                  if (!isNaN(numValue)) updates.backgroundPosterCustomWidth = String(numValue);
                                  if (unit) updates.backgroundPosterCustomWidthUnit = unit;
                                  if (Object.keys(updates).length > 0) setAttributes(updates);
                                }}
                                units={customSizeUnits}
                                placeholder={isPosterWidthAuto ? "auto" : ""}
                              />
                            </div>
                            <Button
                              isSmall
                              variant={isPosterWidthAuto ? "primary" : "secondary"}
                              onClick={() => {
                                if (isPosterWidthAuto) {
                                  setAttributes({ backgroundPosterCustomWidth: "100", backgroundPosterCustomWidthUnit: "%" });
                                } else {
                                  setAttributes({ backgroundPosterCustomWidth: "auto" });
                                }
                              }}
                            >
                              AUTO
                            </Button>
                          </div>
                        </div>
                        <div className="zenblocks-inspector-background-image__height-controls">
                          <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                            {__("Height", "zenblocks")}
                          </label>
                          <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                            <div style={{ flex: 1, opacity: isPosterHeightAuto ? 0.5 : 1, pointerEvents: isPosterHeightAuto ? "none" : "auto" }}>
                              <UnitControl
                                value={isPosterHeightAuto ? "" : `${posterCustomHeight}${posterCustomHeightUnit}`}
                                onChange={(value) => {
                                  const numValue = parseFloat(value);
                                  const unit = value.replace(/[\d.-]/g, "") || posterCustomHeightUnit;
                                  const updates = {};
                                  if (!isNaN(numValue)) updates.backgroundPosterCustomHeight = String(numValue);
                                  if (unit) updates.backgroundPosterCustomHeightUnit = unit;
                                  if (Object.keys(updates).length > 0) setAttributes(updates);
                                }}
                                units={customSizeUnits}
                                placeholder={isPosterHeightAuto ? "auto" : ""}
                              />
                            </div>
                            <Button
                              isSmall
                              variant={isPosterHeightAuto ? "primary" : "secondary"}
                              onClick={() => {
                                if (isPosterHeightAuto) {
                                  setAttributes({ backgroundPosterCustomHeight: "100", backgroundPosterCustomHeightUnit: "%" });
                                } else {
                                  setAttributes({ backgroundPosterCustomHeight: "auto" });
                                }
                              }}
                              style={{ flexShrink: 0 }}
                            >
                              AUTO
                            </Button>
                          </div>
                        </div>
                      </div>
                    )}
                  </div>
                </>
              )}
            </ProFeatureOverlay>
          ) : effectiveHoverState ? (
            <p style={{ fontSize: "12px", color: "#757575", marginBottom: "12px", padding: "8px", backgroundColor: "#f0f0f0", borderRadius: "4px" }}>
              {translateVideoDefaultStateHint()}
            </p>
          ) : (
            <>
              {renderVideoSourceTabs()}

              <div style={{ marginBottom: "12px", padding: "10px", background: "#f6f7f7", borderRadius: "4px" }}>
                <div style={{ fontSize: "11px", fontWeight: 600, marginBottom: "6px" }}>{__("Video", "zenblocks")}</div>
                {attributes.backgroundVideoUrl ? (
                  <div style={{ marginBottom: "8px" }}>
                    {videoConfig.type === "file" ? (
                      <video
                        src={attributes.backgroundVideoUrl}
                        muted
                        playsInline
                        controls
                        style={{ width: "100%", height: "auto", borderRadius: "3px", display: "block", background: "#111" }}
                      />
                    ) : isEmbedVideo ? (
                      <iframe
                        src={videoConfig.embedUrl}
                        title={__("Current background video", "zenblocks")}
                        style={{ width: "100%", aspectRatio: "16 / 9", border: 0, borderRadius: "3px", display: "block", background: "#111" }}
                        allow="autoplay; encrypted-media; fullscreen; picture-in-picture"
                        allowFullScreen
                      />
                    ) : (
                      <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("Unsupported video URL.", "zenblocks")}</p>
                    )}
                  </div>
                ) : (
                  <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("No video selected.", "zenblocks")}</p>
                )}

                {attributes.backgroundVideoUrl && (
                  <div className="zenblocks-image-selector__remove-link-wrap">
                    <button
                      type="button"
                      className="zenblocks-image-selector__remove-link"
                      onClick={() => {
                        setAttributes({ backgroundVideoUrl: "" });
                        setVideoUrlInputValue("");
                      }}
                    >
                      {__("Remove Video", "zenblocks")}
                    </button>
                  </div>
                )}

                <div className="zenblocks-bg-video-setting__fit">
                  <SelectControl
                    label={__("Video Fit", "zenblocks")}
                    value={videoFit}
                    options={[
                      { label: __("Cover", "zenblocks"), value: "cover" },
                      { label: __("Contain", "zenblocks"), value: "contain" },
                      { label: __("Fill", "zenblocks"), value: "fill" },
                      { label: __("None", "zenblocks"), value: "none" },
                    ]}
                    onChange={(value) => setAttributes({ backgroundVideoFit: value })}
                  />
                </div>
                <div className="zenblocks-bg-video-setting__position-x">
                  <RangeControl
                    label={__("Video Position X", "zenblocks")}
                    value={videoPosX}
                    min={0}
                    max={100}
                    onChange={(value) => setAttributes({ backgroundVideoPositionX: value })}
                  />
                </div>
                <div className="zenblocks-bg-video-setting__position-y">
                  <RangeControl
                    label={__("Video Position Y", "zenblocks")}
                    value={videoPosY}
                    min={0}
                    max={100}
                    onChange={(value) => setAttributes({ backgroundVideoPositionY: value })}
                  />
                </div>
                {(videoFit === "fill" || videoFit === "none") && (
                  <>
                    <div className="zenblocks-inspector-background-image__width-controls" style={{ marginBottom: "12px" }}>
                      <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                        {__("Width", "zenblocks")}
                      </label>
                      <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                        <div style={{ flex: 1, opacity: isVideoWidthAuto ? 0.5 : 1, pointerEvents: isVideoWidthAuto ? "none" : "auto" }}>
                          <UnitControl
                            value={isVideoWidthAuto ? "" : `${videoCustomWidth}${videoCustomWidthUnit}`}
                            onChange={(value) => {
                              const numValue = parseFloat(value);
                              const unit = value.replace(/[\d.-]/g, "") || videoCustomWidthUnit;
                              const updates = {};
                              if (!isNaN(numValue)) updates.backgroundVideoCustomWidth = String(numValue);
                              if (unit) updates.backgroundVideoCustomWidthUnit = unit;
                              if (Object.keys(updates).length > 0) setAttributes(updates);
                            }}
                            units={customSizeUnits}
                            placeholder={isVideoWidthAuto ? "auto" : ""}
                          />
                        </div>
                        <Button
                          isSmall
                          variant={isVideoWidthAuto ? "primary" : "secondary"}
                          onClick={() => {
                            if (isVideoWidthAuto) {
                              setAttributes({ backgroundVideoCustomWidth: "100", backgroundVideoCustomWidthUnit: "%" });
                            } else {
                              setAttributes({ backgroundVideoCustomWidth: "auto" });
                            }
                          }}
                        >
                          AUTO
                        </Button>
                      </div>
                    </div>

                    <div className="zenblocks-inspector-background-image__height-controls" style={{ marginBottom: "12px" }}>
                      <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                        {__("Height", "zenblocks")}
                      </label>
                      <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                        <div style={{ flex: 1, opacity: isVideoHeightAuto ? 0.5 : 1, pointerEvents: isVideoHeightAuto ? "none" : "auto" }}>
                          <UnitControl
                            value={isVideoHeightAuto ? "" : `${videoCustomHeight}${videoCustomHeightUnit}`}
                            onChange={(value) => {
                              const numValue = parseFloat(value);
                              const unit = value.replace(/[\d.-]/g, "") || videoCustomHeightUnit;
                              const updates = {};
                              if (!isNaN(numValue)) updates.backgroundVideoCustomHeight = String(numValue);
                              if (unit) updates.backgroundVideoCustomHeightUnit = unit;
                              if (Object.keys(updates).length > 0) setAttributes(updates);
                            }}
                            units={customSizeUnits}
                            placeholder={isVideoHeightAuto ? "auto" : ""}
                          />
                        </div>
                        <Button
                          isSmall
                          variant={isVideoHeightAuto ? "primary" : "secondary"}
                          onClick={() => {
                            if (isVideoHeightAuto) {
                              setAttributes({ backgroundVideoCustomHeight: "100", backgroundVideoCustomHeightUnit: "%" });
                            } else {
                              setAttributes({ backgroundVideoCustomHeight: "auto" });
                            }
                          }}
                        >
                          AUTO
                        </Button>
                      </div>
                    </div>
                  </>
                )}
                {(videoConfig.type === "youtube" || videoConfig.type === "vimeo") && (
                  <p style={{ margin: "6px 0 0", fontSize: "11px", color: "#646970" }}>
                    {__("YouTube/Vimeo are displayed as embeds, so position control is approximate.", "zenblocks")}
                  </p>
                )}
              </div>

              <div style={{ marginBottom: "8px", padding: "10px", background: "#f6f7f7", borderRadius: "4px" }}>
                <div style={{ fontSize: "11px", fontWeight: 600, marginBottom: "6px" }}>{__("Poster", "zenblocks")}</div>
                {attributes.backgroundVideoPoster ? (
                  <img
                    src={attributes.backgroundVideoPoster}
                    alt={__("Current Poster", "zenblocks")}
                    style={{ width: "100%", height: "120px", objectFit: "cover", borderRadius: "3px", display: "block", marginBottom: "8px" }}
                  />
                ) : (
                  <p style={{ margin: "0 0 8px", fontSize: "11px", color: "#646970" }}>{__("No poster selected.", "zenblocks")}</p>
                )}

                <div className="zenblocks-image-selector__buttons zenblocks-bg-poster-setting__action-buttons">
                  <MediaUploadCheck>
                    <MediaUpload
                      onSelect={(media) => {
                        setAttributes({ backgroundVideoPoster: media?.url || "" });
                        setPosterUrlInputValue(media?.url || "");
                      }}
                      allowedTypes={["image"]}
                      value={attributes.backgroundVideoPoster}
                      render={({ open }) => (
                        <Button
                          onClick={open}
                          variant="secondary"
                          icon={image}
                          className="zenblocks-image-selector__media-button"
                          label={attributes.backgroundVideoPoster ? __("Change Poster", "zenblocks") : __("Select Poster", "zenblocks")}
                          showTooltip
                        />
                      )}
                    />
                  </MediaUploadCheck>
                  <Button
                    onClick={() => setIsPosterUrlInputOpen(!isPosterUrlInputOpen)}
                    variant={isPosterUrlInputOpen ? "primary" : "secondary"}
                    icon={link}
                    className="zenblocks-image-selector__url-button"
                    label={__("Poster URL", "zenblocks")}
                    showTooltip
                  />
                  {attributes.backgroundVideoPoster && (
                    <Button
                      variant="secondary"
                      isDestructive
                      onClick={() => {
                        setAttributes({ backgroundVideoPoster: "" });
                        setPosterUrlInputValue("");
                      }}
                      icon={trash}
                      className="zenblocks-image-selector__remove-button"
                      label={__("Remove Poster", "zenblocks")}
                    />
                  )}
                </div>

                {isPosterUrlInputOpen && (
                  <div className="zenblocks-image-selector__url-input">
                    <TextControl
                      label={__("Poster URL (optional)", "zenblocks")}
                      value={posterUrlInputValue}
                      onChange={setPosterUrlInputValue}
                      placeholder="https://example.com/poster.jpg"
                    />
                    <div className="zenblocks-image-selector__url-actions">
                      <Button
                        onClick={() => {
                          setAttributes({ backgroundVideoPoster: posterUrlInputValue });
                          setIsPosterUrlInputOpen(false);
                        }}
                        variant="primary"
                      >
                        {__("Apply", "zenblocks")}
                      </Button>
                      <Button
                        onClick={() => {
                          setIsPosterUrlInputOpen(false);
                          setPosterUrlInputValue(attributes.backgroundVideoPoster || "");
                        }}
                        variant="secondary"
                      >
                        {__("Cancel", "zenblocks")}
                      </Button>
                    </div>
                  </div>
                )}

                <div className="zenblocks-bg-poster-setting__fit">
                  <SelectControl
                    label={__("Poster Fit", "zenblocks")}
                    value={posterFit}
                    options={[
                      { label: __("Cover", "zenblocks"), value: "cover" },
                      { label: __("Contain", "zenblocks"), value: "contain" },
                      { label: __("Fill", "zenblocks"), value: "fill" },
                      { label: __("None", "zenblocks"), value: "none" },
                    ]}
                    onChange={(value) => setAttributes({ backgroundPosterFit: value })}
                  />
                </div>
                <div className="zenblocks-bg-poster-setting__position-x">
                  <RangeControl
                    label={__("Poster Position X", "zenblocks")}
                    value={posterPosX}
                    min={0}
                    max={100}
                    onChange={(value) => setAttributes({ backgroundPosterPositionX: value })}
                  />
                </div>
                <div className="zenblocks-bg-poster-setting__position-y">
                  <RangeControl
                    label={__("Poster Position Y", "zenblocks")}
                    value={posterPosY}
                    min={0}
                    max={100}
                    onChange={(value) => setAttributes({ backgroundPosterPositionY: value })}
                  />
                </div>
                {(posterFit === "fill" || posterFit === "none") && (
                  <>
                    <div className="zenblocks-inspector-background-image__width-controls" style={{ marginBottom: "12px" }}>
                      <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                        {__("Width", "zenblocks")}
                      </label>
                      <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                        <div style={{ flex: 1, opacity: isPosterWidthAuto ? 0.5 : 1, pointerEvents: isPosterWidthAuto ? "none" : "auto" }}>
                          <UnitControl
                            value={isPosterWidthAuto ? "" : `${posterCustomWidth}${posterCustomWidthUnit}`}
                            onChange={(value) => {
                              const numValue = parseFloat(value);
                              const unit = value.replace(/[\d.-]/g, "") || posterCustomWidthUnit;
                              const updates = {};
                              if (!isNaN(numValue)) updates.backgroundPosterCustomWidth = String(numValue);
                              if (unit) updates.backgroundPosterCustomWidthUnit = unit;
                              if (Object.keys(updates).length > 0) setAttributes(updates);
                            }}
                            units={customSizeUnits}
                            placeholder={isPosterWidthAuto ? "auto" : ""}
                          />
                        </div>
                        <Button
                          isSmall
                          variant={isPosterWidthAuto ? "primary" : "secondary"}
                          onClick={() => {
                            if (isPosterWidthAuto) {
                              setAttributes({ backgroundPosterCustomWidth: "100", backgroundPosterCustomWidthUnit: "%" });
                            } else {
                              setAttributes({ backgroundPosterCustomWidth: "auto" });
                            }
                          }}
                        >
                          AUTO
                        </Button>
                      </div>
                    </div>

                    <div className="zenblocks-inspector-background-image__height-controls" style={{ marginBottom: "12px" }}>
                      <label style={{ display: "block", marginBottom: "4px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>
                        {__("Height", "zenblocks")}
                      </label>
                      <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
                        <div style={{ flex: 1, opacity: isPosterHeightAuto ? 0.5 : 1, pointerEvents: isPosterHeightAuto ? "none" : "auto" }}>
                          <UnitControl
                            value={isPosterHeightAuto ? "" : `${posterCustomHeight}${posterCustomHeightUnit}`}
                            onChange={(value) => {
                              const numValue = parseFloat(value);
                              const unit = value.replace(/[\d.-]/g, "") || posterCustomHeightUnit;
                              const updates = {};
                              if (!isNaN(numValue)) updates.backgroundPosterCustomHeight = String(numValue);
                              if (unit) updates.backgroundPosterCustomHeightUnit = unit;
                              if (Object.keys(updates).length > 0) setAttributes(updates);
                            }}
                            units={customSizeUnits}
                            placeholder={isPosterHeightAuto ? "auto" : ""}
                          />
                        </div>
                        <Button
                          isSmall
                          variant={isPosterHeightAuto ? "primary" : "secondary"}
                          onClick={() => {
                            if (isPosterHeightAuto) {
                              setAttributes({ backgroundPosterCustomHeight: "100", backgroundPosterCustomHeightUnit: "%" });
                            } else {
                              setAttributes({ backgroundPosterCustomHeight: "auto" });
                            }
                          }}
                        >
                          AUTO
                        </Button>
                      </div>
                    </div>
                  </>
                )}
              </div>
            </>
          )}
        </div>
      ) : (
        <ResponsiveControlV2
          initialOpen={true}
          enableResponsiveToggle={true}
          responsiveEnabled={responsiveEnabled}
          onResponsiveToggle={handleResponsiveToggle}
          attributes={attributes}
          setAttributes={setAttributes}
          syncAttributeName={responsiveAttrName}
        >
          {(tabName) => renderImageControls(tabName)}
        </ResponsiveControlV2>
      )}
    </div>
  );

  return (
    <PanelBodyWithSync title={title} initialOpen={initialOpen} opened={opened} onToggle={onToggle} onSync={effectiveHoverState ? handleSyncImage : undefined} className="zenblocks-nested-panel" level={2} panelType="settings" panelName="background-image">
      {isPro ? <ProFeatureOverlay featureName="背景画像" learnMorePath={learnMorePath}>{content}</ProFeatureOverlay> : content}
    </PanelBodyWithSync>
  );
};

export const getBackgroundImageValue = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "backgroundImageV2Hover" : "backgroundImageV2";
  const data = attributes[attrName];
  if (!data) return null;

  const enabledBreakpoints = getEnabledBreakpoints();
  const currentIndex = enabledBreakpoints.indexOf(device);

  for (let i = currentIndex; i >= 0; i--) {
    const bp = enabledBreakpoints[i];
    const bpData = data[bp];
    if (bpData && bpData.url && bpData.url !== "") {
      return bpData.url;
    }
  }
  return null;
};

export const getBackgroundImagePosition = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "backgroundImageV2Hover" : "backgroundImageV2";
  const data = attributes[attrName];
  if (!data) return "50% 50%";

  const enabledBreakpoints = getEnabledBreakpoints();
  const currentIndex = enabledBreakpoints.indexOf(device);

  for (let i = currentIndex; i >= 0; i--) {
    const bp = enabledBreakpoints[i];
    const bpData = data[bp];
    if (bpData && bpData.position && bpData.position !== "") {
      return bpData.position;
    }
  }
  return "50% 50%";
};

export const getBackgroundImageSize = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "backgroundImageV2Hover" : "backgroundImageV2";
  const data = attributes[attrName];
  if (!data) return "cover";

  const enabledBreakpoints = getEnabledBreakpoints();
  const currentIndex = enabledBreakpoints.indexOf(device);

  for (let i = currentIndex; i >= 0; i--) {
    const bp = enabledBreakpoints[i];
    const bpData = data[bp];
    if (bpData && bpData.size && bpData.size !== "") {
      if (bpData.size === "fill" || bpData.size === "none") {
        const w = bpData.customWidth || "auto";
        const wUnit = bpData.customWidthUnit || "%";
        const h = bpData.customHeight || "auto";
        const hUnit = bpData.customHeightUnit || "%";
        const width = w === "auto" ? "auto" : `${w}${wUnit}`;
        const height = h === "auto" ? "auto" : `${h}${hUnit}`;
        return `${width} ${height}`;
      }
      return bpData.size;
    }
  }
  return "cover";
};

export const getBackgroundImageRepeat = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "backgroundImageV2Hover" : "backgroundImageV2";
  const data = attributes[attrName];
  if (!data) return "no-repeat";

  const enabledBreakpoints = getEnabledBreakpoints();
  const currentIndex = enabledBreakpoints.indexOf(device);

  for (let i = currentIndex; i >= 0; i--) {
    const bp = enabledBreakpoints[i];
    const bpData = data[bp];
    if (bpData && bpData.repeat && bpData.repeat !== "") {
      return bpData.repeat;
    }
  }
  return "no-repeat";
};

export default BackgroundImageSettingV7;
