/**
 * Button Generator - Main Application File
 *
 * This demonstrates how to use the modular button generator system.
 * Effects are imported and registered with the generator.
 */

import { ButtonGenerator } from "./button-generator-core.js";
import { UIBuilder } from "./ui-builder.js";

// Import effects (each effect file exports a register() function)
import * as solidBg from "./effects/background-solid.js";
import * as gradientBg from "./effects/background-gradient.js";
import * as textureBg from "./effects/background-texture.js";
import * as emojiWallpaper from "./effects/background-emoji-wallpaper.js";
import * as externalImage from "./effects/background-external-image.js";
import * as rainbowBg from "./effects/background-rainbow.js";
import * as rain from "./effects/background-rain.js";
import * as starfield from "./effects/background-starfield.js";
//import * as bubbles from "./effects/background-bubbles.js";
import * as aurora from "./effects/background-aurora.js";
import * as fire from "./effects/background-fire.js";
import * as border from "./effects/border.js";
import * as standardText from "./effects/text-standard.js";
import * as textShadow from "./effects/text-shadow.js";
import * as waveText from "./effects/wave-text.js";
import * as rainbowText from "./effects/rainbow-text.js";
import * as flashText from "./effects/flash-text.js";
import * as spinText from "./effects/spin-text.js";
import * as tickerText from "./effects/ticker-text.js";
import * as glitch from "./effects/glitch.js";
import * as pulse from "./effects/pulse.js";
import * as shimmer from "./effects/shimmer.js";
import * as scanline from "./effects/scanline.js";
import * as rgbSplit from "./effects/rgb-split.js";
import * as noise from "./effects/noise.js";
import * as rotate from "./effects/rotate.js";
import * as hologram from "./effects/hologram.js";
import * as spotlight from "./effects/spotlight.js";

/**
 * Initialize the button generator application
 */
export function init() {
  // Wait for DOM to be ready
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", setupApp);
  } else {
    setupApp();
  }
}

/**
 * Setup the application
 */
async function setupApp() {
  console.log("Initializing Button Generator...");

  // Setup collapsible sections
  setupCollapsible();

  // Get canvas
  const canvas = document.getElementById("button-canvas");
  if (!canvas) {
    console.error("Canvas element not found!");
    return;
  }

  // Create button generator
  const generator = new ButtonGenerator(canvas, {
    fps: 20,
    duration: 2,
    fonts: [
      "Arial",
      "Lato",
      "Roboto",
      "Open Sans",
      "Montserrat",
      "Oswald",
      "Bebas Neue",
      "Roboto Mono",
      "VT323",
      "Press Start 2P",
      "DSEG7-Classic",
    ],
  });

  // Register all effects
  console.log("Registering effects...");
  solidBg.register(generator);
  gradientBg.register(generator);
  textureBg.register(generator);
  emojiWallpaper.register(generator);
  externalImage.register(generator);
  rainbowBg.register(generator);
  rain.register(generator);
  starfield.register(generator);
  //bubbles.register(generator);
  aurora.register(generator);
  fire.register(generator);
  border.register(generator);
  standardText.register(generator);
  textShadow.register(generator);
  waveText.register(generator);
  rainbowText.register(generator);
  flashText.register(generator);
  spinText.register(generator);
  tickerText.register(generator);
  glitch.register(generator);
  pulse.register(generator);
  shimmer.register(generator);
  scanline.register(generator);
  rgbSplit.register(generator);
  noise.register(generator);
  rotate.register(generator);
  hologram.register(generator);
  spotlight.register(generator);

  console.log(`Registered ${generator.getAllEffects().length} effects`);

  // Build UI from effects
  console.log("Building UI...");
  const controlsContainer = document.querySelector(".controls-section");
  if (!controlsContainer) {
    console.error("Controls container not found!");
    return;
  }

  const uiBuilder = new UIBuilder(controlsContainer);
  uiBuilder.buildUI(generator.getAllEffects());
  uiBuilder.setupConditionalVisibility();

  // Add GIF export settings at the bottom
  addGifExportSettings(controlsContainer, generator);

  // Preload fonts
  console.log("Loading fonts...");
  await generator.preloadFonts();

  // Bind controls (after UI is built)
  generator.bindControls();

  // Setup additional UI handlers
  setupUIHandlers(generator);

  // Setup download button
  setupDownloadButton(generator);

  // Setup presets
  setupPresets(generator);

  // Initial draw
  generator.updatePreview();

  console.log("Button Generator ready!");
}

/**
 * Add GIF export settings controls
 */
function addGifExportSettings(container, generator) {
  const groupDiv = document.createElement('div');
  groupDiv.className = 'control-group collapsed';

  // Header
  const header = document.createElement('h3');
  header.className = 'control-group-header';
  header.textContent = 'Advanced Settings';
  groupDiv.appendChild(header);

  const controlsDiv = document.createElement('div');
  controlsDiv.className = 'control-group-controls';

  // Color count control
  const colorsWrapper = document.createElement('div');
  colorsWrapper.className = 'control-wrapper';
  colorsWrapper.innerHTML = `
    <div class="info-text">Note: This only affects frame-by-frame settings, i.e. 8 colours would be 8 colours per frame. I am working on a solution for this.</div>
    <label for="gif-colors">
      Color Count
      <span class="control-description">(16-32 for the 90s experience)</span>
    </label>
    <div class="range-container">
      <input type="range" id="gif-colors" min="2" max="256" step="1" value="256">
      <span id="gif-colors-value" class="range-value">256</span>
    </div>
  `;
  controlsDiv.appendChild(colorsWrapper);

  // Quality control
  const qualityWrapper = document.createElement('div');
  qualityWrapper.className = 'control-wrapper';
  qualityWrapper.innerHTML = `
    <label for="gif-quality">
      Quantization Quality
      <span class="control-description">(lower = better but slower export)</span>
    </label>
    <div class="range-container">
      <input type="range" id="gif-quality" min="1" max="30" step="1" value="1">
      <span id="gif-quality-value" class="range-value">1</span>
    </div>
  `;
  controlsDiv.appendChild(qualityWrapper);

  // Dither control
  const ditherWrapper = document.createElement('div');
  ditherWrapper.className = 'control-wrapper';
  ditherWrapper.innerHTML = `
    <label for="gif-dither">
      Dithering Pattern
      <span class="control-description"></span>
    </label>
    <select id="gif-dither">
      <option value="false">None (Smooth)</option>
      <option value="FloydSteinberg">Floyd-Steinberg (Classic)</option>
      <option value="FalseFloydSteinberg">False Floyd-Steinberg (Fast)</option>
      <option value="Stucki">Stucki (Distributed)</option>
      <option value="Atkinson">Atkinson (Retro Mac)</option>
    </select>
  `;
  controlsDiv.appendChild(ditherWrapper);

  groupDiv.appendChild(controlsDiv);
  container.appendChild(groupDiv);

  // Setup event listeners for value display
  const colorsInput = document.getElementById('gif-colors');
  const colorsValue = document.getElementById('gif-colors-value');
  colorsInput.addEventListener('input', () => {
    colorsValue.textContent = colorsInput.value;
  });

  const qualityInput = document.getElementById('gif-quality');
  const qualityValue = document.getElementById('gif-quality-value');
  qualityInput.addEventListener('input', () => {
    qualityValue.textContent = qualityInput.value;
  });

  // Update generator config when changed
  colorsInput.addEventListener('change', () => {
    generator.gifConfig.colorCount = parseInt(colorsInput.value);
    generator.updatePreview(); // Update preview to show color quantization
  });

  // Also update preview on slider input for real-time feedback
  colorsInput.addEventListener('input', () => {
    generator.gifConfig.colorCount = parseInt(colorsInput.value);
    generator.updatePreview(); // Real-time preview update
  });

  qualityInput.addEventListener('change', () => {
    generator.gifConfig.quality = parseInt(qualityInput.value);
  });

  const ditherSelect = document.getElementById('gif-dither');
  ditherSelect.addEventListener('change', () => {
    const value = ditherSelect.value;
    generator.gifConfig.dither = value === 'false' ? false : value;
  });
}

/**
 * Setup collapsible section functionality
 */
function setupCollapsible() {
  const headers = document.querySelectorAll(".control-group-header");
  console.log("Found", headers.length, "collapsible headers");

  headers.forEach((header) => {
    header.addEventListener("click", () => {
      const controlGroup = header.closest(".control-group");
      if (controlGroup) {
        controlGroup.classList.toggle("collapsed");
      }
    });
  });
}

/**
 * Setup UI handlers for conditional visibility
 */
function setupUIHandlers(generator) {
  // Note: Conditional visibility is now handled automatically by UIBuilder.setupConditionalVisibility()
  // This function is kept for any additional custom handlers if needed in the future
}

/**
 * Setup download button
 */
function setupDownloadButton(generator) {
  const downloadBtn = document.getElementById("download-button");
  if (!downloadBtn) return;

  downloadBtn.addEventListener("click", async () => {
    const originalText = downloadBtn.textContent;
    downloadBtn.disabled = true;
    downloadBtn.textContent = "Generating GIF...";

    try {
      const blob = await generator.exportAsGif((progress, stage) => {
        if (stage === "generating") {
          const percent = Math.round(progress * 100);
          downloadBtn.textContent = `Generating: ${percent}%`;
        } else if (stage === "encoding") {
          const percent = Math.round(progress * 100);
          downloadBtn.textContent = `Encoding: ${percent}%`;
        }
      });

      // Download the blob
      const link = document.createElement("a");
      link.download = "button-88x31.gif";
      link.href = URL.createObjectURL(blob);
      link.click();
      URL.revokeObjectURL(link.href);

      downloadBtn.textContent = originalText;
    } catch (error) {
      console.error("Error generating GIF:", error);
      alert("Error generating GIF. Please try again.");
      downloadBtn.textContent = originalText;
    } finally {
      downloadBtn.disabled = false;
    }
  });
}

/**
 * Setup preset buttons
 */
function setupPresets(generator) {
  // Random preset
  const randomBtn = document.getElementById("preset-random");
  if (randomBtn) {
    randomBtn.addEventListener("click", () => {
      applyRandomPreset();
      generator.updatePreview();
    });
  }

  // Classic preset
  const classicBtn = document.getElementById("preset-classic");
  if (classicBtn) {
    classicBtn.addEventListener("click", () => {
      applyClassicPreset();
      generator.updatePreview();
    });
  }

  // Modern preset
  const modernBtn = document.getElementById("preset-modern");
  if (modernBtn) {
    modernBtn.addEventListener("click", () => {
      applyModernPreset();
      generator.updatePreview();
    });
  }
}

/**
 * Apply random preset
 */
function applyRandomPreset() {
  const randomColor = () =>
    "#" +
    Math.floor(Math.random() * 16777215)
      .toString(16)
      .padStart(6, "0");

  // Random background
  const bgTypeEl = document.getElementById("bg-type");
  if (bgTypeEl) {
    bgTypeEl.value = ["solid", "gradient", "texture"][
      Math.floor(Math.random() * 3)
    ];
    bgTypeEl.dispatchEvent(new Event("change"));
  }

  setControlValue("bg-color", randomColor());
  setControlValue("gradient-color1", randomColor());
  setControlValue("gradient-color2", randomColor());
  setControlValue("gradient-angle", Math.floor(Math.random() * 360));

  // Random text colors
  setControlValue("text-color", randomColor());
  setControlValue("text-gradient-color1", randomColor());
  setControlValue("text-gradient-color2", randomColor());
  setControlValue("text2-color", randomColor());
  setControlValue("text2-gradient-color1", randomColor());
  setControlValue("text2-gradient-color2", randomColor());

  // Random border
  setControlValue("border-color", randomColor());
  setControlValue("border-width", Math.floor(Math.random() * 6));
}

/**
 * Apply classic 90s preset
 */
function applyClassicPreset() {
  setControlValue("bg-type", "gradient");
  setControlValue("gradient-color1", "#6e6e6eff");
  setControlValue("gradient-color2", "#979797");
  setControlValue("gradient-angle", 90);

  setControlValue("text-color-type", "solid");
  setControlValue("text-color", "#000000");
  setControlValue("text2-color-type", "solid");
  setControlValue("text2-color", "#000000");

  setControlValue("border-width", 2);
  setControlValue("border-color", "#000000");
  setControlValue("border-style", "outset");

  setControlValue("font-family", "VT323");
  setControlValue("font-family2", "VT323");

  document.getElementById("bg-type")?.dispatchEvent(new Event("change"));
}

/**
 * Apply modern preset
 */
function applyModernPreset() {
  setControlValue("bg-type", "gradient");
  setControlValue("gradient-color1", "#0a0a0a");
  setControlValue("gradient-color2", "#1a0a2e");
  setControlValue("gradient-angle", 135);

  setControlValue("text-color-type", "gradient");
  setControlValue("text-gradient-color1", "#00ffaa");
  setControlValue("text-gradient-color2", "#00ffff");
  setControlValue("text-gradient-angle", 90);

  setControlValue("text2-color-type", "gradient");
  setControlValue("text2-gradient-color1", "#ff00ff");
  setControlValue("text2-gradient-color2", "#ff6600");

  setControlValue("border-width", 1);
  setControlValue("border-color", "#00ffaa");
  setControlValue("border-style", "solid");

  setControlValue("font-family", "Roboto Mono");
  setControlValue("font-family2", "Roboto Mono");

  document.getElementById("bg-type")?.dispatchEvent(new Event("change"));
  document
    .getElementById("text-color-type")
    ?.dispatchEvent(new Event("change"));
  document
    .getElementById("text2-color-type")
    ?.dispatchEvent(new Event("change"));
}

/**
 * Helper to set control value
 */
function setControlValue(id, value) {
  const el = document.getElementById(id);
  if (el) {
    if (el.type === "checkbox") {
      el.checked = value;
    } else {
      el.value = value;
    }

    // Update value display if it exists
    const valueDisplay = document.getElementById(id + "-value");
    if (valueDisplay) {
      valueDisplay.textContent = value;
    }
  }
}

// Auto-initialize when imported
init();
