import * as htmlToImage from "html-to-image";
import { PDFDocument } from "pdf-lib";

/** ฟังก์ชันสำหรับแสดง loading spinner */
export function showLoadingSpinner() {
  const loading = document.createElement("div");
  loading.id = "loading-spinner";
  loading.style.position = "fixed";
  loading.style.top = "0";
  loading.style.left = "0";
  loading.style.width = "100vw";
  loading.style.height = "100vh";

  // ปรับให้มืดขึ้น (0.6) และเพิ่มการเบลอฉากหลัง (blur)
  loading.style.background = "rgba(0, 0, 0, 0.6)";
  loading.style.backdropFilter = "blur(4px)";

  loading.style.display = "flex";
  loading.style.alignItems = "center";
  loading.style.justifyContent = "center";
  loading.style.zIndex = "99999";

  loading.innerHTML = `
    <div style="display:flex;flex-direction:column;align-items:center;">
      <div style="
        border: 8px solid #f3f3f3;
        border-top: 8px solid #3498db;
        border-radius: 50%;
        width: 60px;
        height: 60px;
        animation: spin 1s linear infinite;">
        </div>
    </div>

    <style>
      @keyframes spin {
        0% { transform: rotate(0deg);}
        100% { transform: rotate(360deg);}
      }
    </style>
  `;
  document.body.appendChild(loading);
}

/** ฟังก์ชันสำหรับซ่อน loading spinner */
function hideLoadingSpinner() {
  const loading = document.getElementById("loading-spinner");
  if (loading) loading.remove();
}

/**
 * Prepares an HTML node for export by cloning it, applying styles to reveal its full size,
 * and calculating its dimensions.
 * @param node The HTMLElement to prepare.
 * @returns A promise that resolves with the cloned node, its container, and its dimensions.
 */
async function prepareNodeForExport(node: HTMLElement) {
  const container = document.createElement("div");
  container.style.position = "absolute";
  container.style.left = "-9999px";
  container.style.top = "0";
  container.style.width = "fit-content";
  container.style.height = "fit-content";
  container.style.overflow = "visible";
  container.style.backgroundColor = "#fff"; // ป้องกันพื้นหลังโปร่งแสง

  const clone = node.cloneNode(true) as HTMLElement;

  clone.style.width = "max-content"; // ให้กางตามความกว้างของ Chart ทั้งหมด
  clone.style.height = "auto";
  clone.style.overflow = "visible";

  container.appendChild(clone);
  document.body.appendChild(container);

  await document.fonts.ready;
  // เพิ่มเวลาอีกนิดเพื่อให้ CSS 'auto' คำนวณเสร็จสมบูรณ์
  await new Promise((resolve) => setTimeout(resolve, 1200));

  const fullWidth = clone.scrollWidth;
  const fullHeight = clone.scrollHeight;

  return { clone, container: container, fullWidth, fullHeight };
}

/**
 * ฟังก์ชันสำหรับ export โครงสร้างองค์กรเป็น PNG
 * @param node HTMLElement ที่ต้องการ export เป็น PNG
 */
export async function exportChartToPNG(node: HTMLElement): Promise<void> {
  if (!node) return;

  let container: HTMLElement | null = null;
  try {
    const {
      clone,
      container: cont,
      fullWidth,
      fullHeight,
    } = await prepareNodeForExport(node);
    container = cont;

    const imageData = await htmlToImage.toPng(clone, {
      backgroundColor: "#ffffff",
      quality: 1,
      width: fullWidth + 100, // Add padding to prevent clipping
      height: fullHeight + 100,
      style: {
        padding: "50px",
        margin: "0",
        fontFamily: "'Sarabun', sans-serif",
      },
      cacheBust: true,
    });

    const link = document.createElement("a");
    link.download = "orgchart.png";
    link.href = imageData;
    link.click();
  } catch (error: any) {
    console.error("Export Error:", error);
    alert("Export ไม่สำเร็จ: " + error.message);
  } finally {
    if (container && document.body.contains(container)) {
      document.body.removeChild(container);
    }
    hideLoadingSpinner();
  }
}

/**
 * ฟังก์ชันสำหรับ export โครงสร้างองค์กรเป็น PDF
 * @param node HTMLElement ที่ต้องการ export เป็น PDF
 */
export async function exportChartToPDF(node: HTMLElement): Promise<void> {
  if (!node) return;

  let container: HTMLElement | null = null;
  try {
    const {
      clone,
      container: cont,
      fullWidth,
      fullHeight,
    } = await prepareNodeForExport(node);
    container = cont;

    // Use htmlToImage for better Thai language stability
    const imageData = await htmlToImage.toPng(clone, {
      backgroundColor: "#ffffff",
      quality: 1,
      width: fullWidth,
      height: fullHeight,
      style: {
        fontFamily: "'Sarabun', sans-serif",
      },
      cacheBust: true,
    });

    // Create PDF with pdf-lib
    const pdfDoc = await PDFDocument.create();
    // Add a PDF page based on the actual image size
    const page = pdfDoc.addPage([fullWidth, fullHeight]);
    const pngImage = await pdfDoc.embedPng(imageData);

    page.drawImage(pngImage, {
      x: 0,
      y: 0,
      width: fullWidth,
      height: fullHeight,
    });

    const pdfBytes = await pdfDoc.save();

    // Download the file
    const blob = new Blob([pdfBytes], { type: "application/pdf" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "orgchart.pdf";
    a.click();
    URL.revokeObjectURL(url);
  } catch (err: any) {
    console.error("PDF Export Error:", err);
    alert("Export PDF ไม่สำเร็จ: " + err.message);
  } finally {
    // Clean up the clone and hide loading
    if (container && document.body.contains(container)) {
      document.body.removeChild(container);
    }
    hideLoadingSpinner();
  }
}
