/**
 * ボタンパターンのコレクション
 * 各パターンはattributes形式で定義（parse()によるバリデーションエラーを回避）
 * ButtonPatternPreviewがcreateBlock() + serialize()でプレビューを動的生成
 *
 * 順番管理: ファイル名の番号順に import → そのまま表示
 * パターンの追加: presets/preset-XX.js を作成し、ここに import を追加
 */

import preset01 from "./presets/preset-01";
import preset02 from "./presets/preset-02";
import preset03 from "./presets/preset-03";
import preset04 from "./presets/preset-04";
import preset05 from "./presets/preset-05";
import preset06 from "./presets/preset-06";
import preset07 from "./presets/preset-07";
import preset08 from "./presets/preset-08";
import preset09 from "./presets/preset-09";
import preset10 from "./presets/preset-10";
import preset11 from "./presets/preset-11";
import preset12 from "./presets/preset-12";
import preset13 from "./presets/preset-13";
import preset14 from "./presets/preset-14";
import preset15 from "./presets/preset-15";
import preset16 from "./presets/preset-16";
import preset17 from "./presets/preset-17";
import preset18 from "./presets/preset-18";
import preset19 from "./presets/preset-19";
import preset20 from "./presets/preset-20";
import preset21 from "./presets/preset-21";
import preset22 from "./presets/preset-22";
import preset23 from "./presets/preset-23";
import preset24 from "./presets/preset-24";
import preset25 from "./presets/preset-25";
import preset26 from "./presets/preset-26";
import preset27 from "./presets/preset-27";
import preset28 from "./presets/preset-28";
import preset29 from "./presets/preset-29";
import preset30 from "./presets/preset-30";
import preset31 from "./presets/preset-31";
import preset32 from "./presets/preset-32";

const buttonPatterns = [
  preset01,
  preset02,
  preset03,
  preset04,
  preset05,
  preset06,
  preset07,
  preset08,
  preset09,
  preset10,
  preset11,
  preset12,
  preset13,
  preset14,
  preset15,
  preset16,
  preset17,
  preset18,
  preset19,
  preset20,
  preset21,
  preset22,
  preset23,
  preset24,
  preset25,
  preset26,
  preset27,
  preset28,
  preset29,
  preset30,
  preset31,
  preset32,
];

const BREAKPOINTS = ["pc", "md", "tb", "sp"];

const isNonEmptyString = (value) => typeof value === "string" && value.trim() !== "";

const hasVideoMedia = (mediaType, mediaUrl) => mediaType === "video" && isNonEmptyString(mediaUrl);

const hasResponsiveImageUrl = (data) => BREAKPOINTS.some((bp) => isNonEmptyString(data?.[bp]?.url));

const hasLegacyThumbnailUrl = (attributes = {}) =>
  ["thumbnailUrlPC", "thumbnailUrlMD", "thumbnailUrlTB", "thumbnailUrlSP"].some((key) => isNonEmptyString(attributes[key]));

const hasLegacyIconFrame = (attributes = {}) => {
  const numericKeys = [
    "iconFrameSize",
    "iconFrameWidth",
    "iconFrameHeight",
    "iconFrameBorderWidth",
    "iconFrameRadius",
    "iconFrameSizePC",
    "iconFrameSizeMD",
    "iconFrameSizeTB",
    "iconFrameSizeSP",
    "iconFrameWidthPC",
    "iconFrameWidthMD",
    "iconFrameWidthTB",
    "iconFrameWidthSP",
    "iconFrameHeightPC",
    "iconFrameHeightMD",
    "iconFrameHeightTB",
    "iconFrameHeightSP",
    "iconFrameBorderWidthPC",
    "iconFrameBorderWidthMD",
    "iconFrameBorderWidthTB",
    "iconFrameBorderWidthSP",
    "iconFrameRadiusPC",
    "iconFrameRadiusMD",
    "iconFrameRadiusTB",
    "iconFrameRadiusSP",
  ];

  if (numericKeys.some((key) => Number(attributes[key] ?? 0) > 0)) {
    return true;
  }

  const colorKeys = [
    "iconFrameBgColor",
    "iconFrameBgColorPC",
    "iconFrameBgColorMD",
    "iconFrameBgColorTB",
    "iconFrameBgColorSP",
    "iconFrameBorderColor",
    "iconFrameBorderColorPC",
    "iconFrameBorderColorMD",
    "iconFrameBorderColorTB",
    "iconFrameBorderColorSP",
  ];

  return colorKeys.some((key) => isNonEmptyString(attributes[key]) && attributes[key] !== "transparent");
};

const hasV2IconFrame = (attributes = {}) =>
  BREAKPOINTS.some((bp) => {
    const data = attributes.iconFrameV2?.[bp];
    if (!data || typeof data !== "object") return false;

    const sizeActive = Number(data.size ?? 0) > 0;
    const widthActive = Number(data.width ?? 0) > 0;
    const heightActive = Number(data.height ?? 0) > 0;
    const borderActive = Number(data.borderWidth ?? 0) > 0;
    const radiusActive = Number(data.radius ?? 0) > 0;
    const bgColorActive = isNonEmptyString(data.bgColor) && data.bgColor !== "transparent";
    const borderColorActive = isNonEmptyString(data.borderColor) && data.borderColor !== "transparent";

    return sizeActive || widthActive || heightActive || borderActive || radiusActive || bgColorActive || borderColorActive;
  });

const isBandColorVisible = (value) => {
  if (!value || typeof value !== "object") return false;

  const hasGradient = value.useGradient === true && isNonEmptyString(value.gradient);
  const hasColor = isNonEmptyString(value.color) && value.color !== "transparent";

  if (!hasGradient && !hasColor) {
    return false;
  }

  if (value.opacity === "" || value.opacity === null || value.opacity === undefined) {
    return true;
  }

  const opacity = Number(value.opacity);
  return Number.isFinite(opacity) ? opacity > 0 : true;
};

const hasBandPattern = (data) =>
  BREAKPOINTS.some((bp) => {
    const type = data?.[bp]?.type;
    return isNonEmptyString(type) && type !== "none";
  });

const hasThumbnailMedia = (attributes = {}) => {
  if (hasVideoMedia(attributes.thumbnailMediaType, attributes.thumbnailVideoUrl)) {
    return true;
  }

  return hasResponsiveImageUrl(attributes.thumbnailImageV2) || hasLegacyThumbnailUrl(attributes);
};

const isProPresetAttributes = (attributes = {}) => {
  // copy/text modules are available in free version.

  // Pro-only thumbnail module.
  if (hasThumbnailMedia(attributes)) {
    return true;
  }

  // Pro-only band module.
  if (
    hasVideoMedia(attributes.bandMediaType, attributes.bandVideoUrl) ||
    hasResponsiveImageUrl(attributes.bandImageV2) ||
    hasBandPattern(attributes.bandPatternV2) ||
    hasBandPattern(attributes.bandPatternV2Hover) ||
    BREAKPOINTS.some(
      (bp) =>
        isBandColorVisible(attributes.bandColorV2?.[bp]) ||
        isBandColorVisible(attributes.bandColorV2Hover?.[bp]) ||
        isBandColorVisible(attributes.bandImageBaseColorV2?.[bp]) ||
        isBandColorVisible(attributes.bandImageBaseColorV2Hover?.[bp])
    )
  ) {
    return true;
  }

  // Pro-only animations.
  if (
    (isNonEmptyString(attributes.hoverAnimation) && attributes.hoverAnimation !== "none") ||
    (isNonEmptyString(attributes.iconAnimation) && attributes.iconAnimation !== "none") ||
    (isNonEmptyString(attributes.textAnimation) && attributes.textAnimation !== "none") ||
    (isNonEmptyString(attributes.frameAnimation) && attributes.frameAnimation !== "none") ||
    (isNonEmptyString(attributes.buttonAnimation) && attributes.buttonAnimation !== "none")
  ) {
    return true;
  }

  // Pro-only video background.
  if (hasVideoMedia(attributes.backgroundMediaType, attributes.backgroundVideoUrl)) {
    return true;
  }

  // Pro-only icon frame.
  // Use the same "safe keys" logic as detectProFeatures() in edit.js to avoid
  // false positives from styling-only values (e.g. radius/bgColor set as template
  // values while iconFrameSize is 0, meaning the frame is not actually visible).
  // Keys with non-zero block.json defaults (iconFrameWidthPC, iconFrameHeightPC,
  // iconFrameRadiusPC, iconFrameBorderWidthPC, etc.) are excluded.
  if (hasV2IconFrame(attributes) || (() => {
    const safeNumericKeys = [
      "iconFrameSize", "iconFrameWidth", "iconFrameHeight", "iconFrameBorderWidth", "iconFrameRadius",
      "iconFrameSizePC", "iconFrameSizeMD", "iconFrameSizeTB", "iconFrameSizeSP",
      "iconFrameWidthMD", "iconFrameHeightMD", "iconFrameBorderWidthMD", "iconFrameRadiusMD",
    ];
    if (safeNumericKeys.some((key) => Number(attributes[key] ?? 0) > 0)) return true;
    const colorKeys = [
      "iconFrameBgColor", "iconFrameBgColorPC", "iconFrameBgColorMD", "iconFrameBgColorTB", "iconFrameBgColorSP",
      "iconFrameBorderColor", "iconFrameBorderColorPC", "iconFrameBorderColorMD", "iconFrameBorderColorTB", "iconFrameBorderColorSP",
    ];
    return colorKeys.some((key) => isNonEmptyString(attributes[key]) && attributes[key] !== "transparent");
  })()) {
    return true;
  }

  return false;
};

const patternsWithMeta = buttonPatterns.map((preset, index) => ({
  ...preset,
  id: `preset-${String(index + 1).padStart(2, "0")}`,
  isPro: isProPresetAttributes(preset.attributes || {}),
}));

const resolvePluginUrls = (obj) => {
  const pluginUrl = window.zenBlocks?.pluginUrl || "";
  const json = JSON.stringify(obj);
  return JSON.parse(json.replace(/\{\{PLUGIN_URL\}\}/g, pluginUrl));
};

export { isProPresetAttributes, hasThumbnailMedia, hasVideoMedia, hasResponsiveImageUrl, hasBandPattern, isBandColorVisible, hasV2IconFrame, hasLegacyIconFrame, isNonEmptyString, BREAKPOINTS };

export function getProcessedPatterns() {
  return resolvePluginUrls([...patternsWithMeta]);
}
