import { BrowserWindow, ipcMain } from "electron";
import fs from 'fs';
import path from 'path';
import { tempDir } from "../utils/constants";


interface Position {
  left: number;
  top: number;
  width: number;
  height: number;
}

interface FontStyles {
  name: string;
  size: number;
  bold: boolean;
  weight: number;
  color: string;
}

interface TextElement {
  position: Position;
  paragraphs: {
    alignment: number;
    text: string;
    font: FontStyles;
  }[];
}

interface PictureElement {
  position: Position;
  picture: {
    is_network: boolean;
    path: string;
  };
  shape: string | null;
  object_fit: {
    fit: string | null;
    focus: number[];
  };
  overlay: string | null;
  border_radius: number[];
}

interface BoxElement {
  position: Position;
  type: number;
  fill: {
    color: string;
  };
  border_radius: number;
  stroke: {
    color: string;
    thickness: number;
  };
  shadow: {
    radius: number;
    color: string;
    offset: number;
    opacity: number;
    angle: number;
  };
}

interface LineElement {
  position: Position;
  lineType: number;
  thickness: string;
  color: string;
}

interface GraphElement {
  position: Position;
  picture: {
    is_network: boolean;
    path: string;
  };
  border_radius: number[];
}

type SlideElement = TextElement | PictureElement | BoxElement | LineElement | GraphElement;




export function setupSlideMetadataHandlers() {
  ipcMain.handle("get-slide-metadata", async (_, url: string, theme: string, customColors?: any) => {
    let win: BrowserWindow | null = null;

    try {
      win = new BrowserWindow({
        width: 1920,
        height: 1080,
        webPreferences: {
          webSecurity: false,
          preload: path.join(__dirname, '../preloads/index.js'),
        },
        show: false,
      });

      await win.loadURL(url, { userAgent: 'electron' });


      await win.webContents.executeJavaScript(`
        new Promise((resolve) => {
          const check = () => {
            const el = document.querySelector('[data-element-type="slide-container"]');
            if (el) return resolve(true);
            setTimeout(check, 200);
          };
          check();
        });
      `);
      const metadata = await win.webContents.executeJavaScript(
        `
 (() => {
          const rgbToHex = (color) => {
            if (!color || color === "transparent" || color === "none") return "000000";
            if (color.startsWith("#")) return color.replace("#", "");
            const matches = color.match(/\\d+/g);
            if (!matches) return "000000";
            const [r, g, b] = matches.map(x => parseInt(x));
            return [r, g, b].map(x => x.toString(16).padStart(2, "0")).join("");
          };

          const slidesMetadata = [];
          const slideContainers = document.querySelectorAll('[data-element-type="slide-container"]');

          slideContainers.forEach((container) => {
            const containerEl = container;
            containerEl.style.width = "1280px";
            containerEl.style.height = "720px";
            containerEl.style.transform = "none";

            const containerRect = containerEl.getBoundingClientRect();
            const slideIndex = parseInt(containerEl.getAttribute("data-slide-index") || "0");
            const backgroundColor = rgbToHex(window.getComputedStyle(containerEl).backgroundColor);

            const elements = [];
            const slideElements = containerEl.querySelectorAll('[data-slide-element]:not([data-element-type="slide-container"])');

            slideElements.forEach((element) => {
              const el = element;
              const elementRect = el.getBoundingClientRect();
              const computedStyle = window.getComputedStyle(el);

              const position = {
                left: Math.round(elementRect.left - containerRect.left),
                top: Math.round(elementRect.top - containerRect.top),
                width: Math.round(elementRect.width),
                height: Math.round(elementRect.height),
              };

              const elementType = el.getAttribute("data-element-type");
              if (!elementType) return;

              switch (elementType) {
                case "text":
                  elements.push({
                    position,
                    paragraphs: [{
                      alignment: el.getAttribute("data-is-align") === 'true' ? 2 : 1,
                      text: el.getAttribute("data-text-content") || el.textContent || "",
                      font: {
                        name: computedStyle.fontFamily.split('_')[2] || 'Inter',
                        size: parseInt(computedStyle.fontSize),
                        bold: parseInt(computedStyle.fontWeight) >= 500,
                        weight: parseInt(computedStyle.fontWeight),
                        color: rgbToHex(computedStyle.color),
                      },
                    }],
                  });
                  break;

                case "picture":
                  const imgEl = el.tagName.toLowerCase() === "img" ? el : el.querySelector("img");
                  if (imgEl) {
                    elements.push({
                      position,
                      picture: {
                        is_network: imgEl.src.startsWith("http"),
                        path: imgEl.src || imgEl.getAttribute("data-image-path") || "",
                      },
                      shape: imgEl.getAttribute('data-image-type'),
                      object_fit: {
                        fit: imgEl.getAttribute('data-object-fit'),
                        focus: [
                          parseFloat(imgEl.getAttribute('data-focial-point-x') || '0'),
                          parseFloat(imgEl.getAttribute('data-focial-point-y') || '0'),
                        ],
                      },
                      overlay: el.getAttribute("data-is-icon") ? "ffffff" : null,
                      border_radius: Array(4).fill(parseInt(computedStyle.borderRadius) || 0),
                    });
                  }
                  break;

                case "graph":
                  elements.push({
                    position,
                    picture: {
                      is_network: true,
                      path: \`__GRAPH_PLACEHOLDER__\${el.getAttribute("data-element-id")}\`,
                    },
                    border_radius: [0, 0, 0, 0],
                  });
                  break;

                case "slide-box":
                case "filledbox":
                  const boxShadow = computedStyle.boxShadow;
                  let shadowRadius = 0;
                  let shadowColor = "000000";
                  let shadowOffsetX = 0;
                  let shadowOffsetY = 0;
                  let shadowOpacity = 0;

                  if (boxShadow && boxShadow !== "none") {
                    const boxShadowRegex =
                      /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+),?\\s*([\\d.]+)?\\)?\\s+(-?\\d+)px\\s+(-?\\d+)px\\s+(-?\\d+)px/;
                    const match = boxShadow.match(boxShadowRegex);

                    if (match) {
                      const r = match[1];
                      const g = match[2];
                      const b = match[3];
                      const rgbStr = "rgb(" + r + ", " + g + ", " + b + ")";
                      shadowColor = rgbToHex(rgbStr);
                      shadowOpacity = match[4] ? parseFloat(match[4]) : 1;
                      shadowOffsetX = parseInt(match[5]);
                      shadowOffsetY = parseInt(match[6]);
                      shadowRadius = parseInt(match[7]);
                    }
                  }

                  elements.push({
                    position,
                    type:
                      computedStyle.borderRadius === "9999px" ||
                      computedStyle.borderRadius === "50%"
                        ? 9
                        : 5,
                    fill: {
                      color: rgbToHex(computedStyle.backgroundColor),
                    },
                    border_radius: parseInt(computedStyle.borderRadius) || 0,
                    stroke: {
                      color: rgbToHex(computedStyle.borderColor),
                      thickness: parseInt(computedStyle.borderWidth) || 0,
                    },
                    shadow: {
                      radius: shadowRadius,
                      color: shadowColor,
                      offset: Math.sqrt(
                        shadowOffsetX * shadowOffsetX +
                          shadowOffsetY * shadowOffsetY
                      ),
                      opacity: shadowOpacity,
                      angle: Math.round(
                        (Math.atan2(shadowOffsetY, shadowOffsetX) * 180) / Math.PI
                      ),
                    },
                  });
                  break;

                case "line":
                  elements.push({
                    position,
                    lineType: 1,
                    thickness: computedStyle.borderWidth || computedStyle.height,
                    color: rgbToHex(
                      computedStyle.borderColor || computedStyle.backgroundColor
                    ),
                  });
                  break;
              }
            });

            slidesMetadata.push({ slideIndex, backgroundColor, elements });
          });

          return slidesMetadata;
        })();
`
      )
      // ✅ Handle Graphs: capture each graph element as an image
      const graphIds: { id: string; bounds: Electron.Rectangle }[] = await win.webContents.executeJavaScript(`
        (() => {
          return Array.from(document.querySelectorAll('[data-element-type="graph"]')).map(el =>  el.getAttribute("data-element-id"));
        })();
      `);

      for (const id of graphIds) {
        try {
          // Scroll into view first
          await win.webContents.executeJavaScript(`
    document.querySelector('[data-element-id="${id}"]').scrollIntoView({ behavior: 'instant', block: 'center' });
 
    `);
          // Wait a bit for any animations/rendering to complete
          await new Promise((r) => setTimeout(r, 2000));

          const bounds: Electron.Rectangle = await win.webContents.executeJavaScript(`
      (() => {
        const el = document.querySelector('[data-element-id="${id}"]');
        if (!el) return null;
        const rect = el.getBoundingClientRect();
        return {
          x: Math.round(rect.left),
          y: Math.round(rect.top),
          width: Math.round(rect.width),
          height: Math.round(rect.height),
        };
      })();
    `);

          const image = await win.webContents.capturePage(bounds);
          const buffer = image.toJPEG(100);


          if (buffer.length === 0) {
            console.error("Empty buffer! Graph not captured.");
            continue;
          }

          const filePath = path.join(tempDir, `chart-${id}-${Date.now()}.jpeg`);
          fs.writeFileSync(filePath, buffer);

          // Update metadata
          metadata.forEach((slide: any) => {
            slide.elements.forEach((element: any) => {
              if ("picture" in element && element.picture.path === `__GRAPH_PLACEHOLDER__${id}`) {
                element.picture.path = filePath;
              }
            });
          });
        } catch (err) {
          console.error(`Failed to capture or save chart-${id}:`, err);
        }
      }
      return metadata;
    } catch (error) {
      console.error("Error during page preparation:", error);
      throw error;
    } finally {
      // if (browser) await browser.close();
      if (win) win.close();
    }
  });
}
