// InvoiceDetail.jsx
import React, { useEffect, useRef, useState } from 'react';
import html2pdf from 'html2pdf.js';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment';
import {
  dateFormatChange1,
  decryptToObject,
  encryptObject,
  extractLastNumber,
  extractLastNumberOrderId,
  getSession,
  sessionStore,
} from '../../Services/Others';
import { ApplicationPreferences, getBranchDetail, getCommonAppPreference } from '../../Features/BrachLogin/BranchLogin';
import PrintStyle1 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle1';
import PrintStyle2 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle2';
import PrintStyle3 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle3';
import PrintStyle4 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle4';
import PrintStyle5 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle5';
import PrintStyle6 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle6';
import PrintStyle7 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle7';
import PrintStyle8 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle8';
import PrintStyle9 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle9';
import PrintStyle10 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle10';
import PrintStyle11 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle11';
import PrintStyle12 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle12';
import {
  getPrintSelectionComponentData,
  GloabalFieldDetails,
  GlobalPricingAppPricingName,
  GlobalprintDatas,
  PricingAppPricingNameData,
  SelectedPrintTemplate,
} from '../../Features/ThemeChange/ThemeChange';
import {
  getPreferenceData,
  PaymentGatewayGetdetail,
} from '../../Features/BookingScreen/BookingData/BookingData';
import axios from 'axios';
import { FiDownload, FiChevronLeft, FiChevronRight } from 'react-icons/fi';
import './PaymentPdfBooking.scss';
import TaxInvoice from '../BookingScreen/PrintTemplates/A4/TaxInvoice';
import A4Standard from '../PurchaseReturn/PrintReturn/A4purchaseReturn/A4Standard';
import { PublicQrCodeget, PublicQrCodepost } from '../../Features/ConfigMasterPage/ConfigMasterPage';
import PrintStyle13 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle13';
import PrintA5Style11 from '../BookingScreen/PrintTemplates/A4/PrintStyleA5';
import InvoiceTemplate from '../BookingScreen/PrintTemplates/A4/A4Standard';
import PrintA4Style11 from '../BookingScreen/PrintTemplates/A4/PrintA4Style11';

const apiUrlToken = import.meta.env.ENV_API_URL_TOKEN;

const LinkUrlCreate = () => {
  const dispatch = useDispatch();
  const CreatedDate = '2023-10-01T12:00:00Z';
  const printRef = useRef();
  const containerRef = useRef();
  const [currentPage, setCurrentPage] = useState(0);
  const url_string = window.location.href;
  const url = new URL(url_string);
  const [PrintOrderDetails, setPrintOrderDetails] = useState([]);
  const [printerTemplateStyle, setPrintSettingData] = useState('');
  const [Preference, setPreferenceData] = useState([]);
  const [base64Image, setBase64Image] = useState(null);
  const [conversionError, setConversionError] = useState(null);
  const [allData, setAllData] = useState(null);
  const [table2Data, setTable2Data] = useState({});
  const [branchDetails, setBranchDetails] = useState({});
  const [ProdId, setProdId] = useState([]);
  const [isDataLoading, setIsDataLoading] = useState(true);
  const [allDataLoaded, setAllDataLoaded] = useState(false);

  const codesParam = url.searchParams.get('code');

  // Global selectors
  const FieldDetails = useSelector(GloabalFieldDetails);
  const pricingAppName = useSelector(GlobalPricingAppPricingName);
  const printTemplate = useSelector(SelectedPrintTemplate); // This should get the PrintTemplate from global state
  const globalPrintDatas = useSelector(GlobalprintDatas); // This should get printDatas from global state
  const appPreferences = useSelector(ApplicationPreferences);

const commonModulePreference = appPreferences?.find(
    (preference) => preference?.PreferredCatName === "Common Module"
  )?.PreferenceCatDetails;
  const sportsAppPreference = commonModulePreference?.find(
    (preference) => preference?.PreferredSubCatName === "SportsApp" && preference?.PreferredStatus === "Y"
  );
  useEffect(() => {
    initializeData();
  }, []);

  const initializeData = async () => {
    try {
      setIsDataLoading(true);
      setAllDataLoaded(false);
      await addSession();
      await getQrCode();
    } catch (error) {
      console.error('Error initializing data:', error);
      setIsDataLoading(false);
    }
  };

  const getQrCode = async () => {
    try {
      const getQrCodedata = await dispatch(PublicQrCodeget(codesParam)).unwrap();
      const oldUrl = getQrCodedata.data.data?.[0]?.OldUrl;
      const decrypted = decryptToObject(oldUrl);

      // Normalize decrypted value into an array of OrderIds
      let orderIds = [];
      if (Array.isArray(decrypted)) {
        orderIds = decrypted.map((v) => String(v).trim()).filter(Boolean);
      } else if (typeof decrypted === 'string') {
        orderIds = decrypted.split(',').map((v) => v.trim()).filter(Boolean);
      } else if (decrypted && typeof decrypted === 'object') {
        const possible = decrypted.OrderId || decrypted.orderId || decrypted.code || decrypted.id;
        if (possible) orderIds = [String(possible).trim()];
      }

      setProdId(orderIds);
    } catch (error) {
      console.error('Error getting QR code:', error);
      setIsDataLoading(false);
    }
  };

  const addSession = async () => {
    if (!sessionStorage.getItem('auth')) {
      try {
        let data = {
          username: '1000000001',
          password: '1234',
        };
        const response = await axios.post(
          `${apiUrlToken}/jwtTokenGenerator`,
          data,
          {
            headers: {
              'Content-Type': 'application/json',
              Accept: 'application/json',
            },
          }
        );

        const { token } = response?.data;
        sessionStorage.setItem('auth', token);
        sessionStore('LoginType', 'Kiosk');
      } catch (error) {
        console.error('Error adding session:', error);
      }
    }
  };

  // Fetch API data when ProdId is available
  useEffect(() => {
    if (Array.isArray(ProdId) && ProdId.length > 0) {
      fetchApiData(ProdId);
    }
  }, [ProdId]);

  const fetchApiData = async (orderIds = []) => {
    try {
      const promises = orderIds.map((orderId) =>
        dispatch(PaymentGatewayGetdetail(orderId))
          .unwrap()
          .then((response) => response?.data?.data?.[0] || null)
      );

      const results = await Promise.all(promises);
      const validResults = results.filter(Boolean);

      setPrintOrderDetails(validResults);
      if (validResults.length > 0) {
        await loadAllRequiredData(validResults[0]);
      }
    } catch (error) {
      console.error("Error fetching bill details:", error);
      setIsDataLoading(false);
    }
  };

  const loadAllRequiredData = async (firstInvoice) => {
    try {
      const { AppId, CompId, BranchId } = firstInvoice;
      const pricingData = {
        appId: AppId,
        compId: CompId,
        branchId: BranchId,
      };
      const printData = { AppId, CompId, BranchId };

      // Step 1: Call PricingAppPricingName to update global state
      console.log("Step 1: Calling PricingAppPricingNameData...");
      const pricingRes = await dispatch(PricingAppPricingNameData(pricingData)).unwrap();
      console.log(pricingRes, "PricingAppPricingName response");
        const commonapppreference = await dispatch(getCommonAppPreference({ appId: AppId})).unwrap();
      // Step 2: Call getPrintSelectionComponentData to update global state with print template
      console.log("Step 2: Calling getPrintSelectionComponentData...");
      const printSettings = await dispatch(getPrintSelectionComponentData(printData)).unwrap();
      console.log(printSettings,commonapppreference, "getPrintSelectionComponentData response");

      // Step 3: Call getPreferenceData
      console.log("Step 3: Calling getPreferenceData...");
      const preferences = await dispatch(getPreferenceData(printData)).unwrap();
      setPreferenceData(preferences?.data);

      // Step 4: Fetch branch details
      console.log("Step 4: Fetching branch details...");
      const branchIds = [...new Set([BranchId])]; // Start with current branch
      await Promise.all(branchIds.map(branchId => fetchBranchData(branchId)));

      // All data loaded successfully
      console.log("All data loaded successfully");
      setAllDataLoaded(true);

    } catch (error) {
      console.error('Error loading required data:', error);
    } finally {
      setIsDataLoading(false);
    }
  };

  // Handle additional branch details after PrintOrderDetails is set
  useEffect(() => {
    if (PrintOrderDetails?.length > 0 && allDataLoaded) {
      // Get any additional unique branch IDs from all invoices
      const allBranchIds = [...new Set(PrintOrderDetails.map(invoice => invoice.BranchId))];
      const currentBranchIds = Object.keys(branchDetails);
      const newBranchIds = allBranchIds.filter(id => !currentBranchIds.includes(String(id)));

      // Fetch details for any new branches
      newBranchIds.forEach(branchId => {
        if (branchId) {
          fetchBranchData(branchId);
        }
      });
    }
  }, [PrintOrderDetails, allDataLoaded]);

  const fetchBranchData = async (BranchId) => {
    try {
      const response = await dispatch(
        getBranchDetail({ BrId: BranchId })
      ).unwrap();
      if (response?.data?.statusCode === 1) {
        setBranchDetails(prev => ({
          ...prev,
          [BranchId]: {
            address: response?.data?.data?.[0]?.Address1,
            city: response?.data?.data?.[0]?.City,
            zip: response?.data?.data?.[0]?.Zip,
            logo: response?.data?.data?.[0]?.CompLogo
          }
        }));
      }
    } catch (error) {
      console.error('Error fetching branch data:', error);
    }
  };

  const imageUrlToBase64 = async (url) => {
    try {
      const response = await fetch(url);
      const blob = await response.blob();
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      });
    } catch (error) {
      console.error('Error fetching or converting image:', error);
      throw error;
    }
  };

  // Convert logos to base64
  useEffect(() => {
    async function convertLogos() {
      const newBase64Images = {};

      for (const [branchId, details] of Object.entries(branchDetails)) {
        if (details.logo) {
          try {
            const base64 = await imageUrlToBase64(details.logo);
            newBase64Images[branchId] = base64;
          } catch (error) {
            console.error(`Error converting image for branch ${branchId}:`, error);
            newBase64Images[branchId] = null;
          }
        }
      }

      setBase64Image(newBase64Images);
    }

    if (Object.keys(branchDetails).length > 0) {
      convertLogos();
    }
  }, [branchDetails]);

  const CashierName = PrintOrderDetails?.[0]?.CashierName || null;

  // const handleDownloadPDF = () => {
  //   html2pdf().from(printRef.current).save();
  // };


  const handleDownloadPDF = () => {
    const element = printRef.current;
    const options = {
      // margin: 0.5,
      margin: 0,
      filename: "document.pdf",
      image: { type: "jpeg", quality: 0.98 },
      html2canvas: { scale: 2, useCORS: true }, // makes CSS + images sharper
      // jsPDF: { unit: "in", format: "a4", orientation: "portrait" },
      jsPDF: { unit: "px", format: [element.offsetWidth, element.offsetHeight] },
    };

    html2pdf().set(options).from(element).save();
  };

  const scrollToPage = (pageIndex) => {
    const pages = containerRef.current?.children;
    if (pages && pages[pageIndex]) {
      pages[pageIndex].scrollIntoView({ behavior: 'smooth', block: 'start' });
      setCurrentPage(pageIndex);
    }
  };

  const handleNextPage = () => {
    if (currentPage < PrintOrderDetails.length - 1) {
      scrollToPage(currentPage + 1);
    }
  };

  const handlePrevPage = () => {
    if (currentPage > 0) {
      scrollToPage(currentPage - 1);
    }
  };

  // Get preference data
  let SalesModePref = Preference?.[0]?.SettingDtlDetails?.filter(
    (i) => i.SettingIdName === 'Sales Mode'
  )?.[0];

  let PrintLogo = Preference?.[0]?.SettingDtlDetails?.filter(
    (i) => i.SettingIdName === 'PrintLogo'
  )?.[0];

  let PrintGreeting = Preference?.[0]?.SettingDtlDetails?.filter(
    (i) => i.SettingIdName === 'PrintGreetings'
  )?.[0];

  const Date1 = dateFormatChange1(CreatedDate);

  // Show loading state while data is being fetched
  if (isDataLoading || !allDataLoaded) {
    return (
      <div className="loading-container" style={{ padding: '20px', textAlign: 'center' }}>
        <div>Loading invoice Bill...</div>
      </div>
    );
  }

  // Show message if no data
  if (!PrintOrderDetails || PrintOrderDetails.length === 0) {
    return (
      <div className="no-data-container" style={{ padding: '20px', textAlign: 'center' }}>
        <div>No invoice data found.</div>
      </div>
    );
  }

  // Show message if print template is not loaded
  if (!printTemplate) {
    return (
      <div className="no-template-container" style={{ padding: '20px', textAlign: 'center' }}>
        <div>Print template not available. Please check your configuration.</div>
      </div>
    );
  }

  return (
    <>
      <div className="invoice-viewer-controls">
        <button
          onClick={handleDownloadPDF}
          className="control-btn download-btn"
          title="Download PDF"
        >
          <FiDownload size={20} />
        </button>

        {PrintOrderDetails.length > 1 && (
          <div className="pagination-controls">
            <button
              onClick={handlePrevPage}
              disabled={currentPage === 0}
              className="control-btn nav-btn"
              title="Previous Invoice"
            >
              <FiChevronLeft size={20} />
            </button>

            <span className="page-indicator">
              {currentPage + 1} / {PrintOrderDetails.length}
            </span>

            <button
              onClick={handleNextPage}
              disabled={currentPage === PrintOrderDetails.length - 1}
              className="control-btn nav-btn"
              title="Next Invoice"
            >
              <FiChevronRight size={20} />
            </button>
          </div>
        )}
      </div>

      <div className="invoice-container" ref={containerRef}>
        <div ref={printRef}>
          {PrintOrderDetails?.map((table2Data, index) => {
            if (!table2Data) return null;
            const { BranchId, SalesDate, CashierName, productDetails, TaxDetails,
              ExtraChargeDetails, OrderOfferDetails, PaymentOrderDtl, OrderId, FYStatus } = table2Data;

            const branchDetail = branchDetails[BranchId] || {};
            const currentBase64Image = base64Image?.[BranchId] || null;

            const Date1 = dateFormatChange1(SalesDate);
            const PaymentStatusSuccess = PaymentOrderDtl?.filter(ps => ps.PaymentStatus === 'S');

            const ExtraChargeTotal = ExtraChargeDetails?.reduce(
              (accumulator, currentObject) => accumulator + currentObject.TotalAmt, 0
            ) || 0;

            const productsData = productDetails || [];
            const offers = OrderOfferDetails || [];
            let TotalOfferAmount = 0;

            // Calculate SalesWiseOffers total amount
            offers.forEach((offer) => {
              if (offer.TableName === 'SalesWiseOffers') {
                TotalOfferAmount += offer.OfferAmount;
              }
            });

            const hasMappedOffer = offers.some((offer) =>
              ['ItemWiseOffers', 'BundleOffers', 'QuantityWiseOffers'].includes(offer.TableName)
            );

            if (hasMappedOffer) {
              const productTotal = productsData?.reduce(
                (acc, item) => acc + (item?.Type != 'C' ? item.OfferAmt : item.OfferValue || 0), 0
              );
              TotalOfferAmount += productTotal;
            } else {
              const Combothere = productsData?.filter((item) => item?.Type == 'C');
              const CombothereTotal = Combothere?.reduce(
                (acc, item) => acc + (item.OfferValue || 0), 0
              );
              TotalOfferAmount += CombothereTotal;
            }

            let totalQuantityFilter = productsData?.map(
              (item) => item?.SalesQty || item?.OrderQty
            );

            const totalQuantity = totalQuantityFilter?.reduce(
              (accumulator, currentValue) => accumulator + currentValue, 0
            ) || 0;

            const OrderDetailGST = TaxDetails?.filter(
              (item) => item.TaxIdName?.toLowerCase() === 'cgst,sgst'
            );

            const OrderDetailIGST = TaxDetails?.filter(
              (item) => item.TaxIdName?.toLowerCase() === 'igst'
            );

            const OrderDetailVAT = TaxDetails?.filter(
              (item) => item.TaxIdName?.toLowerCase() === 'vat'
            );

            const tokenGroups = (productsData || []).reduce(
              (acc, item, idx) => {
                if (item.TokenAvailable === 'Y') {
                  if (!item.CounterName) {
                    acc[`individual-${idx}`] = [item];
                  } else {
                    if (!acc[item.CounterName]) acc[item.CounterName] = [];
                    acc[item.CounterName].push(item);
                  }
                }
                return acc;
              },
              {}
            );

            // Render print template based on global state
            const renderPrintTemplate = () => {
              const commonProps = {
                index,
                ExtraChargeTotal,
                Date1,
                base64Image: currentBase64Image,
                BranchAddress: branchDetail.address,
                BranchCity: branchDetail.city,
                BranchZip: branchDetail.zip,
                SalesModePref,
                CashierName,
                totalQuantity,
                OrderDetailGST,
                OrderDetailIGST,
                OrderDetailVAT,
                table2Data,
                totalQuantityFilter,
                PaymentStatus: PaymentOrderDtl,
                PrintLogo,
                PrintGreeting,
                printDatas: globalPrintDatas,
              sportsAppPreference:sportsAppPreference
              };
console.log(printTemplate,"printTemplate")
              switch (printTemplate) {
                case 'Style 1':
                  return <PrintStyle1 {...commonProps} isPdf={true} />;
                case 'Style 2':
                  return <PrintStyle2 {...commonProps} isPdf={true} />;
                case 'Style 3':
                  return <PrintStyle3 {...commonProps} isPdf={true} />;
                case 'Style 4':
                  return <PrintStyle4 {...commonProps} isPdf={true} />;
                case 'Style 5':
                  return <PrintStyle5 {...commonProps} isPdf={true} />;
                case 'Style 6':
                  return <PrintStyle6 {...commonProps} isPdf={true} />;
                case 'Style 7':
                  return <PrintStyle7 {...commonProps} isPdf={true} />;
                case 'Style 8':
                  return <PrintStyle8 {...commonProps} isPdf={true} />;
                case 'Style 9':
                  return <PrintStyle9 {...commonProps} isPdf={true} />;
                case 'Style 10':
                  return <PrintStyle10 {...commonProps} isPdf={true} />;
                case 'Style 11':
                  return <PrintStyle11 {...commonProps} isPdf={true} />;
                case 'Style 12':
                  // return <PrintStyle12 {...commonProps}  isPdf={true}/>;
                  //  case 'Style 13':
                  return <PrintStyle13 {...commonProps} isPdf={true} />;
                case 'A4':
                  return <PrintA4Style11 {...commonProps} isPdf={true} />;
                case 'A5':
                  return <PrintA5Style11 {...commonProps} isPdf={true} />;
                case 'A4Standard':
                  return <InvoiceTemplate {...commonProps} isPdf={true} />;
                case 'TaxInvoice':
                  return <TaxInvoice {...commonProps} isPdf={true} />;
                default:
                  return <PrintStyle1 {...commonProps} isPdf={true} />;
              }
            };

            return (
              <div key={index} className="invoice-page">
                <div
                  className="Reprint-body"
                  id={`RePrint-${index}`}
                  style={{ width: '50%' }}
                />

                {renderPrintTemplate()}

                {/* Token Print */}
                {/* {Object.entries(tokenGroups).map(
                  ([counterName, items], tokenIdx) => (
                    <div key={`token-${index}-${tokenIdx}`} className="token-page">
                      <div
                        className="Reprint-body"
                        id={`TakeawayToken${index}-${tokenIdx}-${counterName}`}
                        style={{ width: '50%' }}
                      >
                        <div className="Re-print-top">
                          <p className="Re-print-title">{items[0]?.BrName}</p>
                          <p className="Re-print-title">Token</p>
                        </div>
                        <div className="Re-print-top2">
                          <p className="Re-print-bold">
                            BillNo:&nbsp;
                            {OrderId && extractLastNumberOrderId(OrderId, FYStatus)}
                          </p>
                          <p className="Re-print-bold">{Date1}</p>
                        </div>
                        <table className="Re-print-Table">
                          <thead className="Re-print-th">
                            <tr>
                              <th className="Re-print-td">S.No</th>
                              <th className="Re-print-td">Item</th>
                              <th className="Re-print-td">Qty</th>
                              <th className="Re-print-td">Rate</th>
                              <th className="Re-print-td">Price</th>
                            </tr>
                          </thead>
                          <tbody>
                            {items?.map((item, idx) => (
                              <tr className="Re-print-body-Tr" key={idx}>
                                <td className="Re-print-td">{idx + 1}</td>
                                <td className="Re-print-body-Product">
                                  {item.ProdName}
                                </td>
                                <td className="Re-print-body-Rate">
                                  {item.SalesQty}
                                </td>
                                <td className="Re-print-body-Rate">
                                  {item.Rate}
                                </td>
                                <td className="Re-print-body-Rate">
                                  {item.TotalAmt}
                                </td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  )
                )} */}
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
};

export default LinkUrlCreate;