import { PanelBody, Button, SelectControl, FocalPointPicker, RangeControl, Notice } from "@wordpress/components";
import CustomColorPalette from "../../CustomColorPalette";
import { __ } from "@wordpress/i18n";
import ResponsiveControlV2 from "../../ResponsiveControlV2";
import { useResponsiveTabV2 } from "../../ResponsiveTabContextV2";
import { __experimentalUnitControl as UnitControl } from "@wordpress/components";
import PanelBodyWithSync from "../../PanelBodyWithSync";
import ProFeatureOverlay from "../../ProFeatureOverlay";
import StyledToggle from "../../StyledToggle";
import { getEnabledBreakpoints } from "../../../../../core/breakpoints";
import BandTransitionSetting from "./BandTransitionSetting";
import BandPatternSettingV7 from "./BandPatternSettingV7";
import ImageSelector from "../../ImageSelector";
import VideoMediaSelector from "../../VideoMediaSelector";
import { getResolvedPresetImages, presetCategories } from "../../../../../assets/images/presets/backgrounds";

const getDefaultBandImage = () => ({
  pc: { url: "", focalPosition: "50% 50%", objectFit: "cover", repeat: "no-repeat", bgWidth: "100", bgWidthUnit: "%", bgHeight: "auto", bgHeightUnit: "%", rotate: "0", frameWidth: 100, frameWidthUnit: "%", frameHeight: 60, frameHeightUnit: "px", borderEnabled: false, borderWidth: 0, borderStyle: "none", borderColor: "transparent", borderColorAlpha: 1, borderBoxSizing: "border-box", borderRadius: 0, borderRadiusUnit: "px", offsetX: 0, offsetXUnit: "%", offsetY: 0, offsetYUnit: "%", originX: "left", originY: "top", opacity: 1 },
  md: { url: "", focalPosition: "", objectFit: "", repeat: "", bgWidth: "", bgWidthUnit: "", bgHeight: "", bgHeightUnit: "", rotate: "", frameWidth: "", frameWidthUnit: "", frameHeight: "", frameHeightUnit: "", borderEnabled: "", borderWidth: "", borderStyle: "", borderColor: "", borderColorAlpha: "", borderBoxSizing: "", borderRadius: "", borderRadiusUnit: "", offsetX: "", offsetXUnit: "", offsetY: "", offsetYUnit: "", originX: "", originY: "", opacity: "" },
  tb: { url: "", focalPosition: "", objectFit: "", repeat: "", bgWidth: "", bgWidthUnit: "", bgHeight: "", bgHeightUnit: "", rotate: "", frameWidth: "", frameWidthUnit: "", frameHeight: "", frameHeightUnit: "", borderEnabled: "", borderWidth: "", borderStyle: "", borderColor: "", borderColorAlpha: "", borderBoxSizing: "", borderRadius: "", borderRadiusUnit: "", offsetX: "", offsetXUnit: "", offsetY: "", offsetYUnit: "", originX: "", originY: "", opacity: "" },
  sp: { url: "", focalPosition: "", objectFit: "", repeat: "", bgWidth: "", bgWidthUnit: "", bgHeight: "", bgHeightUnit: "", rotate: "", frameWidth: "", frameWidthUnit: "", frameHeight: "", frameHeightUnit: "", borderEnabled: "", borderWidth: "", borderStyle: "", borderColor: "", borderColorAlpha: "", borderBoxSizing: "", borderRadius: "", borderRadiusUnit: "", offsetX: "", offsetXUnit: "", offsetY: "", offsetYUnit: "", originX: "", originY: "", opacity: "" },
});

const getDefaultBandColor = () => ({
  pc: { color: "transparent", gradient: null, useGradient: false, opacity: 1, mixBlendMode: "normal" },
  md: { color: "", gradient: "", useGradient: null, opacity: "", mixBlendMode: "" },
  tb: { color: "", gradient: "", useGradient: null, opacity: "", mixBlendMode: "" },
  sp: { color: "", gradient: "", useGradient: null, opacity: "", mixBlendMode: "" },
});

const getDefaultBandImageBaseColor = () => ({
  pc: { color: "", alpha: 1, gradient: null, useGradient: false },
  md: { color: "", alpha: "", gradient: "", useGradient: null },
  tb: { color: "", alpha: "", gradient: "", useGradient: null },
  sp: { color: "", alpha: "", gradient: "", useGradient: null },
});

const getDefaultBandOpacity = () => ({
  pc: { value: 100, mixBlendMode: "normal" },
  md: { value: "", mixBlendMode: "" },
  tb: { value: "", mixBlendMode: "" },
  sp: { value: "", mixBlendMode: "" },
});

const getDefaultBandTransform = () => ({
  pc: { skewX: 0, skewY: 0 },
  md: { skewX: "", skewY: "" },
  tb: { skewX: "", skewY: "" },
  sp: { skewX: "", skewY: "" },
});

const mixBlendModes = [
  { label: __("Normal", "zenblocks"), value: "normal" },
  { label: __("Multiply", "zenblocks"), value: "multiply" },
  { label: __("Screen", "zenblocks"), value: "screen" },
  { label: __("Overlay", "zenblocks"), value: "overlay" },
  { label: __("Darken", "zenblocks"), value: "darken" },
  { label: __("Lighten", "zenblocks"), value: "lighten" },
  { label: __("Color Dodge", "zenblocks"), value: "color-dodge" },
  { label: __("Color Burn", "zenblocks"), value: "color-burn" },
  { label: __("Hard Light", "zenblocks"), value: "hard-light" },
  { label: __("Soft Light", "zenblocks"), value: "soft-light" },
  { label: __("Difference", "zenblocks"), value: "difference" },
  { label: __("Exclusion", "zenblocks"), value: "exclusion" },
  { label: __("Hue", "zenblocks"), value: "hue" },
  { label: __("Saturation", "zenblocks"), value: "saturation" },
  { label: __("Color", "zenblocks"), value: "color" },
  { label: __("Luminosity", "zenblocks"), value: "luminosity" },
];

const parseFocalPositionToPercent = (position, fallbackX = 50, fallbackY = 50) => {
  const raw = String(position || "").trim();
  if (!raw) return { x: fallbackX, y: fallbackY };
  const parts = raw.split(/\s+/);
  const x = parseFloat(String(parts[0] || `${fallbackX}%`).replace("%", ""));
  const y = parseFloat(String(parts[1] || `${fallbackY}%`).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 BandSettingV7 = ({ attributes, setAttributes, title, initialOpen = false, opened, onToggle, isHoverState = false, onSync, panelStates = {}, onTogglePanel, isPro = false, level = 1 }) => {
  const suffix = isHoverState ? "Hover" : "";
  const imageAttrName = `bandImageV2${suffix}`;
  const colorAttrName = `bandColorV2${suffix}`;
  const imageBaseColorAttrName = `bandImageBaseColorV2${suffix}`;
  const responsiveAttrName = `useResponsiveBandImage${suffix}`;
  const responsiveSizeAttrName = `useResponsiveBandSize${suffix}`;
  const responsiveRadiusAttrName = `useResponsiveBandRadius${suffix}`;
  const responsivePositionAttrName = `useResponsiveBandPosition${suffix}`;
  const responsiveBorderAttrName = `useResponsiveBandBorder${suffix}`;
  const responsiveColorAttrName = `useResponsiveBandColor${suffix}`;
  const responsiveImageBaseColorAttrName = `useResponsiveBandImageBaseColor${suffix}`;
  const responsiveEnabled = attributes[responsiveAttrName] !== undefined ? attributes[responsiveAttrName] : false;
  const responsiveSizeEnabled = attributes[responsiveSizeAttrName] !== undefined ? attributes[responsiveSizeAttrName] : responsiveEnabled;
  const responsiveRadiusEnabled = attributes[responsiveRadiusAttrName] !== undefined ? attributes[responsiveRadiusAttrName] : responsiveEnabled;
  const responsivePositionEnabled = attributes[responsivePositionAttrName] !== undefined ? attributes[responsivePositionAttrName] : responsiveEnabled;
  const responsiveBorderEnabled = attributes[responsiveBorderAttrName] !== undefined ? attributes[responsiveBorderAttrName] : false;
  const responsiveColorEnabled = attributes[responsiveColorAttrName] !== undefined ? attributes[responsiveColorAttrName] : false;
  const responsiveImageBaseColorEnabled = attributes[responsiveImageBaseColorAttrName] !== undefined ? attributes[responsiveImageBaseColorAttrName] : false;
  const bandOpacityAttrName = `bandOpacityV2${suffix}`;
  const responsiveBandOpacityAttrName = `useResponsiveBandOpacity${suffix}`;
  const responsiveBandOpacityEnabled = attributes[responsiveBandOpacityAttrName] !== undefined ? attributes[responsiveBandOpacityAttrName] : false;
  const bandTransformAttrName = `bandTransformV2${suffix}`;
  const responsiveBandTransformAttrName = `useResponsiveBandTransform${suffix}`;
  const responsiveBandTransformEnabled = attributes[responsiveBandTransformAttrName] !== undefined ? attributes[responsiveBandTransformAttrName] : false;
  const { activeTab } = useResponsiveTabV2();
  const enabledBreakpoints = getEnabledBreakpoints();

  const bandImageData = attributes[imageAttrName] || getDefaultBandImage();
  const bandColorData = attributes[colorAttrName] || getDefaultBandColor();
  const bandImageBaseColorData = attributes[imageBaseColorAttrName] || getDefaultBandImageBaseColor();
  const bandOpacityData = attributes[bandOpacityAttrName] || getDefaultBandOpacity();
  const bandTransformData = attributes[bandTransformAttrName] || getDefaultBandTransform();
  const bandMediaType = attributes.bandMediaType || "image";
  const imageKeys = ["url", "focalPosition", "objectFit", "repeat", "bgWidth", "bgWidthUnit", "bgHeight", "bgHeightUnit", "rotate", "opacity"];
  const sizeKeys = ["frameWidth", "frameWidthUnit", "frameHeight", "frameHeightUnit"];
  const radiusKeys = ["borderRadius", "borderRadiusUnit"];
  const positionKeys = ["offsetX", "offsetXUnit", "offsetY", "offsetYUnit", "originX", "originY"];

  const handleSyncImage = () => {
    if (isHoverState) {
      const normalData = attributes.bandImageV2 || getDefaultBandImage();
      const normalResponsive = attributes.useResponsiveBandImage || false;
      const normalResponsiveSize = attributes.useResponsiveBandSize !== undefined ? attributes.useResponsiveBandSize : normalResponsive;
      const normalResponsiveRadius = attributes.useResponsiveBandRadius !== undefined ? attributes.useResponsiveBandRadius : normalResponsive;
      const normalResponsivePosition = attributes.useResponsiveBandPosition !== undefined ? attributes.useResponsiveBandPosition : normalResponsive;
      setAttributes({
        bandImageV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandImageHover: normalResponsive,
        useResponsiveBandSizeHover: normalResponsiveSize,
        useResponsiveBandRadiusHover: normalResponsiveRadius,
        useResponsiveBandPositionHover: normalResponsivePosition,
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleSyncBorder = () => {
    if (isHoverState) {
      const normalData = attributes.bandImageV2 || getDefaultBandImage();
      const normalResponsive = attributes.useResponsiveBandBorder || false;
      setAttributes({
        bandImageV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandBorderHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleSyncColor = () => {
    if (isHoverState) {
      const normalData = attributes.bandColorV2 || getDefaultBandColor();
      const normalResponsive = attributes.useResponsiveBandColor || false;
      setAttributes({
        bandColorV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandColorHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleSyncImageBaseColor = () => {
    if (isHoverState) {
      const normalData = attributes.bandImageBaseColorV2 || getDefaultBandImageBaseColor();
      const normalResponsive = attributes.useResponsiveBandImageBaseColor || false;
      setAttributes({
        bandImageBaseColorV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandImageBaseColorHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleSyncPattern = () => {
    if (isHoverState) {
      const defaultPattern = {
        pc: { type: "none", color: "#000000", opacity: 0.5, size: 3, sizeUnit: "px", mixBlendMode: "normal" },
        md: { type: "", color: "", opacity: "", size: "", sizeUnit: "", mixBlendMode: "" },
        tb: { type: "", color: "", opacity: "", size: "", sizeUnit: "", mixBlendMode: "" },
        sp: { type: "", color: "", opacity: "", size: "", sizeUnit: "", mixBlendMode: "" },
      };
      const normalData = attributes.bandPatternV2 || defaultPattern;
      const normalResponsive = attributes.useResponsiveBandPattern || false;
      setAttributes({
        bandPatternV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandPatternHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleSyncBandOpacity = () => {
    if (isHoverState) {
      const normalData = attributes.bandOpacityV2 || getDefaultBandOpacity();
      const normalResponsive = attributes.useResponsiveBandOpacity || false;
      setAttributes({
        bandOpacityV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandOpacityHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleBandOpacityChange = (value) => {
    const newData = JSON.parse(JSON.stringify(bandOpacityData));
    if (!responsiveBandOpacityEnabled) {
      enabledBreakpoints.forEach((bp) => {
        newData[bp].value = value;
      });
    } else {
      newData[activeTab].value = value;
    }
    setAttributes({ [bandOpacityAttrName]: newData });
  };

  const handleBandMixBlendModeChange = (value) => {
    const newData = JSON.parse(JSON.stringify(bandOpacityData));
    if (!responsiveBandOpacityEnabled) {
      enabledBreakpoints.forEach((bp) => {
        newData[bp].mixBlendMode = value;
      });
    } else {
      newData[activeTab].mixBlendMode = value;
    }
    setAttributes({ [bandOpacityAttrName]: newData });
  };

  const handleResponsiveBandOpacityToggle = (value) => {
    setAttributes({ [responsiveBandOpacityAttrName]: value });
    const newData = JSON.parse(JSON.stringify(bandOpacityData));
    const pcData = newData.pc;
    enabledBreakpoints.forEach((bp) => {
      if (bp !== 'pc') {
        newData[bp] = { ...pcData };
      }
    });
    setAttributes({ [bandOpacityAttrName]: newData });
  };

  const renderBandOpacityControls = (tabName) => {
    const tabData = bandOpacityData[tabName] || getDefaultBandOpacity().pc;
    const opacityValue = tabData.value === "" ? 100 : tabData.value;
    const mixBlendModeValue = tabData.mixBlendMode || "normal";

    return (
      <>
        <RangeControl
          label={__("Opacity", "zenblocks")}
          value={opacityValue / 100}
          onChange={(value) => handleBandOpacityChange(Math.round(value * 100))}
          min={0}
          max={1}
          step={0.01}
        />
        <SelectControl
          label={__("Mix Blend Mode", "zenblocks")}
          value={mixBlendModeValue}
          options={mixBlendModes}
          onChange={handleBandMixBlendModeChange}
        />
      </>
    );
  };

  const handleSyncBandTransform = () => {
    if (isHoverState) {
      const normalData = attributes.bandTransformV2 || getDefaultBandTransform();
      const normalResponsive = attributes.useResponsiveBandTransform || false;
      setAttributes({
        bandTransformV2Hover: JSON.parse(JSON.stringify(normalData)),
        useResponsiveBandTransformHover: normalResponsive
      });
    } else if (onSync) {
      onSync();
    }
  };

  const handleBandSkewXChange = (value) => {
    const newData = JSON.parse(JSON.stringify(bandTransformData));
    if (!responsiveBandTransformEnabled) {
      enabledBreakpoints.forEach((bp) => {
        newData[bp].skewX = value;
      });
    } else {
      newData[activeTab].skewX = value;
    }
    setAttributes({ [bandTransformAttrName]: newData });
  };

  const handleBandSkewYChange = (value) => {
    const newData = JSON.parse(JSON.stringify(bandTransformData));
    if (!responsiveBandTransformEnabled) {
      enabledBreakpoints.forEach((bp) => {
        newData[bp].skewY = value;
      });
    } else {
      newData[activeTab].skewY = value;
    }
    setAttributes({ [bandTransformAttrName]: newData });
  };

  const handleResponsiveBandTransformToggle = (value) => {
    setAttributes({ [responsiveBandTransformAttrName]: value });
    const newData = JSON.parse(JSON.stringify(bandTransformData));
    const pcData = newData.pc;
    enabledBreakpoints.forEach((bp) => {
      if (bp !== 'pc') {
        newData[bp] = { ...pcData };
      }
    });
    setAttributes({ [bandTransformAttrName]: newData });
  };

  const handleBandMediaTypeChange = (type) => {
    if (type !== "video" || bandMediaType === "video") {
      setAttributes({ bandMediaType: type });
      return;
    }

    const normalImageData = attributes.bandImageV2 || getDefaultBandImage();
    const source = normalImageData.pc || {};
    const sourceUrl = source.url || "";
    const sourceFit = source.objectFit || "cover";
    const sourcePos = parseFocalPositionToPercent(source.focalPosition || "50% 50%", 50, 50);
    const sourceWidth = source.bgWidth || "100";
    const sourceWidthUnit = source.bgWidthUnit || "%";
    const sourceHeight = source.bgHeight || "auto";
    const sourceHeightUnit = source.bgHeightUnit || "%";
    const updates = { bandMediaType: "video" };
    updates.bandVideoFit = sourceFit;
    updates.bandVideoPositionX = sourcePos.x;
    updates.bandVideoPositionY = sourcePos.y;
    updates.bandVideoCustomWidth = sourceWidth;
    updates.bandVideoCustomWidthUnit = sourceWidthUnit;
    updates.bandVideoCustomHeight = sourceHeight;
    updates.bandVideoCustomHeightUnit = sourceHeightUnit;
    updates.bandPosterFit = sourceFit;
    updates.bandPosterPositionX = sourcePos.x;
    updates.bandPosterPositionY = sourcePos.y;
    updates.bandPosterCustomWidth = sourceWidth;
    updates.bandPosterCustomWidthUnit = sourceWidthUnit;
    updates.bandPosterCustomHeight = sourceHeight;
    updates.bandPosterCustomHeightUnit = sourceHeightUnit;

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

    setAttributes(updates);
  };

  const renderBandTransformControls = (tabName) => {
    const tabData = bandTransformData[tabName] || getDefaultBandTransform().pc;
    const skewXValue = tabData.skewX === "" ? 0 : tabData.skewX;
    const skewYValue = tabData.skewY === "" ? 0 : tabData.skewY;

    return (
      <>
        <RangeControl
          label={__("Skew X", "zenblocks")}
          value={skewXValue}
          onChange={handleBandSkewXChange}
          min={-90}
          max={90}
          step={1}
        />
        <RangeControl
          label={__("Skew Y", "zenblocks")}
          value={skewYValue}
          onChange={handleBandSkewYChange}
          min={-90}
          max={90}
          step={1}
        />
      </>
    );
  };

  const handleImageChange = (keyOrChanges, value, responsiveFlag = responsiveEnabled) => {
    const newData = JSON.parse(JSON.stringify(bandImageData));
    const changes = typeof keyOrChanges === 'object' ? keyOrChanges : { [keyOrChanges]: value };
    if (responsiveFlag) {
      Object.entries(changes).forEach(([k, v]) => {
        newData[activeTab][k] = v;
      });
    } else {
      enabledBreakpoints.forEach((bp) => {
        Object.entries(changes).forEach(([k, v]) => {
          newData[bp][k] = v;
        });
      });
    }
    setAttributes({ [imageAttrName]: newData });
  };

  const handleColorChange = (key, value) => {
    const newData = JSON.parse(JSON.stringify(bandColorData));
    if (responsiveColorEnabled) {
      newData[activeTab][key] = value;
    } else {
      enabledBreakpoints.forEach((bp) => {
        newData[bp][key] = value;
      });
    }
    setAttributes({ [colorAttrName]: newData });
  };

  const applyResponsiveToggleForKeys = (attrName, value, targetKeys) => {
    setAttributes({ [attrName]: value });
    const newData = JSON.parse(JSON.stringify(bandImageData));
    if (value) {
      const pcData = newData.pc || {};
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          targetKeys.forEach((key) => {
            newData[bp][key] = pcData[key];
          });
        }
      });
    } else {
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          const defaultBp = getDefaultBandImage()[bp];
          targetKeys.forEach((key) => {
            newData[bp][key] = defaultBp[key];
          });
        }
      });
    }
    setAttributes({ [imageAttrName]: newData });
  };

  const handleResponsiveToggle = (value) => {
    applyResponsiveToggleForKeys(responsiveAttrName, value, imageKeys);
  };

  const handleResponsiveSizeToggle = (value) => {
    applyResponsiveToggleForKeys(responsiveSizeAttrName, value, sizeKeys);
  };

  const handleResponsiveRadiusToggle = (value) => {
    applyResponsiveToggleForKeys(responsiveRadiusAttrName, value, radiusKeys);
  };

  const handleResponsivePositionToggle = (value) => {
    applyResponsiveToggleForKeys(responsivePositionAttrName, value, positionKeys);
  };

  const handleResponsiveColorToggle = (value) => {
    setAttributes({ [responsiveColorAttrName]: value });
    if (value) {
      const newData = JSON.parse(JSON.stringify(bandColorData));
      const pcData = newData.pc || {};
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          Object.keys(pcData).forEach((key) => {
            newData[bp][key] = pcData[key];
          });
        }
      });
      setAttributes({ [colorAttrName]: newData });
    } else {
      const newData = JSON.parse(JSON.stringify(bandColorData));
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          const defaultBp = getDefaultBandColor()[bp];
          Object.keys(defaultBp).forEach((key) => {
            newData[bp][key] = defaultBp[key];
          });
        }
      });
      setAttributes({ [colorAttrName]: newData });
    }
  };

  const handleImageBaseColorChange = (key, value) => {
    const newData = JSON.parse(JSON.stringify(bandImageBaseColorData));
    if (responsiveImageBaseColorEnabled) {
      newData[activeTab][key] = value;
    } else {
      enabledBreakpoints.forEach((bp) => {
        newData[bp][key] = value;
      });
    }
    setAttributes({ [imageBaseColorAttrName]: newData });
  };

  const handleResponsiveImageBaseColorToggle = (value) => {
    const newData = JSON.parse(JSON.stringify(bandImageBaseColorData));
    const emptyBpData = { color: "", alpha: "", gradient: "", useGradient: null };

    if (value) {
      // レスポンシブON: PCの値をMD/TB/SPにコピー（同期）
      const pcData = newData.pc || getDefaultBandImageBaseColor().pc;
      enabledBreakpoints.forEach((bp) => {
        if (bp !== 'pc') {
          newData[bp] = { ...pcData };
        }
      });
    } else {
      // レスポンシブOFF: MD/TB/SPをデフォルト（空）にリセット（PCから継承）
      enabledBreakpoints.forEach((bp) => {
        if (bp !== 'pc') {
          newData[bp] = { ...emptyBpData };
        }
      });
    }

    setAttributes({
      [responsiveImageBaseColorAttrName]: value,
      [imageBaseColorAttrName]: newData
    });
  };

  const resetImageBaseColor = () => {
    const defaultData = getDefaultBandImageBaseColor();
    if (responsiveImageBaseColorEnabled) {
      const newData = JSON.parse(JSON.stringify(bandImageBaseColorData));
      newData[activeTab] = { ...defaultData.pc };
      setAttributes({ [imageBaseColorAttrName]: newData });
    } else {
      setAttributes({ [imageBaseColorAttrName]: defaultData });
    }
  };

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

  const renderImageControls = (tabName) => {
    const defaultTab = getDefaultBandImage().pc;
    const tabData = bandImageData[tabName] || defaultTab;
    const imageUrl = tabData.url || "";
    const focalPosition = tabData.focalPosition || defaultTab.focalPosition;
    const objectFit = tabData.objectFit || defaultTab.objectFit;
    const repeat = tabData.repeat || defaultTab.repeat;
    const bgWidth = tabData.bgWidth || defaultTab.bgWidth;
    const bgWidthUnit = tabData.bgWidthUnit || defaultTab.bgWidthUnit;
    const bgHeight = tabData.bgHeight || defaultTab.bgHeight;
    const bgHeightUnit = tabData.bgHeightUnit || defaultTab.bgHeightUnit;
    const imageRotate = tabData.rotate !== undefined && tabData.rotate !== null && tabData.rotate !== "" ? String(tabData.rotate) : defaultTab.rotate;
    const isWidthAuto = bgWidth === "auto";
    const isHeightAuto = bgHeight === "auto";
    const imageOpacity = tabData.opacity !== "" && tabData.opacity !== undefined ? tabData.opacity : 1;

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

    // ホバー時は常に通常状態の画像URLを表示（ホバーでは独自画像アップロードしないため）
    const normalImageData = attributes.bandImageV2 || getDefaultBandImage();
    const displayImageUrl = isHoverState
      ? (normalImageData[tabName]?.url || normalImageData.pc?.url || "")
      : imageUrl;

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

    if (!isHoverState && bandMediaType === "video") {
      return (
        <VideoMediaSelector
          videoUrl={attributes.bandVideoUrl || ""}
          posterUrl={attributes.bandVideoPoster || ""}
          onChangeVideo={(url) => setAttributes({ bandVideoUrl: url })}
          onChangePoster={(url) => setAttributes({ bandVideoPoster: url })}
          iframeTitle="Band video"
          showPresentationControls={true}
          videoFit={attributes.bandVideoFit || "cover"}
          videoPositionX={Number.isFinite(Number(attributes.bandVideoPositionX)) ? Number(attributes.bandVideoPositionX) : 50}
          videoPositionY={Number.isFinite(Number(attributes.bandVideoPositionY)) ? Number(attributes.bandVideoPositionY) : 50}
          videoCustomWidth={attributes.bandVideoCustomWidth || "100"}
          videoCustomWidthUnit={attributes.bandVideoCustomWidthUnit || "%"}
          videoCustomHeight={attributes.bandVideoCustomHeight || "auto"}
          videoCustomHeightUnit={attributes.bandVideoCustomHeightUnit || "%"}
          onChangeVideoFit={(value) => setAttributes({ bandVideoFit: value })}
          onChangeVideoPositionX={(value) => setAttributes({ bandVideoPositionX: value })}
          onChangeVideoPositionY={(value) => setAttributes({ bandVideoPositionY: value })}
          onChangeVideoCustomWidth={(value) => setAttributes({ bandVideoCustomWidth: value })}
          onChangeVideoCustomWidthUnit={(value) => setAttributes({ bandVideoCustomWidthUnit: value })}
          onChangeVideoCustomHeight={(value) => setAttributes({ bandVideoCustomHeight: value })}
          onChangeVideoCustomHeightUnit={(value) => setAttributes({ bandVideoCustomHeightUnit: value })}
          posterFit={attributes.bandPosterFit || "cover"}
          posterPositionX={Number.isFinite(Number(attributes.bandPosterPositionX)) ? Number(attributes.bandPosterPositionX) : 50}
          posterPositionY={Number.isFinite(Number(attributes.bandPosterPositionY)) ? Number(attributes.bandPosterPositionY) : 50}
          posterCustomWidth={attributes.bandPosterCustomWidth || "100"}
          posterCustomWidthUnit={attributes.bandPosterCustomWidthUnit || "%"}
          posterCustomHeight={attributes.bandPosterCustomHeight || "auto"}
          posterCustomHeightUnit={attributes.bandPosterCustomHeightUnit || "%"}
          onChangePosterFit={(value) => setAttributes({ bandPosterFit: value })}
          onChangePosterPositionX={(value) => setAttributes({ bandPosterPositionX: value })}
          onChangePosterPositionY={(value) => setAttributes({ bandPosterPositionY: value })}
          onChangePosterCustomWidth={(value) => setAttributes({ bandPosterCustomWidth: value })}
          onChangePosterCustomWidthUnit={(value) => setAttributes({ bandPosterCustomWidthUnit: value })}
          onChangePosterCustomHeight={(value) => setAttributes({ bandPosterCustomHeight: value })}
          onChangePosterCustomHeightUnit={(value) => setAttributes({ bandPosterCustomHeightUnit: value })}
        />
      );
    }

    if (isHoverState && bandMediaType === "video") {
      return (
        <p style={{ fontSize: "12px", color: "#757575", marginBottom: "12px", padding: "8px", backgroundColor: "#f0f0f0", borderRadius: "4px" }}>
          {__("Band video uses the default state settings.", "zenblocks")}
        </p>
      );
    }

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

        {/* ホバー時は通常設定の画像を使用する旨を表示 */}
        {isHoverState && (
          <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 && (
          <div className="zenblocks-inspector-band-image__settings">
            <FocalPointPicker
              key={displayImageUrl}
              url={displayImageUrl}
              value={{ x, y }}
              onChange={(focalPoint) => {
                const position = `${focalPoint.x * 100}% ${focalPoint.y * 100}%`;
                handleImageChange("focalPosition", position);
              }}
            />

            <SelectControl
              label={__("Repeat", "zenblocks")}
              value={repeat}
              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) => handleImageChange("repeat", value)}
              className="zenblocks-inspector-band-image__repeat-select"
            />

            <SelectControl
              label={__("Fit Method", "zenblocks")}
              value={objectFit}
              options={[
                { label: __("Cover", "zenblocks"), value: "cover" },
                { label: __("Contain", "zenblocks"), value: "contain" },
                { label: __("Fill", "zenblocks"), value: "fill" },
                { label: __("None", "zenblocks"), value: "none" },
              ]}
              onChange={(value) => handleImageChange("objectFit", value)}
              className="zenblocks-inspector-band-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>
            )}

            {(objectFit === "fill" || objectFit === "none") && (
              <div className="zenblocks-inspector-band-image__custom-size" style={{ marginTop: "10px" }}>
                <div className="zenblocks-inspector-band-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 ? "" : `${bgWidth}${bgWidthUnit}`}
                        onChange={(value) => {
                          const numValue = parseFloat(value);
                          const unit = value.replace(/[\d.-]/g, "") || bgWidthUnit;
                          const changes = {};
                          if (!isNaN(numValue)) changes.bgWidth = String(numValue);
                          if (unit) changes.bgWidthUnit = unit;
                          if (Object.keys(changes).length > 0) handleImageChange(changes);
                        }}
                        units={units}
                        placeholder={isWidthAuto ? "auto" : ""}
                      />
                    </div>
                    <Button
                      isSmall
                      variant={isWidthAuto ? "primary" : "secondary"}
                      onClick={() => {
                        if (isWidthAuto) {
                          handleImageChange({ bgWidth: "100", bgWidthUnit: "%" });
                        } else {
                          handleImageChange("bgWidth", "auto");
                        }
                      }}
                      style={{ flexShrink: 0 }}
                    >
                      AUTO
                    </Button>
                  </div>
                </div>
                <div className="zenblocks-inspector-band-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 ? "" : `${bgHeight}${bgHeightUnit}`}
                        onChange={(value) => {
                          const numValue = parseFloat(value);
                          const unit = value.replace(/[\d.-]/g, "") || bgHeightUnit;
                          const changes = {};
                          if (!isNaN(numValue)) changes.bgHeight = String(numValue);
                          if (unit) changes.bgHeightUnit = unit;
                          if (Object.keys(changes).length > 0) handleImageChange(changes);
                        }}
                        units={units}
                        placeholder={isHeightAuto ? "auto" : ""}
                      />
                    </div>
                    <Button
                      isSmall
                      variant={isHeightAuto ? "primary" : "secondary"}
                      onClick={() => {
                        if (isHeightAuto) {
                          handleImageChange({ bgHeight: "100", bgHeightUnit: "%" });
                        } else {
                          handleImageChange("bgHeight", "auto");
                        }
                      }}
                      style={{ flexShrink: 0 }}
                    >
                      AUTO
                    </Button>
                  </div>
                </div>
              </div>
            )}

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

        <div style={{ marginTop: "16px" }}>
          <RangeControl
            label={__("Opacity", "zenblocks")}
            value={imageOpacity}
            onChange={(value) => handleImageChange("opacity", value)}
            min={0}
            max={1}
            step={0.1}
          />
        </div>
      </>
    );
  };

  const renderColorControls = (tabName) => {
    const tabData = bandColorData[tabName] || getDefaultBandColor().pc;
    const useGradient = tabData.useGradient || false;
    const color = tabData.color || "transparent";
    const gradient = tabData.gradient || "";
    const opacity = tabData.opacity !== "" && tabData.opacity !== undefined ? tabData.opacity : 1;
    const mixBlendMode = tabData.mixBlendMode || "normal";

    return (
      <>
        <CustomColorPalette
          color={color}
          gradient={gradient}
          useGradient={useGradient}
          enableGradient={true}
          enableAlpha={false}
          onColorChange={(value) => handleColorChange("color", value)}
          onGradientChange={(value) => handleColorChange("gradient", value)}
          onUseGradientChange={(value) => handleColorChange("useGradient", value)}
        />
        <RangeControl label={__("Opacity", "zenblocks")} value={opacity} onChange={(value) => handleColorChange("opacity", value)} min={0} max={1} step={0.1} />
        <SelectControl
          label={__("Blend Mode", "zenblocks")}
          value={mixBlendMode}
          options={[
            { label: __("Normal", "zenblocks"), value: "normal" },
            { label: __("Multiply", "zenblocks"), value: "multiply" },
            { label: __("Screen", "zenblocks"), value: "screen" },
            { label: __("Overlay", "zenblocks"), value: "overlay" },
            { label: __("Darken", "zenblocks"), value: "darken" },
            { label: __("Lighten", "zenblocks"), value: "lighten" },
            { label: __("Color Dodge", "zenblocks"), value: "color-dodge" },
            { label: __("Color Burn", "zenblocks"), value: "color-burn" },
            { label: __("Hard Light", "zenblocks"), value: "hard-light" },
            { label: __("Soft Light", "zenblocks"), value: "soft-light" },
            { label: __("Difference", "zenblocks"), value: "difference" },
            { label: __("Exclusion", "zenblocks"), value: "exclusion" },
            { label: __("Hue", "zenblocks"), value: "hue" },
            { label: __("Saturation", "zenblocks"), value: "saturation" },
            { label: __("Color", "zenblocks"), value: "color" },
            { label: __("Luminosity", "zenblocks"), value: "luminosity" },
          ]}
          onChange={(value) => handleColorChange("mixBlendMode", value)}
        />
        <Button
          isSecondary
          onClick={() => {
            handleColorChange("color", "transparent");
            handleColorChange("gradient", null);
            handleColorChange("useGradient", false);
            handleColorChange("opacity", 1);
            handleColorChange("mixBlendMode", "normal");
          }}
          style={{ marginTop: "10px" }}
        >
          {__("Reset to Transparent", "zenblocks")}
        </Button>
      </>
    );
  };

  const renderImageBaseColorControls = (tabName) => {
    const tabData = bandImageBaseColorData[tabName] || getDefaultBandImageBaseColor().pc;
    const currentColor = tabData.color || "";
    const currentAlpha = tabData.alpha !== "" && tabData.alpha !== undefined ? tabData.alpha : 1;
    const useGradient = tabData.useGradient || false;
    const gradient = tabData.gradient || "";

    return (
      <>
        <CustomColorPalette
          color={currentColor}
          alpha={currentAlpha}
          gradient={gradient}
          useGradient={useGradient}
          enableGradient={true}
          enableAlpha={true}
          enableAddButton={true}
          onColorChange={(value) => handleImageBaseColorChange("color", value || "")}
          onAlphaChange={(value) => handleImageBaseColorChange("alpha", value)}
          onGradientChange={(value) => handleImageBaseColorChange("gradient", value)}
          onUseGradientChange={(value) => handleImageBaseColorChange("useGradient", value)}
        />
        {useGradient && (
          <Notice status="warning" isDismissible={false} className="zenblocks-gradient-notice">
            {__("グラデーションにはトランジション効果が適用されません。スムーズなトランジションにはオーバーレイをご利用ください。", "zenblocks")}
          </Notice>
        )}

        <Button variant="secondary" onClick={resetImageBaseColor} style={{ marginTop: "10px" }}>
          {__("Reset", "zenblocks")}
        </Button>
      </>
    );
  };

  const renderSizeControls = (tabName) => {
    const tabData = bandImageData[tabName] || getDefaultBandImage().pc;
    const frameWidth = tabData.frameWidth !== "" && tabData.frameWidth !== undefined ? tabData.frameWidth : 100;
    const frameHeight = tabData.frameHeight !== "" && tabData.frameHeight !== undefined ? tabData.frameHeight : 60;
    const frameWidthUnit = tabData.frameWidthUnit || "%";
    const frameHeightUnit = tabData.frameHeightUnit || "px";

    return (
      <>
        <div style={{ marginBottom: "10px" }}>
          <UnitControl
            label={__("Width", "zenblocks")}
            value={`${frameWidth}${frameWidthUnit}`}
            onChange={(value) => {
              const numValue = parseFloat(value);
              const unit = value.replace(/[\d.-]/g, "");
              const changes = {};
              if (!isNaN(numValue)) changes.frameWidth = numValue;
              if (unit) changes.frameWidthUnit = unit;
              if (Object.keys(changes).length > 0) handleImageChange(changes, undefined, responsiveSizeEnabled);
            }}
            units={units}
          />
        </div>
        <div style={{ marginBottom: "10px" }}>
          <UnitControl
            label={__("Height", "zenblocks")}
            value={`${frameHeight}${frameHeightUnit}`}
            onChange={(value) => {
              const numValue = parseFloat(value);
              const unit = value.replace(/[\d.-]/g, "");
              const changes = {};
              if (!isNaN(numValue)) changes.frameHeight = numValue;
              if (unit) changes.frameHeightUnit = unit;
              if (Object.keys(changes).length > 0) handleImageChange(changes, undefined, responsiveSizeEnabled);
            }}
            units={units}
          />
        </div>
      </>
    );
  };

  const borderStyles = [
    { label: "None", value: "none", icon: null },
    { label: "Solid", value: "solid", icon: "solid" },
    { label: "Dashed", value: "dashed", icon: "dashed" },
    { label: "Dotted", value: "dotted", icon: "dotted" },
  ];

  const boxSizingOptions = [
    { label: "Border Box", value: "border-box" },
    { label: "Content Box", value: "content-box" },
  ];

  const BorderStyleIcon = ({ type }) => {
    const iconStyle = {
      width: "32px",
      height: "16px",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
    };

    if (type === null) {
      return (
        <span style={{ ...iconStyle, fontSize: "10px", fontWeight: "600" }}>
          NONE
        </span>
      );
    }

    if (type === "solid") {
      return (
        <span style={iconStyle}>
          <svg width="32" height="16" viewBox="0 0 32 16">
            <line x1="0" y1="8" x2="32" y2="8" stroke="currentColor" strokeWidth="3" />
          </svg>
        </span>
      );
    }

    if (type === "dashed") {
      return (
        <span style={iconStyle}>
          <svg width="32" height="16" viewBox="0 0 32 16">
            <line x1="1" y1="8" x2="31" y2="8" stroke="currentColor" strokeWidth="3" strokeDasharray="5 3" />
          </svg>
        </span>
      );
    }

    if (type === "dotted") {
      return (
        <span style={iconStyle}>
          <svg width="32" height="16" viewBox="0 0 32 16">
            <line x1="2" y1="8" x2="30" y2="8" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeDasharray="0.1 6" />
          </svg>
        </span>
      );
    }

    return null;
  };

  const handleBandBorderChange = (property, value) => {
    const newData = JSON.parse(JSON.stringify(bandImageData));
    if (responsiveBorderEnabled) {
      newData[activeTab][property] = value;
    } else {
      enabledBreakpoints.forEach((bp) => {
        newData[bp][property] = value;
      });
    }
    setAttributes({ [imageAttrName]: newData });
  };

  const handleResponsiveBorderToggle = (value) => {
    const borderKeys = ["borderEnabled", "borderWidth", "borderStyle", "borderColor", "borderColorAlpha", "borderBoxSizing"];
    setAttributes({ [responsiveBorderAttrName]: value });

    const newData = JSON.parse(JSON.stringify(bandImageData));
    if (value) {
      const pcData = newData.pc || {};
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          borderKeys.forEach((key) => {
            newData[bp][key] = pcData[key];
          });
        }
      });
    } else {
      enabledBreakpoints.forEach((bp) => {
        if (bp !== "pc") {
          const defaultBp = getDefaultBandImage()[bp];
          borderKeys.forEach((key) => {
            newData[bp][key] = defaultBp[key];
          });
        }
      });
    }
    setAttributes({ [imageAttrName]: newData });
  };

  const handleBandBorderEnabledToggle = (value) => {
    const newData = JSON.parse(JSON.stringify(bandImageData));
    const targetBps = responsiveBorderEnabled ? [activeTab] : enabledBreakpoints;
    targetBps.forEach((bp) => {
      newData[bp].borderEnabled = value;
      newData[bp].borderWidth = value ? 1 : 0;
      newData[bp].borderStyle = value ? "solid" : "none";
      newData[bp].borderColor = value ? "#000000" : "transparent";
      newData[bp].borderColorAlpha = 1;
      newData[bp].borderBoxSizing = "border-box";
    });
    setAttributes({ [imageAttrName]: newData });
  };

  const renderBorderControls = (tabName) => {
    const tabData = bandImageData[tabName] || getDefaultBandImage().pc;
    const borderEnabled = tabData.borderEnabled !== "" && tabData.borderEnabled !== undefined ? !!tabData.borderEnabled : false;
    const borderWidth = tabData.borderWidth === "" || tabData.borderWidth === undefined ? 0 : tabData.borderWidth;
    const borderStyle = tabData.borderStyle || "none";
    const borderColor = tabData.borderColor || "transparent";
    const borderColorAlpha = tabData.borderColorAlpha !== "" && tabData.borderColorAlpha !== undefined ? tabData.borderColorAlpha : 1;
    const borderBoxSizing = tabData.borderBoxSizing || "border-box";

    return (
      <>
        <StyledToggle
          label={__("Border", "zenblocks")}
          checked={borderEnabled}
          onChange={handleBandBorderEnabledToggle}
        />
        {borderEnabled && (
          <>
            <CustomColorPalette
              color={borderColor}
              alpha={borderColorAlpha}
              enableGradient={false}
              enableAlpha={true}
              onColorChange={(value) => handleBandBorderChange("borderColor", value === undefined || value === null ? "transparent" : value)}
              onAlphaChange={(value) => handleBandBorderChange("borderColorAlpha", value)}
              label={__("Color", "zenblocks")}
            />

            <RangeControl
              label={__("Width", "zenblocks")}
              value={borderWidth}
              onChange={(value) => handleBandBorderChange("borderWidth", value)}
              min={0}
              max={100}
              step={1}
            />

            <div className="zenblocks-inspector-band-border__style-select" style={{ marginBottom: "16px" }}>
              <label style={{ display: "block", marginBottom: "8px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>{__("Style", "zenblocks")}</label>
              <div className="border-side-button-group" style={{ display: "flex", gap: "4px" }}>
                {borderStyles.map((style) => (
                  <button
                    key={style.value}
                    type="button"
                    className={`border-side-button${borderStyle === style.value ? " is-checked" : ""}`}
                    onClick={() => handleBandBorderChange("borderStyle", style.value)}
                    title={style.label}
                  >
                    <BorderStyleIcon type={style.icon} />
                  </button>
                ))}
              </div>
            </div>

            {!isHoverState && (
              <div className="zenblocks-inspector-band-border__box-sizing" style={{ marginBottom: "16px" }}>
                <label style={{ display: "block", marginBottom: "8px", fontSize: "11px", fontWeight: "500", textTransform: "uppercase" }}>{__("Box Sizing", "zenblocks")}</label>
                <div style={{ display: "flex", gap: "4px" }}>
                  {boxSizingOptions.map((option) => (
                    <Button
                      key={option.value}
                      variant={borderBoxSizing === option.value ? "primary" : "secondary"}
                      onClick={() => handleBandBorderChange("borderBoxSizing", option.value)}
                      style={{ flex: 1, justifyContent: "center", fontSize: "11px" }}
                    >
                      {option.label}
                    </Button>
                  ))}
                </div>
              </div>
            )}
          </>
        )}
      </>
    );
  };

  const renderRadiusControls = (tabName) => {
    const tabData = bandImageData[tabName] || getDefaultBandImage().pc;
    const borderRadius = tabData.borderRadius !== "" && tabData.borderRadius !== undefined ? tabData.borderRadius : 0;
    const borderRadiusUnit = tabData.borderRadiusUnit || "px";

    return (
      <>
        <UnitControl
          label={__("Border Radius", "zenblocks")}
          value={`${borderRadius}${borderRadiusUnit}`}
          onChange={(value) => {
            const numValue = parseFloat(value);
            const unit = value.replace(/[\d.-]/g, "");
            const changes = {};
            if (!isNaN(numValue)) changes.borderRadius = numValue;
            if (unit) changes.borderRadiusUnit = unit;
            if (Object.keys(changes).length > 0) handleImageChange(changes, undefined, responsiveRadiusEnabled);
          }}
          units={units}
        />
      </>
    );
  };

  const renderPositionControls = (tabName) => {
    const tabData = bandImageData[tabName] || getDefaultBandImage().pc;
    const offsetX = tabData.offsetX !== "" && tabData.offsetX !== undefined ? tabData.offsetX : 0;
    const offsetY = tabData.offsetY !== "" && tabData.offsetY !== undefined ? tabData.offsetY : 0;
    const offsetXUnit = tabData.offsetXUnit || "%";
    const offsetYUnit = tabData.offsetYUnit || "%";
    const originX = tabData.originX || "left";
    const originY = tabData.originY || "top";

    // Icons for position buttons
    const IconLeft = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="4" y1="4" x2="4" y2="20" stroke="currentColor" strokeWidth="2" />
        <rect x="8" y="8" width="12" height="8" fill="currentColor" />
      </svg>
    );
    const IconCenterH = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="12" y1="4" x2="12" y2="20" stroke="currentColor" strokeWidth="2" />
        <rect x="6" y="8" width="12" height="8" fill="currentColor" />
      </svg>
    );
    const IconRight = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="20" y1="4" x2="20" y2="20" stroke="currentColor" strokeWidth="2" />
        <rect x="4" y="8" width="12" height="8" fill="currentColor" />
      </svg>
    );
    const IconTop = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="4" y1="4" x2="20" y2="4" stroke="currentColor" strokeWidth="2" />
        <rect x="8" y="8" width="8" height="12" fill="currentColor" />
      </svg>
    );
    const IconCenterV = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="4" y1="12" x2="20" y2="12" stroke="currentColor" strokeWidth="2" />
        <rect x="8" y="6" width="8" height="12" fill="currentColor" />
      </svg>
    );
    const IconBottom = ({ isActive }) => (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" className={isActive ? "icon-active" : "icon-inactive"}>
        <line x1="4" y1="20" x2="20" y2="20" stroke="currentColor" strokeWidth="2" />
        <rect x="8" y="4" width="8" height="12" fill="currentColor" />
      </svg>
    );

    return (
      <>
        <div className="zenblocks-position-control">
          <div className="zenblocks-position-control__label">{__("X Position", "zenblocks")}</div>
          <div className="zenblocks-position-control__row">
            <div className={`zenblocks-origin-buttons${isHoverState ? " is-disabled" : ""}`} title={isHoverState ? __("Cannot change origin on hover", "zenblocks") : undefined}>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--first ${originX === "left" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originX: "left" }, undefined, responsivePositionEnabled)}
                title={__("Left", "zenblocks")}
                disabled={isHoverState}
              >
                <IconLeft isActive={originX === "left"} />
              </button>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--middle ${originX === "center" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originX: "center" }, undefined, responsivePositionEnabled)}
                title={__("Center", "zenblocks")}
                disabled={isHoverState}
              >
                <IconCenterH isActive={originX === "center"} />
              </button>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--last ${originX === "right" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originX: "right" }, undefined, responsivePositionEnabled)}
                title={__("Right", "zenblocks")}
                disabled={isHoverState}
              >
                <IconRight isActive={originX === "right"} />
              </button>
            </div>
            <div className="zenblocks-position-control__input">
              <UnitControl
                value={`${offsetX}${offsetXUnit}`}
                onChange={(value) => {
                  const numValue = parseFloat(value);
                  const unit = value.replace(/[\d.-]/g, "");
                  const changes = {};
                  if (!isNaN(numValue)) changes.offsetX = numValue;
                  if (unit) changes.offsetXUnit = unit;
                  if (Object.keys(changes).length > 0) handleImageChange(changes, undefined, responsivePositionEnabled);
                }}
                units={units}
              />
            </div>
          </div>
        </div>
        <div className="zenblocks-position-control">
          <div className="zenblocks-position-control__label">{__("Y Position", "zenblocks")}</div>
          <div className="zenblocks-position-control__row">
            <div className={`zenblocks-origin-buttons${isHoverState ? " is-disabled" : ""}`} title={isHoverState ? __("Cannot change origin on hover", "zenblocks") : undefined}>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--first ${originY === "top" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originY: "top" }, undefined, responsivePositionEnabled)}
                title={__("Top", "zenblocks")}
                disabled={isHoverState}
              >
                <IconTop isActive={originY === "top"} />
              </button>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--middle ${originY === "center" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originY: "center" }, undefined, responsivePositionEnabled)}
                title={__("Center", "zenblocks")}
                disabled={isHoverState}
              >
                <IconCenterV isActive={originY === "center"} />
              </button>
              <button
                type="button"
                className={`zenblocks-origin-button zenblocks-origin-button--last ${originY === "bottom" ? "is-active" : ""}`}
                onClick={() => !isHoverState && handleImageChange({ originY: "bottom" }, undefined, responsivePositionEnabled)}
                title={__("Bottom", "zenblocks")}
                disabled={isHoverState}
              >
                <IconBottom isActive={originY === "bottom"} />
              </button>
            </div>
            <div className="zenblocks-position-control__input">
              <UnitControl
                value={`${offsetY}${offsetYUnit}`}
                onChange={(value) => {
                  const numValue = parseFloat(value);
                  const unit = value.replace(/[\d.-]/g, "");
                  const changes = {};
                  if (!isNaN(numValue)) changes.offsetY = numValue;
                  if (unit) changes.offsetYUnit = unit;
                  if (Object.keys(changes).length > 0) handleImageChange(changes, undefined, responsivePositionEnabled);
                }}
                units={units}
              />
            </div>
          </div>
        </div>
      </>
    );
  };

  const content = (
    <>
      <PanelBodyWithSync title={__("Overlay", "zenblocks")} opened={panelStates.bandColor} onToggle={() => onTogglePanel && onTogglePanel("bandColor")} onSync={isHoverState ? handleSyncColor : undefined} level={2} panelType="settings" panelName="band-overlay">
        <div className="zenblocks-inspector-band-overlay">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveColorEnabled} onResponsiveToggle={handleResponsiveColorToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveColorAttrName}>
            {(tabName) => renderColorControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <BandPatternSettingV7
        attributes={attributes}
        setAttributes={setAttributes}
        title={__("Pattern", "zenblocks")}
        opened={panelStates.bandPattern}
        onToggle={() => onTogglePanel && onTogglePanel("bandPattern")}
        onSync={isHoverState ? handleSyncPattern : undefined}
        isHoverState={isHoverState}
        supportsHover={true}
        isPro={false}
      />
      <PanelBodyWithSync title={__("Image", "zenblocks")} opened={panelStates.bandImage} onToggle={() => onTogglePanel && onTogglePanel("bandImage")} onSync={isHoverState ? handleSyncImage : undefined} level={2} panelType="settings" panelName="band-image">
        <div className="zenblocks-inspector-band-image">
          {!isHoverState && (
            <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={() => handleBandMediaTypeChange("image")}
                  className={`zenblocks-media-type-tabs__button${bandMediaType === "image" ? " is-active" : ""}`}
                  aria-pressed={bandMediaType === "image"}
                >
                  {"Image"}
                </Button>
                <Button
                  variant="secondary"
                  onClick={() => handleBandMediaTypeChange("video")}
                  className={`zenblocks-media-type-tabs__button${bandMediaType === "video" ? " is-active" : ""}`}
                  aria-pressed={bandMediaType === "video"}
                >
                  {__("Video", "zenblocks")}
                </Button>
              </div>
            </div>
          )}
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveEnabled} onResponsiveToggle={handleResponsiveToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveAttrName}>
            {(tabName) => renderImageControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Color", "zenblocks")} opened={panelStates.bandImageBaseColor} onToggle={() => onTogglePanel && onTogglePanel("bandImageBaseColor")} onSync={isHoverState ? handleSyncImageBaseColor : undefined} level={2} panelType="settings" panelName="band-image-base-color">
        <div className="zenblocks-inspector-band-image-base-color">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveImageBaseColorEnabled} onResponsiveToggle={handleResponsiveImageBaseColorToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveImageBaseColorAttrName}>
            {(tabName) => renderImageBaseColorControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Size", "zenblocks")} opened={panelStates.bandSize} onToggle={() => onTogglePanel && onTogglePanel("bandSize")} onSync={isHoverState ? handleSyncImage : undefined} level={2} panelType="settings" panelName="band-size">
        <div className="zenblocks-inspector-band-size">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveSizeEnabled} onResponsiveToggle={handleResponsiveSizeToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveSizeAttrName}>
            {(tabName) => renderSizeControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Border", "zenblocks")} opened={panelStates.bandBorder} onToggle={() => onTogglePanel && onTogglePanel("bandBorder")} onSync={isHoverState ? handleSyncBorder : undefined} level={2} panelType="settings" panelName="band-border">
        <div className="zenblocks-inspector-band-border">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveBorderEnabled} onResponsiveToggle={handleResponsiveBorderToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveBorderAttrName}>
            {(tabName) => renderBorderControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Border Radius", "zenblocks")} opened={panelStates.bandRadius} onToggle={() => onTogglePanel && onTogglePanel("bandRadius")} onSync={isHoverState ? handleSyncImage : undefined} level={2} panelType="settings" panelName="band-radius">
        <div className="zenblocks-inspector-band-radius">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveRadiusEnabled} onResponsiveToggle={handleResponsiveRadiusToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveRadiusAttrName}>
            {(tabName) => renderRadiusControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Position", "zenblocks")} opened={panelStates.bandPosition} onToggle={() => onTogglePanel && onTogglePanel("bandPosition")} onSync={isHoverState ? handleSyncImage : undefined} level={2} panelType="settings" panelName="band-position">
        <div className="zenblocks-inspector-band-position">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsivePositionEnabled} onResponsiveToggle={handleResponsivePositionToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsivePositionAttrName}>
            {(tabName) => renderPositionControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Opacity", "zenblocks")} opened={panelStates.bandOpacity} onToggle={() => onTogglePanel && onTogglePanel("bandOpacity")} onSync={isHoverState ? handleSyncBandOpacity : undefined} level={2} panelType="settings" panelName="band-opacity">
        <div className="zenblocks-inspector-band-opacity">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveBandOpacityEnabled} onResponsiveToggle={handleResponsiveBandOpacityToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveBandOpacityAttrName}>
            {(tabName) => renderBandOpacityControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      <PanelBodyWithSync title={__("Transform", "zenblocks")} opened={panelStates.bandTransform} onToggle={() => onTogglePanel && onTogglePanel("bandTransform")} onSync={isHoverState ? handleSyncBandTransform : undefined} level={2} panelType="settings" panelName="band-transform">
        <div className="zenblocks-inspector-band-transform">
          <ResponsiveControlV2 initialOpen={true} enableResponsiveToggle={true} responsiveEnabled={responsiveBandTransformEnabled} onResponsiveToggle={handleResponsiveBandTransformToggle} attributes={attributes} setAttributes={setAttributes} syncAttributeName={responsiveBandTransformAttrName}>
            {(tabName) => renderBandTransformControls(tabName)}
          </ResponsiveControlV2>
        </div>
      </PanelBodyWithSync>
      {!isHoverState && (
        <BandTransitionSetting
          attributes={attributes}
          setAttributes={setAttributes}
          title={__("Transition", "zenblocks")}
          opened={panelStates.bandTransition}
          onToggle={() => onTogglePanel && onTogglePanel("bandTransition")}
        />
      )}
    </>
  );

  return (
    <PanelBodyWithSync
      title={title}
      initialOpen={initialOpen}
      opened={opened}
      onToggle={onToggle}
      onSync={isHoverState ? onSync : undefined}
      level={level}
      panelType="parent"
      hasSubpanel={true}
      panelName="band"
    >
      {isPro ? <ProFeatureOverlay featureName="バンド設定" learnMorePath="/docs/block/element/buttonbasic/button/band/">{content}</ProFeatureOverlay> : content}
    </PanelBodyWithSync>
  );
};

export const getBandUrl = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "bandImageV2Hover" : "bandImageV2";
  const data = attributes[attrName];
  if (!data) return "";

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

export const getBandFocalPosition = (attributes, device = "pc", isHover = false) => {
  const attrName = isHover ? "bandImageV2Hover" : "bandImageV2";
  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.focalPosition && bpData.focalPosition !== "") {
      return bpData.focalPosition;
    }
  }
  return "50% 50%";
};

export default BandSettingV7;
