<template>
  <svg
    v-if="iconData"
    :class="svgClass"
    :fill="fill"
    :stroke="stroke"
    :viewBox="viewBox"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path v-for="(path, index) in iconData.paths" :key="index" v-bind="path" />
  </svg>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-facing-decorator";
import icons from "../assets/icons.json";
import { logger } from "../utils/logger";

/**
 * Icon path interface
 */
interface IconPath {
  d: string;
  fillRule?: string;
  clipRule?: string;
  strokeLinecap?: string;
  strokeLinejoin?: string;
  strokeWidth?: string | number;
  fill?: string;
  stroke?: string;
}

/**
 * Icon data interface
 */
interface IconData {
  paths: IconPath[];
}

/**
 * Icons JSON structure
 */
interface IconsJson {
  [key: string]: IconPath | IconData;
}

/**
 * Icon Renderer Component
 *
 * This component loads SVG icon definitions from a JSON file and renders them
 * as SVG elements. It provides a clean way to use icons without cluttering
 * templates with long SVG path definitions.
 *
 * @author Matthew Raymer
 * @version 1.0.0
 * @since 2024
 */
@Component({
  name: "IconRenderer",
})
export default class IconRenderer extends Vue {
  @Prop({ required: true }) readonly iconName!: string;
  @Prop({ default: "h-5 w-5" }) readonly svgClass!: string;
  @Prop({ default: "none" }) readonly fill!: string;
  @Prop({ default: "currentColor" }) readonly stroke!: string;
  @Prop({ default: "0 0 24 24" }) readonly viewBox!: string;

  /**
   * Get the icon data for the specified icon name
   *
   * @returns {IconData | null} The icon data object or null if not found
   */
  get iconData(): IconData | null {
    const icon = (icons as IconsJson)[this.iconName];
    if (!icon) {
      logger.warn(`Icon "${this.iconName}" not found in icons.json`);
      return null;
    }

    // Convert single path to array format for consistency
    if ("d" in icon) {
      return {
        paths: [icon as IconPath],
      };
    }

    return icon as IconData;
  }
}
</script>
