import React, { useRef, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import imageLogo from '../content/images/Logo.png';
import * as shared from '../scripts/shared.js';
import { jsPDF } from "jspdf";

const PageInvoiceOrEstimate = () => {
    const canvasRefs = useRef([]);
    const location = useLocation();
    console.log("location:", location);
    const props = location.state.data;

    let styles = {
        container: {
            flexDirection: 'column',
            padding: 20,
        },
        header: {
            flexDirection: 'row',
            alignItems: 'center',
            marginBottom: 20,
        },
        logo: {
            width: 80,
            height: 80,
            marginRight: 20,
        },
        line: {
            height: 1,
            backgroundColor: '#000',
            marginVertical: 10,
        },
        page: {
            flexDirection: 'row',
            backgroundColor: '#E4E4E4',
            width: '100%',
            height: '100%',
            padding: 20,
        },
        section: {
            margin: 10,
            padding: 10,
            flexGrow: 1,
        },
    };
    console.log("PageInvoiceOrEstimate");
    console.log(props);
    

    const heightA4 = 1123;
    const widthA4 = 794;
    const borderPage = 75;
    const marginTable = 50;
    const spacingLabel = marginTable - 20; 
    const heightLine = 25;
    // positioning
    const heightMyBusiness = 180;
    const heightIssue = 325;
    const heightBankMyBusiness = 420;
    const heightBillToSite = 560;
    const heightHeadTable = 800;
    const heightRowMax = 1200; // update this !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    const maxRows = Math.floor((heightRowMax - heightHeadTable - heightLine) / (heightLine + spacingLabel));
    console.log("maxRows:", maxRows);
    const xPositionTableColumns = [120, 420, 520, 620];
    const typeForm = props.typeForm == "1" ? "Invoice" : "Estimate";
    console.log("typeForm:", typeForm);
    let countRowsTemp = 0;
    if (props["type" + typeForm] == "0") {
        countRowsTemp = props["quantityGoods" + typeForm];
    } else {
        for (let indexService = 0; indexService < props["quantityServices" + typeForm]; indexService++) {
            countRowsTemp += props["quantityBillingPeriodService" + typeForm + (indexService + 1)];
        }
    }
    const countRows = countRowsTemp;
    console.log("countRows:", countRows);
    const countPages = Math.ceil(props["quantityServices" + typeForm] / maxRows);
    console.log("countPages:", countPages);
    const nameFont = "Arial";
    
    const downloadPdf = (canvas, index) => {
      const pdf = new jsPDF();
      pdf.addImage(canvas.toDataURL("image/png"), "PNG", 0, 0);
      pdf.save(`canvas${index}.pdf`);
    };
    

    const renderCanvases = () => {
        const canvases = [];
        for (let indexCanvas = 0; indexCanvas < countPages; indexCanvas++) {
            canvases.push(
                <div>
                    <canvas
                    key={indexCanvas}
                    ref={(ref) => (canvasRefs.current[indexCanvas] = ref)}
                    width={widthA4}
                    height={heightA4}
                    style={{ border: '1px solid black', margin: '10px' }}
                    />
                    <button
                    onClick={() =>
                        downloadPdf(canvasRefs.current[indexCanvas], indexCanvas)
                    }
                    >
                    Download as PDF
                    </button>
                </div>
            );
        }
        return canvases;
    };

    useEffect(() => {
        let hasGoods = props["type" + typeForm] == "0";
        let hasServices = props["type" + typeForm] == "1";
        let countGoods = props["quantityGoods" + typeForm];
        let countServices = props["quantityServices" + typeForm];
        let indexGoodOrService = -1;
        let indexSubservice = -1;
        let indexRow = -1;
        let pages = [];
        let page;
        let isRequiredPageNew = true;
        while ((hasGoods && indexGoodOrService < countGoods - 1) || (hasServices && indexGoodOrService < countServices && indexRow < countRows - 1)) {
            if (isRequiredPageNew) {
                page = {
                    hasServices: hasServices,
                    hasGoods: hasGoods,
                    services: [],
                    goods: [],
                    total: 0,
                    hasTotal: false,
                };
                isRequiredPageNew = false;
            }
            indexRow++;
            if (hasGoods) {
                indexGoodOrService++;
                let good = {
                    description: props["descriptionGood" + typeForm + (indexGoodOrService + 1)],
                    quantity: props["quantityGood" + typeForm + (indexGoodOrService + 1)],
                    rate: props["rateGood" + typeForm + (indexGoodOrService + 1)],
                };
                good["subtotal"] = (good.quantity * good.rate).toFixed(2);
                page.goods.push(good);
                page.total += Number(good.subtotal);
            }
            if (hasServices) {
                indexSubservice++;
                if (indexGoodOrService == -1 || indexSubservice == props["quantityBillingPeriodService" + typeForm + (indexGoodOrService + 1)]) {
                    indexSubservice = -1;
                    indexGoodOrService++;
                    indexRow--;
                } else {
                    let service = {
                        description: props["descriptionIncrementService" + typeForm + (indexGoodOrService + 1) + "s" + (indexSubservice + 1)],
                        quantity: props["quantityRatePeriodsIncrementService" + typeForm + (indexGoodOrService + 1) + "s" + (indexSubservice + 1)],
                        rate: props["rateService" + typeForm + (indexGoodOrService + 1)],
                    };
                    service["subtotal"] = (service.quantity * service.rate).toFixed(2);
                    page.services.push(service);
                    page.total += Number(service.subtotal);
                }
            }
            if (indexRow >= maxRows) {
                indexRow = 0;
                pages.push(page);
                isRequiredPageNew = true;
            }
            if (indexRow == countRows - 1) {
                page.hasTotal = true;
                pages.push(page);
                break;
            }
        }
        console.log("pages:", pages);


        let indexPage = -1;
        canvasRefs.current.forEach((canvasRef) => {
            indexPage++;
            let page = pages[indexPage];
            console.log("plotting page:", indexPage, page);
            const canvas = canvasRef;
            const ctx = canvas.getContext('2d');
        
            // Clear the canvas
            ctx.clearRect(0, 0, widthA4, heightA4);
            ctx.fillStyle = '#fff';
            ctx.fillRect(0, 0, widthA4, heightA4);
            ctx.fillStyle = '#000';

            plot(ctx, page);
        });
    }, []);

    const plot = (context, page) => { // typeForm, do_goods, rows_g, n_goods, do_services, rows_s, n_services, n_subs, ratedisc, date_due, my_ref) {
        plotPageLayout(context);
        plotPageInterpersonal(context);
        plotHeadingsTableInvoiceOrEstimate(context);

        let currency = props.currency;

        if (page.hasServices) {
            context.font = '12px ' + nameFont;
            // page.services.map((service, index) => {
            let service;
            for (let indexService = 0; indexService < page.services.length; indexService++) {
                service = page.services[indexService];
                context.fillText(service.description, xPositionTableColumns[0], heightHeadTable + (indexService + 1) * heightLine);
                context.fillText(service.quantity, xPositionTableColumns[1], heightHeadTable + (indexService + 1) * heightLine);
                context.fillText(service.rate, xPositionTableColumns[2], heightHeadTable + (indexService + 1) * heightLine);
                context.fillText(service.subtotal, xPositionTableColumns[3], heightHeadTable + (indexService + 1) * heightLine);
            };
        }
        if (page.hasGoods) {
            context.font = '12px ' + nameFont;
            // page.goods.map((good, index) => {
            let good;
            for (let indexGood = 0; indexGood < page.goods.length; indexGood++) {
                good = page.goods[indexGood];
                context.fillText(good.description, xPositionTableColumns[0], heightHeadTable + (indexGood + 1) * heightLine);
                context.fillText(good.quantity, xPositionTableColumns[1], heightHeadTable + (indexGood + 1) * heightLine);
                context.fillText(good.rate, xPositionTableColumns[2], heightHeadTable + (indexGood + 1) * heightLine);
                context.fillText(good.subtotal, xPositionTableColumns[3], heightHeadTable + (indexGood + 1) * heightLine);
            };
        }
        if (page.hasTotal) {
            context.font = '12px ' + nameFont;
            let heightRowTotal = heightHeadTable + (1 + (page.hasGoods ? page.goods.length : page.services.length)) * heightLine;
            console.log("page total: ", page.total);
            context.fillText(currency + page.total.toFixed(2), xPositionTableColumns[3] - 10, heightRowTotal);
            context.fillText('TOTAL:', xPositionTableColumns[3] - borderPage - 10, heightRowTotal);
        }
    }
    
    const plotPageLayout = (context) => {
        context.beginPath();
        context.font = '20px ' + nameFont;
        context.fillText(typeForm, borderPage, 100);
        // context.fillText('ESTIMATE', borderPage, 100);
        context.font = 'bold 12px ' + nameFont;
        context.fillText('BANK NAME:', borderPage, heightBankMyBusiness);
        context.fillText('ACCOUNT NAME:', borderPage, heightBankMyBusiness + heightLine);
        context.fillText('ACCOUNT NUMBER:', borderPage, heightBankMyBusiness + heightLine * 2);
        context.fillText('SORT CODE:', borderPage, heightBankMyBusiness + heightLine * 3);
        context.font = 'bold 12px ' + nameFont;
        context.fillText('ISSUE DATE:', widthA4 / 2 + marginTable, heightIssue);
        context.fillText('DUE DATE:', widthA4 / 2 + marginTable, heightIssue + heightLine);
        context.fillText('REFERENCE:', widthA4 / 2 + marginTable, heightIssue + heightLine * 2);
        context.font = 'bold 12px ' + nameFont;
        context.fillText('BILL TO:', borderPage, heightBillToSite);
        context.fillText('SITE / LOCATION:', widthA4 / 2 + marginTable, heightBillToSite);
        context.stroke();
    }

    const plotPageInterpersonal = (context) => {
        context.font = '14px ' + nameFont;
        context.fillText(props.nameMyBusiness, borderPage, heightMyBusiness );
        context.font = '12px ' + nameFont;
        context.fillText(props.address1MyBusiness, borderPage, heightMyBusiness + heightLine * 1);
        context.fillText(props.address2MyBusiness, borderPage, heightMyBusiness + heightLine * 2);
        context.fillText(props.address3MyBusiness, borderPage, heightMyBusiness + heightLine * 3);
        context.fillText(props.address4MyBusiness, borderPage, heightMyBusiness + heightLine * 4);
        context.fillText(props.address5MyBusiness, borderPage, heightMyBusiness + heightLine * 5);
        context.fillText(props.emailMyBusiness, borderPage, heightMyBusiness + heightLine * 6);
        context.fillText(props.companyNumberMyBusiness, borderPage, heightMyBusiness + heightLine * 7);

        // logo
        var img = new Image();
        img.crossOrigin = "anonymous";
        // CORS_ALLOW_ALL_ORIGINS = true;
        img.style.border = 'none';
        img.src = imageLogo; // "https://raw.githubusercontent.com/Teddy-1024/Neural_Network/master/Deane_logo.png";
        let sz_img = 200;
        img.onload = function() {
            context.drawImage(img, widthA4 - borderPage * 3 / 2 -sz_img, borderPage, sz_img, sz_img); // , 0, 0, 0, 0, borderPage + 25, borderPage + 2, sz_img, sz_img);
            context.stroke();
        }

        context.font = '12px ' + nameFont;
        context.fillText(props.nameBankMyBusiness, borderPage + 150, heightBankMyBusiness);
        context.fillText(props.accountNameBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine);
        context.fillText(props.accountNumberBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine * 2);
        context.fillText(props.sortCodeBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine * 3);

        context.font = '12px ' + nameFont;
        context.fillText(getDateIssue(), widthA4 / 2 + marginTable + 120, heightIssue);
        context.fillText(getDateDue(), widthA4 / 2 + marginTable + 120, heightIssue + heightLine);
        context.fillText(getReference(), widthA4 / 2 + marginTable + 120, heightIssue + heightLine * 2);

        context.font = '12px ' + nameFont;
        context.fillText(props.nameTheirBusiness, borderPage, heightBillToSite + heightLine * 1);
        context.fillText(props.address1TheirBusiness, borderPage, heightBillToSite + heightLine * 2);
        context.fillText(props.address2TheirBusiness, borderPage, heightBillToSite + heightLine * 3);
        context.fillText(props.address3TheirBusiness, borderPage, heightBillToSite + heightLine * 4);
        context.fillText(props.address4TheirBusiness, borderPage, heightBillToSite + heightLine * 5);
        context.fillText(props.address5TheirBusiness, borderPage, heightBillToSite + heightLine * 6);
        context.fillText(props.emailTheirBusiness, borderPage, heightBillToSite + heightLine * 7);
        context.fillText(props.phoneTheirBusiness, borderPage, heightBillToSite + heightLine * 8);

        context.fillText(props.nameContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 1);
        context.fillText(props.address1ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 2);
        context.fillText(props.address2ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 3);
        context.fillText(props.address3ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 4);
        context.fillText(props.address4ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 5);
        context.fillText(props.address5ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 6);
        context.stroke();
    }
    
    const getDateIssue = () => {
        let date = new Date(props["dateBilling" + typeForm]);
        return shared.date2str(new Date(date.getFullYear(), date.getMonth(), -1));
    }

    const getDateDue = () => {
        let date_0 = new Date(props.dateBillingInvoice);
        let y0 = date_0.getFullYear();
        let m0 = date_0.getMonth();
        let date_1 = new Date(y0, m0 + 1, 1);
        let n_working_days = 1;
        let n_days_total = 4;
        let date_temp = date_1;
        for (let i = 1; i < 6; i++) {
            date_temp.setDate(date_temp.getDate() + 1);
            let billday = date_temp.getDay();
            if (!(billday == 0 || billday == 6)) {
                n_working_days++;
            }
            if (n_working_days == n_days_total) {
                break;
            }
        }
        let date_2 = date_temp;
        return convertDateToString(date_2);
    }

    const convertDateToString = (date) => {
        return date.getFullYear().toString() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0');
    }

    const getReference = (pageHasGoods) => {
        let name;
        if (pageHasGoods) {
            name = "goods" + convertDateToString(new Date());
        } else {
            let week1 = props["idBillingPeriodFirstIncrementalService" + typeForm + "1"];
            let weekN = String(Number(week1) + Number(props["quantityBillingPeriodService" + typeForm + "1"]) - 1);
            let year = props["dateBilling" + typeForm].substr(2, 2);// date.getFullYear();
            name = year + "_wks_" + week1 + "-" + weekN;
        }
        return name;
    }

    function plotHeadingsTableInvoiceOrEstimate(context) {
        context.font = 'bold 12px ' + nameFont;
        context.fillText('DESCRIPTION', xPositionTableColumns[0] + 30, heightHeadTable);
        context.fillText('QUANTITY', xPositionTableColumns[1] - 20, heightHeadTable);
        context.fillText('UNIT COST [' + props.currency + ']', xPositionTableColumns[2] - 12, heightHeadTable);
        context.fillText('SUBTOTAL', xPositionTableColumns[3] - 10, heightHeadTable);
    }

    return (
        <div>
            {renderCanvases()}
        </div>
    );
};

export default PageInvoiceOrEstimate;