/**
 * SVGIconSetting Utilities
 *
 * アイコンデータとユーティリティ関数を管理
 */

import featherIconsData from "../icons/feather.json";
import fontAwesomeOutlineData from "../icons/fontawesome-outline.json";
import fontAwesomeSolidData from "../icons/fontawesome-solid.json";
import fontAwesomeBrandsData from "../icons/fontawesome-brands.json";
import tablerOutlineData from "../icons/tabler-outline.json";
import tablerSolidData from "../icons/tabler-solid.json";
import heroiconsOutlineData from "../icons/heroicons-outline.json";
import heroiconsSolidData from "../icons/heroicons-solid.json";
import remixiconOutlineData from "../icons/remixicon-outline.json";
import remixiconSolidData from "../icons/remixicon-solid.json";
import lucideData from "../icons/lucide.json";

export const iconLicenses = {
  feather: {
    name: "Feather Icons",
    license: "MIT License",
    url: "https://feathericons.com/",
    attribution: "Created by Cole Bemis",
  },
  fontawesome: {
    name: "Font Awesome Free",
    license: "Icons: CC BY 4.0 License",
    url: "https://fontawesome.com/license/free",
    attribution: "Copyright 2024 Fonticons, Inc. (https://fontawesome.com)",
  },
  tabler: {
    name: "Tabler Icons",
    license: "MIT License",
    url: "https://tabler-icons.io/",
    attribution: "Created by Paweł Kuna & Tabler Team",
  },
  heroicons: {
    name: "Heroicons",
    license: "MIT License",
    url: "https://heroicons.com/",
    attribution: "Created by Tailwind Labs",
  },
  lucide: {
    name: "Lucide Icons",
    license: "ISC License",
    url: "https://lucide.dev/",
    attribution: "Cole Bemis 2013-2022 (Feather), Lucide Contributors 2022",
  },
  remixicon: {
    name: "RemixIcon",
    license: "Apache License 2.0",
    url: "https://remixicon.com/",
    attribution: "Copyright 2023 RemixIcon. Commercial and non-commercial use with attribution. Re-selling prohibited.",
  },
};

export { featherIconsData, fontAwesomeOutlineData, fontAwesomeSolidData, fontAwesomeBrandsData, tablerOutlineData, tablerSolidData, heroiconsOutlineData, heroiconsSolidData, remixiconOutlineData, remixiconSolidData, lucideData };

/**
 * アイコンが属するカテゴリーを特定する関数
 * @param {string} iconValue - アイコンの値
 * @returns {string} カテゴリー名
 */
export const getIconCategory = (iconValue) => {
  if (!iconValue) return "none";
  if (iconValue.startsWith("feather-")) return "feather";
  if (iconValue.startsWith("fa-")) return "fontawesome";
  if (iconValue.startsWith("tabler-")) return "tabler";
  if (iconValue.startsWith("heroicons-")) return "heroicons";
  if (iconValue.startsWith("remixicon-")) return "remixicon";
  if (iconValue.startsWith("lucide-")) return "lucide";
  if (iconValue.startsWith("custom-svg-")) return "custom";
  return "none";
};

/**
 * SVGのviewBoxをパスの境界に合わせて自動調整する関数
 * @param {string} svgString - SVG文字列
 * @returns {string} 調整されたSVG文字列
 */
export const adjustViewBoxToPath = (svgString) => {
  if (typeof DOMParser === "undefined" || typeof XMLSerializer === "undefined") {
    return svgString;
  }

  try {
    const parser = new DOMParser();
    const svgDoc = parser.parseFromString(svgString, "image/svg+xml");

    const parserError = svgDoc.querySelector("parsererror");
    if (parserError) {
      return svgString;
    }

    const svg = svgDoc.querySelector("svg");
    if (!svg) {
      return svgString;
    }

    const graphicsElements = svgDoc.querySelectorAll("path, circle, rect, ellipse, line, polyline, polygon");

    if (graphicsElements.length === 0) {
      return svgString;
    }

    let tempContainer;
    let addedToDOM = false;

    try {
      if (!svg.closest("body")) {
        tempContainer = document.createElement("div");
        tempContainer.style.position = "absolute";
        tempContainer.style.visibility = "hidden";
        tempContainer.style.top = "-9999px";
        tempContainer.appendChild(svg.cloneNode(true));
        document.body.appendChild(tempContainer);
        addedToDOM = true;
      }

      let minX = Infinity,
        minY = Infinity,
        maxX = -Infinity,
        maxY = -Infinity;

      let validBoundingBoxFound = false;

      graphicsElements.forEach((element) => {
        try {
          const targetElement = addedToDOM ? tempContainer.querySelector(element.tagName.toLowerCase()) : element;

          if (targetElement && typeof targetElement.getBBox === "function") {
            const bbox = targetElement.getBBox();

            if (bbox && isFinite(bbox.x) && isFinite(bbox.y) && isFinite(bbox.width) && isFinite(bbox.height) && bbox.width > 0 && bbox.height > 0) {
              minX = Math.min(minX, bbox.x);
              minY = Math.min(minY, bbox.y);
              maxX = Math.max(maxX, bbox.x + bbox.width);
              maxY = Math.max(maxY, bbox.y + bbox.height);
              validBoundingBoxFound = true;
            }
          }
        } catch (e) {
          // getBBox failed for element
        }
      });

      if (addedToDOM && tempContainer && tempContainer.parentNode) {
        tempContainer.parentNode.removeChild(tempContainer);
      }

      if (validBoundingBoxFound && minX !== Infinity && minY !== Infinity && maxX !== -Infinity && maxY !== -Infinity) {
        const width = maxX - minX;
        const height = maxY - minY;

        const minSize = 1;
        const actualWidth = Math.max(width, minSize);
        const actualHeight = Math.max(height, minSize);

        const padding = Math.max(Math.max(actualWidth, actualHeight) * 0.05, 1);
        const adjustedMinX = minX - padding;
        const adjustedMinY = minY - padding;
        const adjustedWidth = actualWidth + padding * 2;
        const adjustedHeight = actualHeight + padding * 2;

        svg.setAttribute("viewBox", `${adjustedMinX} ${adjustedMinY} ${adjustedWidth} ${adjustedHeight}`);

        const serializer = new XMLSerializer();
        return serializer.serializeToString(svgDoc);
      } else {
        return svgString;
      }
    } catch (innerError) {
      if (addedToDOM && tempContainer && tempContainer.parentNode) {
        tempContainer.parentNode.removeChild(tempContainer);
      }
      throw innerError;
    }
  } catch (e) {
    return svgString;
  }
};
