// Manual panel editor for admins/power users

import { Alpine } from "../../alpine";
import { apiPut } from "../../api";
import { Panel } from "./panel-detector";
import { detectPanels } from "./panel-detection.service";

async function loadImageForPage(pageNumber: number): Promise<HTMLImageElement> {
  const mediaItemId = document.body.dataset.mediaItemId;
  if (!mediaItemId) {
    throw new Error("No mediaItemId found");
  }

  const token = localStorage.getItem("token");
  const response = await fetch(`/readers/${mediaItemId}/pages/${pageNumber}`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  if (!response.ok) {
    throw new Error(`Failed to load page ${pageNumber}`);
  }

  const blob = await response.blob();
  const img = new Image();
  img.src = URL.createObjectURL(blob);

  await new Promise<void>((resolve) => {
    img.onload = () => resolve();
  });

  return img;
}

function getCurrentPageNumber(): number {
  // Try Alpine first
  const Alpine = (window as any).Alpine;
  if (Alpine) {
    const readerEl = document.querySelector('[x-data="readerShell"]');
    if (readerEl) {
      const readerShell = Alpine.$data(readerEl);
      if (readerShell?.currentPage) {
        return readerShell.currentPage;
      }
    }
  }

  // Fallback: check for dataset attribute on reader content
  const content = document.getElementById("reader-content");
  const pageFromDataset = content?.dataset.currentPage;
  if (pageFromDataset) {
    return parseInt(pageFromDataset, 10);
  }

  // Final fallback
  return 1;
}
function loadPage(pageNumber: number): void {
  // Dispatch event for reader to handle navigation
  window.dispatchEvent(
    new CustomEvent("navigate-to-page", { detail: { page: pageNumber } }),
  );
}

function openPanelEditor(pageNumber: number): void {
  const modal = document.getElementById("panel-editor-modal");
  modal?.classList.remove("hidden");

  // Load page image
  const canvas = document.getElementById(
    "panel-editor-canvas",
  ) as HTMLCanvasElement;
  const ctx = canvas?.getContext("2d");

  // Load image and draw to canvas
  loadImageForPage(pageNumber).then((image) => {
    canvas!.width = image.width;
    canvas!.height = image.height;
    ctx?.drawImage(image, 0, 0);

    // Allow user to draw panels
    enablePanelDrawing(canvas!);
  });
}

function enablePanelDrawing(canvas: HTMLCanvasElement): void {
  let isDrawing = false;
  let startX = 0;
  let startY = 0;

  canvas.addEventListener("mousedown", (e) => {
    isDrawing = true;
    startX = e.offsetX;
    startY = e.offsetY;
  });

  canvas.addEventListener("mousemove", (e) => {
    if (!isDrawing) return;

    // Draw selection rectangle
    const ctx = canvas.getContext("2d");
    ctx?.strokeRect(startX, startY, e.offsetX - startX, e.offsetY - startY);
  });

  canvas.addEventListener("mouseup", (e) => {
    if (!isDrawing) return;
    isDrawing = false;

    // Save panel
    const panel: Panel = {
      id: `manual-${Date.now()}`,
      x: (startX / canvas.width) * 100,
      y: (startY / canvas.height) * 100,
      width: ((e.offsetX - startX) / canvas.width) * 100,
      height: ((e.offsetY - startY) / canvas.height) * 100,
      reading_order: 0, // Will be set by server
    };

    saveManualPanel(panel);
  });
}

async function saveManualPanel(panel: Panel): Promise<void> {
  const mediaItemId = document.body.dataset.mediaItemId;
  const pageNumber = getCurrentPageNumber();

  await apiPut(`/readers/${mediaItemId}/panels/${pageNumber}`, {
    detection_method: "manual",
    panels: [panel],
  });

  // Reload with new panels
  loadPage(pageNumber);
}

// Re-detect panels using detection service
async function reDetectPanels(pageNumber: number): Promise<Panel[]> {
  const image = await loadImageForPage(pageNumber);

  const canvas = document.createElement("canvas");
  canvas.width = image.width;
  canvas.height = image.height;
  const ctx = canvas.getContext("2d")!;
  ctx.drawImage(image, 0, 0);

  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const result = await detectPanels(imageData, true);

  return result.panels;
}

// Alpine component
Alpine.data("panelEditor", () => ({
  get isComicOrManga(): boolean {
    const libraryType = document.body.dataset.mediaType;
    return libraryType === "comic" || libraryType === "manga";
  },

  openPanelEditor(pageNumber: number) {
    openPanelEditor(pageNumber);
  },

  async reDetectPanels(pageNumber: number) {
    const panels = await reDetectPanels(pageNumber);
    return panels;
  },
}));

export { openPanelEditor, reDetectPanels };
