import { useState, useRef } from 'react';
import { Emailsend } from '../../../../Features/PurchaseOrder/PurchaseOrder';
import {
  blobToBase64,
  encryptObject,
  pdfDiv,
} from '../../../../Services/Others';
import { PrintStyleFunction } from '../../../paymentpdfPage/PrintStyleFunction';
import { PDFDocument } from 'pdf-lib';
import { PublicQrCodepost } from '../../../../Features/ConfigMasterPage/ConfigMasterPage';
import { renderToStaticMarkup } from 'react-dom/server';

const MainHomeUrl = import.meta.env.ENV_MAIN_BASE_URL;

// Create a secure blob URL creator that works in all environments
const createSecureBlobUrl = (blob) => {
  try {
    return URL.createObjectURL(blob);
  } catch (error) {
    console.warn(
      'Standard blob URL creation failed, using alternative approach'
    );
    return window.URL.createObjectURL(blob);
  }
};

// Revoke blob URL safely
const revokeSecureBlobUrl = (url) => {
  if (url && url.startsWith('blob:')) {
    try {
      URL.revokeObjectURL(url);
    } catch (error) {
      console.warn('Failed to revoke blob URL:', error);
    }
  }
};

// Merge multiple pdf blobs into one
const mergePdfBlobs = async (blobs) => {
  const mergedPdf = await PDFDocument.create();

  for (const blob of blobs) {
    const pdfBytes = await blob.arrayBuffer();
    const pdf = await PDFDocument.load(pdfBytes);
    const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
    copiedPages.forEach((page) => mergedPdf.addPage(page));
  }

  const mergedBytes = await mergedPdf.save();
  return new Blob([mergedBytes], { type: 'application/pdf' });
};

export const MobileMultiPdfPrint = async ({
  printerTemplateStyle = 'Style 13',
  printDatas = {},
  PrintOrderDetails = [],
  setPrintOrderDetails = () => {},
  PrintComing = '',
  emailId = '',
  dispatch,
  UserId = '',
  onProgress = () => {},
}) => {
  try {
    const style = await PrintStyleFunction(printerTemplateStyle, 'Sales');

    const stylesMap = {
      'Style 1': 'PrintStyle1',
      'Style 2': 'PrintStyle2',
      'Style 3': 'PrintStyle3',
      'Style 4': 'PrintStyle4',
      'Style 5': 'PrintStyle5',
      'Style 6': 'PrintStyle6',
      'Style 7': 'PrintStyle7',
      'Style 8': 'PrintStyle8',
      'Style 9': 'PrintStyle9',
      'Style 10': 'PrintStyle10',
      'Style 11': 'PrintStyle11',
      'Style 12': 'PrintStyle12',
      'Style 13': 'RePrint',
      A4: 'PrintStyleA4',
      A5: 'PrintStyleA5',
      A4Standard: 'A4Standard',
      TaxInvoice: 'TaxInvoice',
    };

    const selectedStyle = stylesMap[printerTemplateStyle] || 'RePrint';
    const Printsize = printDatas?.PageSize || 'A4';

    // Create or clear the container
    let container = document.getElementById('print-merged');
    if (!container) {
      container = document.createElement('div');
      container.id = 'print-merged';
      container.style.display = 'none';
      document.body.appendChild(container);
    } else {
      container.innerHTML = '';
    }

    // Process in batches for large files
    const BATCH_SIZE = 5;
    const totalOrders = PrintOrderDetails.length;
    let processedOrders = 0;
    let allBlobs = [];

    for (let i = 0; i < totalOrders; i += BATCH_SIZE) {
      const batch = PrintOrderDetails.slice(i, i + BATCH_SIZE);

      // Clear container for each batch
      container.innerHTML = '';

      // Process each order in the current batch
      batch.forEach((_, index) => {
        const globalIndex = i + index;
        const element = document.getElementById(
          `${selectedStyle}-${globalIndex}`
        );
        if (element) {
          const cloned = element.cloneNode(true);

          // Add page break between orders (except the last one)
          if (globalIndex < totalOrders - 1) {
            const pageBreak = document.createElement('div');
            pageBreak.style.pageBreakAfter = 'always';
            container.appendChild(cloned);
            container.appendChild(pageBreak);
          } else {
            container.appendChild(cloned);
          }
        } else {
          console.warn(
            '⚠️ Element not found:',
            `${selectedStyle}-${globalIndex}`
          );
        }
      });

      // Generate PDF for this batch
      try {
        const pdfBlob = await pdfDiv('print-merged', style);
        allBlobs.push(pdfBlob);

        processedOrders += batch.length;
        const progress = Math.round((processedOrders / totalOrders) * 100);
        onProgress(progress);
      } catch (error) {
        console.error('Error generating PDF batch:', error);
        throw new Error(
          `Failed to generate PDF for batch starting at index ${i}`
        );
      }
    }

    // ✅ Merge all PDF blobs into one
    const combinedPdfBlob = await mergePdfBlobs(allBlobs);
    const base64Pdf = await blobToBase64(combinedPdfBlob);

    // Handle different print actions
    if (PrintComing === 'download') {
      const blobUrl = createSecureBlobUrl(combinedPdfBlob);
      const link = document.createElement('a');
      link.href = blobUrl;
      link.download = 'Receipts.pdf';
      document.body.appendChild(link);
      link.click();

      setTimeout(() => {
        document.body.removeChild(link);
        revokeSecureBlobUrl(blobUrl);
      }, 100);
    }

    // if (PrintComing === "whatsapp") {
    //   const orderIds = PrintOrderDetails.map((row) => row?.OrderId).filter(Boolean);
    //   const documentUrl = `${MainHomeUrl}viewbill?code=${orderIds}`;
    //   const waUrl =
    //     "https://web.whatsapp.com/send?text=" +
    //     encodeURIComponent("Here are your receipts 👉 " + documentUrl);
    //   window.open(waUrl, "_blank");
    // }

    if (PrintComing === 'whatsapp') {
      const orderIdsArray = PrintOrderDetails.map((row) => row?.OrderId).filter(
        Boolean
      );

      if (orderIdsArray.length === 0) {
        console.warn('⚠️ No order IDs found for WhatsApp sharing.');
        return;
      }

      // 2️⃣ Encrypt order IDs
      const encrypted = encryptObject(orderIdsArray);

      // 3️⃣ Prepare payload for backend
      const postData = {
        Url: encrypted,
        CreatedBy: UserId, // Make sure UserId is passed correctly to your function
      };

      try {
        // 4️⃣ Call backend to get a ReferenceNo
        const res = await dispatch(PublicQrCodepost(postData)).unwrap();
        console.log('Backend response:', res);

        // 5️⃣ Extract ReferenceNo (adjust based on your backend response structure)
        // Example: it might be res.data.ReferenceNo or res.ReferenceNo
        const urlData = res?.data?.ReferenceNo || res?.ReferenceNo;

        if (!urlData) {
          console.error('❌ No ReferenceNo returned from backend');
          return;
        }

        // 6️⃣ Build the shareable URL
        const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;

        // 7️⃣ Open WhatsApp Web with URL
        const waUrl =
          'https://web.whatsapp.com/send?text=' +
          encodeURIComponent('Here are your receipts 👉 ' + documentUrl);

        window.open(waUrl, '_blank');
      } catch (err) {
        console.error('❌ WhatsApp sharing failed:', err);
      }
    }

    if (PrintComing === 'email') {
      try {
        const payload = {
          fileBlob: combinedPdfBlob,
          toEmail: emailId,
          type: 'Sales',
          messageTemplatesList: [],
        };

        const res = await dispatch(Emailsend(payload))?.unwrap();
        console.log('✅ Email sent response:', res?.data || res);
        return res;
      } catch (err) {
        console.error('❌ Email error:', err);
      }
    }

    if (!['download', 'whatsapp', 'email'].includes(PrintComing)) {
      const blobUrl = createSecureBlobUrl(combinedPdfBlob);

      const newWindow = window.open('', '_blank');
      if (newWindow) {
        newWindow.document.write(`
          <html>
            <head>
              <title>Receipts</title>
              <style>
                body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f0f0; }
                iframe { width: 100%; height: 100%; border: none; }
                .print-button { position: fixed; top: 20px; right: 20px; z-index: 1000; padding: 10px 15px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
              </style>
            </head>
            <body>
              <button class="print-button" onclick="window.print()">Print</button>
              <iframe src="${blobUrl}" type="application/pdf"></iframe>
            </body>
          </html>
        `);
        newWindow.document.close();
      } else {
        window.location.href = blobUrl;
      }

      // For mobile intent URL
      const intentUrl =
        'intent://open?' +
        'filename=' +
        encodeURIComponent('Receipts.pdf') +
        '&size=' +
        combinedPdfBlob.size +
        '&type=application/pdf' +
        '&data=' +
        encodeURIComponent(base64Pdf) +
        '&PrintTypeS=' +
        encodeURIComponent(Printsize) +
        '&PrintTypeE' +
        '#Intent;scheme=pozoprinter;package=com.example.pozoprinter;end';

      setTimeout(() => {
        try {
          window.location.href = intentUrl;
        } catch (e) {
          console.warn('Could not open intent URL:', e);
        }
      }, 500);
    }

    // Clean up
    setPrintOrderDetails([]);
    if (container) {
      document.body.removeChild(container);
    }

    return { success: true, message: 'PDF processed successfully' };
  } catch (error) {
    console.error('MobileMultiPdfPrint error:', error);
    return { success: false, message: error.message };
  }
};

// Progress component to show processing status
export const PdfProcessingProgress = ({ progress, isProcessing }) => {
  if (!isProcessing) return null;

  return (
    <div
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0,0,0,0.7)',
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: 10999,
      }}
    >
      <div
        style={{
          backgroundColor: 'white',
          padding: '20px',
          borderRadius: '8px',
          textAlign: 'center',
          minWidth: '300px',
        }}
      >
        <h3>Processing PDFs</h3>
        <div
          style={{
            width: '100%',
            backgroundColor: '#f0f0f0',
            borderRadius: '4px',
            margin: '15px 0',
          }}
        >
          <div
            style={{
              width: `${progress}%`,
              height: '20px',
              backgroundColor: '#4caf50',
              borderRadius: '4px',
              transition: 'width 0.3s',
            }}
          ></div>
        </div>
        <p>{progress}% Complete</p>
      </div>
    </div>
  );
};

export const MobileMultiCreditPdfPrint = async ({
  PrintOrderDetails = [],
  BSCreditCustomerPrint,
  style,
  PrintComing = '',
  emailId = '',
  dispatch,
  UserId = '',
  onProgress = () => {},
  BATCH_SIZE = 5,
}) => {
  if (!BSCreditCustomerPrint) {
    throw new Error('BSCreditCustomerPrint component is required');
  }

  // Helper: wait for images & fonts in a container
  const waitForImagesAndFonts = (container, timeout = 7000) =>
    new Promise((resolve) => {
      // images
      const imgs = Array.from(container.querySelectorAll('img'));
      let remaining = imgs.length;
      if (remaining === 0) {
        // still ensure fonts ready
        if (document.fonts && document.fonts.ready) {
          document.fonts.ready.then(() => resolve()).catch(() => resolve());
        } else resolve();
        return;
      }
      const timer = setTimeout(() => {
        clearTimeout(timer);
        resolve();
      }, timeout);
      imgs.forEach((img) => {
        if (img.complete) {
          remaining--;
          if (remaining === 0) {
            clearTimeout(timer);
            // fonts:
            if (document.fonts && document.fonts.ready) {
              document.fonts.ready.then(() => resolve()).catch(() => resolve());
            } else resolve();
          }
        } else {
          img.addEventListener(
            'load',
            () => {
              remaining--;
              if (remaining === 0) {
                clearTimeout(timer);
                if (document.fonts && document.fonts.ready) {
                  document.fonts.ready
                    .then(() => resolve())
                    .catch(() => resolve());
                } else resolve();
              }
            },
            { once: true }
          );
          img.addEventListener(
            'error',
            () => {
              remaining--;
              if (remaining === 0) {
                clearTimeout(timer);
                if (document.fonts && document.fonts.ready) {
                  document.fonts.ready
                    .then(() => resolve())
                    .catch(() => resolve());
                } else resolve();
              }
            },
            { once: true }
          );
        }
      });
    });

  // Fallback mergePdfBlobs using pdf-lib (client-side)
  const mergePdfBlobsFallback = async (blobs) => {
    if (!blobs || blobs.length === 0) {
      return new Blob([], { type: 'application/pdf' });
    }
    if (blobs.length === 1) return blobs[0];

    const mergedPdf = await PDFDocument.create();
    for (const blob of blobs) {
      const arrayBuffer = await blob.arrayBuffer();
      const donorPdf = await PDFDocument.load(arrayBuffer);
      const copiedPages = await mergedPdf.copyPages(
        donorPdf,
        donorPdf.getPageIndices()
      );
      copiedPages.forEach((p) => mergedPdf.addPage(p));
    }
    const mergedBytes = await mergedPdf.save();
    return new Blob([mergedBytes], { type: 'application/pdf' });
  };

  const blobToBase64 = (blob) =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result.split(',')[1]); // base64 without prefix
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });

  // create container or ensure empty
  let printRootContainer = document.getElementById('print-merged-react');
  if (printRootContainer) {
    printRootContainer.innerHTML = '';
  } else {
    printRootContainer = document.createElement('div');
    printRootContainer.id = 'print-merged-react';
    printRootContainer.style.display = 'none';
    document.body.appendChild(printRootContainer);
  }

  const total = PrintOrderDetails.length;
  let allBlobs = [];
  let processedVisible = 0;

  try {
    for (let i = 0; i < total; i += BATCH_SIZE) {
      const batch = PrintOrderDetails.slice(i, i + BATCH_SIZE);

      // clear container for each batch
      printRootContainer.innerHTML = '';

      // Render each BSCreditCustomerPrint into its own div
      const roots = [];
      for (let idx = 0; idx < batch.length; idx++) {
        const globalIndex = i + idx;

        const wrapper = document.createElement('div');
        wrapper.id = `Credit-customer-${globalIndex}`;

        const html = renderToStaticMarkup(
          <BSCreditCustomerPrint PrintDatas={batch[idx]} />
        );

        wrapper.innerHTML = html;

        printRootContainer.appendChild(wrapper);

        // add page break if needed
        if (globalIndex < total - 1) {
          const pb = document.createElement('div');
          pb.style.pageBreakAfter = 'always';
          printRootContainer.appendChild(pb);
        }
        roots.push(printRootContainer);
      }

      await new Promise((res) => setTimeout(res, 120)); // small tick

      await waitForImagesAndFonts(printRootContainer, 8000);

      const batchContainerId = `print-merged-batch-${i}`;
      let batchContainer = document.getElementById(batchContainerId);
      if (!batchContainer) {
        batchContainer = document.createElement('div');
        batchContainer.id = batchContainerId;
        batchContainer.style.display = 'none';
        document.body.appendChild(batchContainer);
      }
      batchContainer.innerHTML = `${style}${printRootContainer.innerHTML}`;

      const pdfBlob = await pdfDiv(batchContainerId, style);
      allBlobs.push(pdfBlob);

      roots.forEach((r) => {
        try {
          r.unmount();
        } catch (e) {
          // ignore
        }
      });

      // cleanup batch container
      try {
        if (batchContainer && batchContainer.parentElement) {
          batchContainer.parentElement.removeChild(batchContainer);
        }
      } catch (e) {
        /* ignore */
      }

      // progress
      processedVisible += batch.length;
      onProgress(Math.round((processedVisible / total) * 100));
    }

    // merge blobs - use existing merge function if available, otherwise fallback
    const combinedPdfBlob =
      typeof mergePdfBlobs === 'function'
        ? await mergePdfBlobs(allBlobs)
        : await mergePdfBlobsFallback(allBlobs);

    const base64Pdf = await blobToBase64(combinedPdfBlob);

    // Action handlers
    if (PrintComing === 'download') {
      const blobUrl =
        typeof createSecureBlobUrl === 'function'
          ? createSecureBlobUrl(combinedPdfBlob)
          : URL.createObjectURL(combinedPdfBlob);
      const link = document.createElement('a');
      link.href = blobUrl;
      link.download = 'Receipts.pdf';
      document.body.appendChild(link);
      link.click();
      setTimeout(() => {
        document.body.removeChild(link);
        if (typeof revokeSecureBlobUrl === 'function')
          revokeSecureBlobUrl(blobUrl);
        else URL.revokeObjectURL(blobUrl);
      }, 300);
      return { success: true };
    }

    if (PrintComing === 'whatsapp') {
      const orderIdsArray = PrintOrderDetails.map((r) => r?.receiptNo).filter(
        Boolean
      );
      if (orderIdsArray.length === 0) {
        console.warn('No order ids for whatsapp');
        return { success: false, message: 'No orders' };
      }
      const encrypted = encryptObject(orderIdsArray);
      const postData = { Url: encrypted, CreatedBy: UserId };
      try {
        const res = await dispatch(PublicQrCodepost(postData)).unwrap();
        const urlData = res?.data?.ReferenceNo || res?.ReferenceNo;
        if (!urlData) throw new Error('No ReferenceNo from backend');
        const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;
        const waUrl =
          'https://web.whatsapp.com/send?text=' +
          encodeURIComponent('Here are your receipts 👉 ' + documentUrl);
        window.open(waUrl, '_blank');
        return { success: true };
      } catch (err) {
        console.error('WhatsApp sharing failed', err);
        return { success: false, message: err?.message || String(err) };
      }
    }

    if (PrintComing === 'email') {
      try {
        const payload = {
          fileBlob: combinedPdfBlob,
          toEmail: emailId,
          type: 'CreditReceipt',
          messageTemplatesList: [],
        };
        const res = await dispatch(Emailsend(payload)).unwrap();
        return { success: true, data: res };
      } catch (err) {
        console.error('Email send failed', err);
        return { success: false, message: err?.message || String(err) };
      }
    }

    // default: open viewer tab and attempt mobile intent
    const blobUrl =
      typeof createSecureBlobUrl === 'function'
        ? createSecureBlobUrl(combinedPdfBlob)
        : URL.createObjectURL(combinedPdfBlob);

    const newWindow = window.open('', '_blank');
    if (newWindow) {
      newWindow.document.write(`
        <html>
          <head><title>Receipts</title>
            <style>
              body{margin:0;background:#f0f0f0;height:100vh;display:flex;align-items:center;justify-content:center}
              iframe{width:100%;height:100%;border:none}
              .print-button{position:fixed;top:16px;right:16px;padding:10px 14px;background:#4CAF50;color:white;border:none;border-radius:6px;cursor:pointer;z-index:9999}
            </style>
          </head>
          <body>
            <button class="print-button" onclick="window.print()">Print</button>
            <iframe src="${blobUrl}" type="application/pdf"></iframe>
          </body>
        </html>
      `);
      newWindow.document.close();
    } else {
      window.location.href = blobUrl;
    }

    // mobile intent (optional)
    const intentUrl =
      'intent://open?' +
      'filename=' +
      encodeURIComponent('Receipts.pdf') +
      '&size=' +
      combinedPdfBlob.size +
      '&type=application/pdf' +
      '&data=' +
      encodeURIComponent(base64Pdf) +
      '#Intent;scheme=pozoprinter;package=com.example.pozoprinter;end';

    try {
      setTimeout(() => {
        try {
          window.location.href = intentUrl;
        } catch (e) {
          /* ignore */
        }
      }, 500);
    } catch (e) {
      /* ignore */
    }

    return { success: true };
  } catch (err) {
    console.error('MobileMultiCreditPdfPrint error:', err);
    return { success: false, message: err?.message || String(err) };
  } finally {
    // final cleanup
    try {
      // remove printRootContainer and any leftover child batch containers
      const root = document.getElementById('print-merged-react');
      if (root && root.parentElement) root.parentElement.removeChild(root);

      // remove any batch containers (ids starting with print-merged-batch-)
      Array.from(
        document.querySelectorAll("[id^='print-merged-batch-']")
      ).forEach((el) => {
        try {
          el.parentElement.removeChild(el);
        } catch (e) {}
      });
    } catch (e) {
      console.warn('Cleanup error', e);
    }
  }
};
