import { ButtonEffect } from "../effect-base.js";

/**
 * Standard text rendering effect
 * Renders static text (when no animations are active)
 */
export class StandardTextEffect extends ButtonEffect {
  constructor(textLineNumber = 1) {
    const suffix = textLineNumber === 1 ? "" : "2";
    super({
      id: `text-standard${suffix}`,
      name: `Standard Text ${textLineNumber}`,
      type: textLineNumber === 1 ? "text" : "text2",
      category: textLineNumber === 1 ? "Text Line 1" : "Text Line 2",
      renderOrder: 20, // After animations
      textLineNumber: textLineNumber, // Pass through config so defineControls can access it
    });
    this.textLineNumber = textLineNumber;
  }

  defineControls() {
    // Access from config since this is called before constructor completes
    const textLineNumber =
      this.textLineNumber || this.config?.textLineNumber || 1;
    const suffix = textLineNumber === 1 ? "" : "2";
    return [
      {
        id: `button-text${suffix}`,
        type: "text",
        label: `Text Line ${textLineNumber}`,
        defaultValue: textLineNumber === 1 ? "RITUAL.SH" : "",
      },
      {
        id: `font-size${suffix}`,
        type: "range",
        label: "Font Size",
        min: 6,
        max: 24,
        defaultValue: textLineNumber === 1 ? 14 : 12,
      },
      {
        id: `text${suffix}-x`,
        type: "range",
        label: "Horizontal Position",
        min: 0,
        max: 100,
        defaultValue: 50,
        description: "Percentage from left",
      },
      {
        id: `text${suffix}-y`,
        type: "range",
        label: "Vertical Position",
        min: 0,
        max: 100,
        defaultValue: textLineNumber === 1 ? 35 : 65,
        description: "Percentage from top",
      },
      {
        id: `text${suffix}-color-type`,
        type: "select",
        label: "Color Type",
        defaultValue: "solid",
        options: [
          { value: "solid", label: "Solid Color" },
          { value: "gradient", label: "Gradient" },
        ],
      },
      {
        id: `text${suffix}-color`,
        type: "color",
        label: "Text Color",
        defaultValue: "#ffffff",
        showWhen: `text${suffix}-color-type`,
      },
      {
        id: `text${suffix}-gradient-color1`,
        type: "color",
        label: "Gradient Color 1",
        defaultValue: "#ffffff",
        showWhen: `text${suffix}-color-type`,
      },
      {
        id: `text${suffix}-gradient-color2`,
        type: "color",
        label: "Gradient Color 2",
        defaultValue: "#00ffff",
        showWhen: `text${suffix}-color-type`,
      },
      {
        id: `text${suffix}-gradient-angle`,
        type: "range",
        label: "Gradient Angle",
        min: 0,
        max: 360,
        defaultValue: 0,
        showWhen: `text${suffix}-color-type`,
      },
      {
        id: `text${suffix}-outline`,
        type: "checkbox",
        label: "Outline",
        defaultValue: false,
      },
      {
        id: `outline${suffix}-color`,
        type: "color",
        label: "Outline Color",
        defaultValue: "#000000",
        showWhen: `text${suffix}-outline`,
      },
      {
        id: `font-family${suffix}`,
        type: "select",
        label: "Font",
        defaultValue: "Lato",
        options: [
          { value: "Lato", label: "Lato" },
          { value: "Roboto", label: "Roboto" },
          { value: "Open Sans", label: "Open Sans" },
          { value: "Montserrat", label: "Montserrat" },
          { value: "Oswald", label: "Oswald" },
          { value: "Bebas Neue", label: "Bebas Neue" },
          { value: "Roboto Mono", label: "Roboto Mono" },
          { value: "VT323", label: "VT323" },
          { value: "Press Start 2P", label: "Press Start 2P" },
          { value: "DSEG7-Classic", label: "DSEG7" },
        ],
      },
      {
        id: `font-bold${suffix}`,
        type: "checkbox",
        label: "Bold",
        defaultValue: false,
      },
      {
        id: `font-italic${suffix}`,
        type: "checkbox",
        label: "Italic",
        defaultValue: false,
      },
    ];
  }

  isEnabled(controlValues) {
    const suffix = this.textLineNumber === 1 ? "" : "2";
    const text = controlValues[`button-text${suffix}`];

    // Only render if text exists and no animations are active on this text
    const waveActive = controlValues[`animate-text-wave${suffix}`];
    const rainbowActive = controlValues[`animate-text-rainbow${suffix}`];
    const spinActive = controlValues[`animate-text-spin${suffix}`];
    const tickerActive = controlValues[`animate-text-ticker${suffix}`];

    return text && text.trim() !== "" && !waveActive && !rainbowActive && !spinActive && !tickerActive;
  }

  apply(context, controlValues, animState, renderData) {
    const suffix = this.textLineNumber === 1 ? "" : "2";

    // Check flash visibility - if flash is active and text is invisible, don't render
    const flashActive = controlValues[`animate-text-flash${suffix}`];
    if (flashActive && renderData[`textFlashVisible${suffix}`] === false) {
      return;
    }

    const text = controlValues[`button-text${suffix}`];
    if (!text) return;

    const fontSize = controlValues[`font-size${suffix}`] || 12;
    const fontWeight = controlValues[`font-bold${suffix}`] ? "bold" : "normal";
    const fontStyle = controlValues[`font-italic${suffix}`]
      ? "italic"
      : "normal";
    const fontFamily = controlValues[`font-family${suffix}`] || "Arial";

    const x = (controlValues[`text${suffix}-x`] / 100) * renderData.width;
    const y = (controlValues[`text${suffix}-y`] / 100) * renderData.height;

    // Set font
    context.font = `${fontStyle} ${fontWeight} ${fontSize}px "${fontFamily}"`;
    context.textAlign = "center";
    context.textBaseline = "middle";

    // Get colors
    const colors = this.getTextColors(
      context,
      controlValues,
      text,
      x,
      y,
      fontSize,
    );

    // Draw outline if enabled
    if (controlValues[`text${suffix}-outline`]) {
      context.strokeStyle = colors.strokeStyle;
      context.lineWidth = 2;
      context.strokeText(text, x, y);
    }

    // Draw text
    context.fillStyle = colors.fillStyle;
    context.fillText(text, x, y);
  }

  /**
   * Get text colors (solid or gradient)
   */
  getTextColors(context, controlValues, text, x, y, fontSize) {
    const suffix = this.textLineNumber === 1 ? "" : "2";
    const colorType = controlValues[`text${suffix}-color-type`] || "solid";

    let fillStyle, strokeStyle;

    if (colorType === "solid") {
      fillStyle = controlValues[`text${suffix}-color`] || "#ffffff";
      strokeStyle = controlValues[`outline${suffix}-color`] || "#000000";
    } else {
      // Gradient
      const angle =
        (controlValues[`text${suffix}-gradient-angle`] || 0) * (Math.PI / 180);
      const textWidth = context.measureText(text).width;
      const x1 = x - textWidth / 2 + (Math.cos(angle) * textWidth) / 2;
      const y1 = y - fontSize / 2 + (Math.sin(angle) * fontSize) / 2;
      const x2 = x + textWidth / 2 - (Math.cos(angle) * textWidth) / 2;
      const y2 = y + fontSize / 2 - (Math.sin(angle) * fontSize) / 2;

      const gradient = context.createLinearGradient(x1, y1, x2, y2);
      gradient.addColorStop(
        0,
        controlValues[`text${suffix}-gradient-color1`] || "#ffffff",
      );
      gradient.addColorStop(
        1,
        controlValues[`text${suffix}-gradient-color2`] || "#00ffff",
      );
      fillStyle = gradient;
      strokeStyle = controlValues[`outline${suffix}-color`] || "#000000";
    }

    return { fillStyle, strokeStyle };
  }
}

// Auto-register effect
export function register(generator) {
  generator.registerEffect(new StandardTextEffect(1));
  generator.registerEffect(new StandardTextEffect(2));
}
