public with sharing class QuotePDFController {
    public QuoteInfo quoteInfo {get; private set;}
    public List<SetInfo> printRecords {get; private set;}
    public Integer pageCnt {get; private set;}
    public String isPrintPrice {get; private set;}
    public String currencyIsoCode {get; private set;}

    public boolean is_hidden_user { get; set; }
    public boolean is_dealer_user { get; set; }

    private String targetId;
    private Integer maxLine = 10;

    private static Map<String, String> paymentTermsMap = new Map<String, String> {
        'Z001' => '预收款/预付款',
        'Z002' => '立即付款',
        'Z003' => '月结30天内付款',
        'Z004' => '月结60天内付款',
        'Z005' => '月结90天内付款',
        'Z006' => '月结120天内付款',
        'Z007' => '月结25天内付款',
        'Z008' => '月结55天内付款',
        'Z009' => '月结85天内付款',
        'Z010' => '月结115天内付款',
        'Z011' => '月结175天内付款',
        'Z012' => '月结205天内付款',
        'Z013' => '半月结，15日之前发货，当月15日到期',
        'Z014' => '月结30天内付款',
        'Z015' => '验收后15天电汇',
        'Z020' => '100%发货后30天内支付',
        'Z021' => '100%发货后60天内电汇支付',
        'Z030' => '收到发票后30天内电汇',
        'Z045' => '月结45天内付款',
        'Z060' => '收到发票后60天内电汇',
        'Z075' => '收到发票后75天内电汇',
        'Z090' => '收到发票后90天内电汇',
        'Z0LC' => '100% L/C (90/10)',
        'Z120' => '收到发票后120天内电汇',
        'Z1LC' => '100% L/C (80/20)',
        'Z1TT' => '90%TT ADV，10%TT AFTER',
        'Z2LC' => '100% L/C (70/30)',
        'Z2TT' => '80%TT ADV，20%TT AFTER',
        'Z30E' => '下月末',
        'Z3LC' => '100% L/C 90 days',
        'Z3TT' => '70%TT ADV，30%TT AFTER',
        'Z4LC' => '90%L/CTransfer 10%TT AFTER',
        'Z4TT' => '100% TT AFTER',
        'Z5LC' => '100%L/C at sight Transfer',
        'Z5TT' => '30% TT ADV，50% TT AT SIGHT，20% TT AFTER',
        'Z60E' => '下2个月末',
        'Z6LC' => '100%L/C (85/15)',
        'Z6TT' => '30% TT ADV，60% TT AT SIGHT，10% TT AFTER',
        'Z7LC' => '100% L/C (60/40)',
        'Z7TT' => '100％TT AFTER(80/20)',
        'Z8TT' => '100% TT AFTER（70/30）',
        'Z9TT' => '100%TT发货后20天内支付',
        'ZCOD' => 'C.O.D.',
        'ZD60' => '立即应付的 到期净值',
        'ZFR1' => '半月结，15日之前发货，当月15日到期',
        'ZL6T' => '90% LC 60 days，10% TT AFTER',
        'ZL95' => '95% L/C AFTER,5% L/C AFTER 6M FROM ACCEPTANCE DATE',
        'ZLC1' => '100% L/C (90/10) Transfer',
        'ZLC2' => '100% L/C AT SIGHT (95/5)',
        'ZLT1' => '90%LC，10%TT',
        'ZLT2' => '80%LC，20%TT',
        'ZLT3' => '70%LC，30%TT',
        'ZLT4' => '95%LC，5%TT',
        'ZLT5' => '50%L/C，50%TT after',
        'ZT20' => '20% T/T ADV,80% T/T AFTER',
        'ZT30' => '30% T/T ADV, 70%T/T AFTER',
        'ZT35' => '35% TT ADV，65% TT AFTER',
        'ZT40' => '40% TT ADV，60% TT AFTER',
        'ZT50' => '50% TT ADV，50% TT AFTER',
        'ZT55' => '95%TT ADV，5%TT AFTER',
        'ZT90' => '验收合格后T/T支付90%，设备正常运行三个月T/T支付10%',
        'ZTT1' => 'TT AFTER DELIVERY 45 DAY',
        'ZTT2' => 'TT AFTER DELIVERY 120 DAY',
        'ZTT3' => '100%TT发货后15个工作日内支付',
        'ZTT4' => '验收合格后T/T支付80%，设备正常运行三个月T/T支付20%',
        'ZZ60' => '60 DAYS AFTER ISSUING INVOICE',
        'ZZ95' => '95% L/C AFTER,5% T/T AFTER 6M FROM ACCEPTANCE DATE',
        'ZZLC' => '100% L/C AT SIGHT',
        'ZZTT' => '100% TT IN ADVANCE'
    };

    public String staticResourceOpportunity{get; private set; }// 20220221 PI改造 by Bright
    public String staticResourceContact{get; private set; }// 20220221 PI改造 by Bright
    public String staticResourceFile{get; private set; }// 20220221 PI改造 by Bright
    

    public QuotePDFController() {
        targetId = ApexPages.currentPage().getParameters().get('Id');
        isPrintPrice = ApexPages.currentPage().getParameters().get('printprice');
        staticResourceOpportunity = JSON.serialize(PIHelper.getPIIntegrationInfo('Opportunity'));// 20220221 PI改造 by Bright
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));// 20220221 PI改造 by Bright
        staticResourceFile = JSON.serialize(PIHelper.getPIIntegrationInfo('Document'));// 20220221 PI改造 by Bright
    }

    // 画面初始化
    public PageReference init() {
        if (targetId == null || targetId.length() == 0) {
            return null;
        }

        is_hidden_user = false;
        // String profileId = UserInfo.getProfileId();

        //新的获取简档ID  calendarUtil.getMemberProfileID  这里用到的人员ID 和获取到的简档ID都是15位的
        String new_profileId = calendarUtil.getMemberProfileID(UserInfo.getUserId().subString(0,15));
        
        // profileId = profileId.substring(0, 15);
        if (new_profileId.substring(0, 15) == System.Label.RT_BS_No_Price) {
            is_hidden_user = true;
        }
        is_dealer_user = false;
        if (UserInfo.getUserType() == 'PowerPartner') {
            is_dealer_user = true;
        }

        // 报价信息
        List<Quote> quoList = [select Id, Name, CreatedDate, OpportunityId, Opportunity.Dealer__c, Opportunity.DealerSalesStaffName__c, AccountId, PrintPrice__c, TotalPrice,
                                      DeliveryLeadTime__c, PaymentTerms__c, ExpirationDate, Warranty__c, Opportunity.TradeType__c, Opportunity.CurrencyIsoCode, Comment__c,
                                      SetName1__c, SetQty1__c, SetName2__c, SetQty2__c, SetName3__c, SetQty3__c, SetName4__c, SetQty4__c, SetName5__c, SetQty5__c,
                                      SetName6__c, SetQty6__c, SetName7__c, SetQty7__c, SetName8__c, SetQty8__c, SetName9__c, SetQty9__c, SetName10__c, SetQty10__c,
                                      SetName11__c, SetQty11__c, SetName12__c, SetQty12__c, SetName13__c, SetQty13__c, SetName14__c, SetQty14__c, SetName15__c, SetQty15__c,
                                      SetName16__c, SetQty16__c, SetName17__c, SetQty17__c, SetName18__c, SetQty18__c, SetName19__c, SetQty19__c, SetName20__c, SetQty20__c,
                                      SetName21__c, SetQty21__c, SetName22__c, SetQty22__c, SetName23__c, SetQty23__c, SetName24__c, SetQty24__c, SetName25__c, SetQty25__c,
                                      SetName26__c, SetQty26__c, SetName27__c, SetQty27__c, SetName28__c, SetQty28__c, SetName29__c, SetQty29__c, SetName30__c, SetQty30__c,
                                      Opportunity.AWS_Data_Id__c,// 20220221 PI改造 by Bright
                                      Custom_Price_Total__c, Custom_Price_Total_Text__c, Shipment_Term__c
                                 from Quote
                                where Id = :targetId];
        Quote quo = new Quote();
        if (quoList.size() > 0) {
            quo = quoList[0];
        } else {
            return null;
        }
        // 币种
        currencyIsoCode = quo.Opportunity.CurrencyIsoCode;
        // 代理商信息
        List<Account> dealerList = [select Id, Name, Address1__c, Phone, Fax
                                      from Account
                                     where Id = :quo.Opportunity.Dealer__c];
        Account dealer = new Account();
        if (dealerList.size() > 0) {
            dealer = dealerList[0];
        }
        // 询价联系人信息
        List<OpportunityContactRole> ocrList = [select Id, OpportunityId, IsPrimary, ContactId
                                                  from OpportunityContactRole
                                                 where OpportunityId = :quo.OpportunityId 
                                                 order by IsPrimary];
        String conid = null;
        if (ocrList.size() > 0) {
            conid = ocrList[0].ContactId;
        }
        for (OpportunityContactRole ocr : ocrList) {
            if (ocr.IsPrimary == true) {
                conid = ocr.ContactId;
                break;
            }
        }
        Contact con = new Contact();
        if (conid != null && conid.length() > 0) {
            con = [select Id, Name, Phone, Email, 
            AWS_Data_Id__c,// 20220221 PI改造 by Bright
            Account.Name from Contact where Id = :conid];
        }
        // PDF报价信息
        quoteInfo = new QuoteInfo(quo, dealer, con);
        // 报价产品信息
        List<QuoteLineItem> qliList = [select Id, QuoteId, Quantity, UnitPrice, Subtotal, Description, Set__c, TotalPrice,
                                              Product2Id, Product2.ProductCode, Product2.Description, Custom_Price__c, PricebookEntry.Hidden_flag__c,
                                              Product2.Product_ECCode__c
                                         from QuoteLineItem
                                        where QuoteId = :targetId
                                        order by Set__c, LineNumber];

        pageCnt = 1;
        printRecords = new List<SetInfo>();
        String strSetCnt = System.Label.QuoteEntryMaxSet;
        Integer intSetCnt = Integer.valueOf(strSetCnt);
        Integer cnt = 1;
        for (Integer i = 1; i <= intSetCnt; i++) {
            String sName = (String) quo.get('SetName' + i + '__c');
            if (sName != null && sName.length() > 0) {
                String setName = 'set' + (i < 10 ? '0' : '') + i;
                SetInfo si = new SetInfo(cnt, setName, quo, qliList, isPrintPrice, is_hidden_user, is_dealer_user);
                printRecords.add(si);
                pageCnt += si.pCnt;
                cnt += 1;
            }
        }
        system.debug('=====pageCnt:' + pageCnt);

        return null;
    }

    // PDF主信息
    public class QuoteInfo {
        public boolean printPrice {get; private set;}

        public String quoteDate {get; private set;}
        public String quoteNo {get; private set;}

        public String dealerName {get; private set;}
        public String dealerContactName {get; private set;}
        public String dealerContactPhone {get; private set;}
        public String dealerAddress {get; private set;}
        public String dealerPhone {get; private set;}
        public String dealerFax {get; private set;}
        public String dealerEmail {get; private set;}

        public String accountName {get; private set;}
        public String accountContactName {get; private set;}
        public String accountContactPhone {get; private set;}
        public String accountContactEmail {get; private set;}

        public String comment {get; private set;}

        public String note1 {get; private set;}
        public String note2 {get; private set;}
        public String note3 {get; private set;}
        public String note4 {get; private set;}
        public String note5 {get; private set;}
        public String note6 {get; private set;}
        public String note7 {get; private set;}
        public String conAwsDataId {get; private set;}
        public String oppAwsDataId {get; private set;}

        public QuoteInfo(Quote quo, Account acc, Contact con) {
            printPrice = quo.PrintPrice__c;

            Datetime cDate = quo.CreatedDate;
            quoteDate = cDate.format('yyyy-MM-dd');
            quoteNo = quo.Name;

            dealerName = acc.Name;
            dealerContactName = quo.Opportunity.DealerSalesStaffName__c;
            dealerContactPhone = '';
            dealerAddress = acc.Address1__c;
            dealerPhone = acc.Phone;
            dealerFax = acc.Fax;
            dealerEmail = '';

            accountName = con.Account.Name;
            accountContactName = con.Name;
            accountContactPhone = con.Phone;
            accountContactEmail = con.Email;

            String temp = quo.Comment__c;
            if (temp != null) {
                temp = temp.replace('\n', '<br/>');
            }
            comment = temp;

            note1 = paymentTermsMap.get(quo.PaymentTerms__c);
            note2 = paymentTermsMap.get(quo.PaymentTerms__c);
            Date n3 = quo.ExpirationDate;
            note3 = n3 == null ? '-' : DateTime.newInstance(n3, Time.newInstance(0, 0, 0, 0)).format('MMMM,dd,yyyy');
            Decimal n4 = quo.Warranty__c;
            note4 = n4 == null ? '0' : n4.format();
            note5 = quo.Shipment_Term__c;
            note6 = quo.Opportunity.TradeType__c == 'Taxation' ? 'tax included' : 'tax exempted';
            note7 = quo.Opportunity.TradeType__c == 'Taxation' ? '含税' : '免税';
            conAwsDataId = con.aws_data_id__c; // 20220222 PI改造 by Bright
            oppAwsDataId = quo.Opportunity.aws_data_id__c;// 20220222 PI改造 by Bright
        }
    }

    public class SetInfo {
        private Integer maxLine = 36;

        public String units {get; private set;}
        public String description {get; private set;}
        public Integer qty {get; private set;}
        public Decimal total {get; private set;}
        public List<List<LineInfo>> setPage {get; private set;}
        public Integer pCnt {get; private set;}

        public SetInfo(Integer no, String setName, Quote info, List<QuoteLineItem> qliList, String isPrintPrice, boolean is_hidden_user, boolean is_dealer_user) {
            units = String.valueOf(no);
            String fieldName = setName.substring(3);
            fieldName = fieldName.indexOf('0') == 0 ? fieldName.substring(1) : fieldName;
            description = (String) info.get('SetName' + fieldName + '__c');
            Decimal d_qty = (Decimal) info.get('SetQty' + fieldName + '__c');
            qty = d_qty == null ? 1 : d_qty.intValue();
            total = 0;

            setPage = new List<List<LineInfo>>();
            pCnt = 0;
            Integer i = 0;
            Integer tmp = 0;
            List<LineInfo> sPage = new List<LineInfo>();
            for (QuoteLineItem qli : qliList) {
                if (qli.Set__c == setName) {
                    i += 1;
                    LineInfo line = new LineInfo(i, qli, qty, info.PrintPrice__c);
                    //LineInfo line = new LineInfo(i, qli, 1, isPrintPrice=='true');
                    if (tmp + line.lineCost <= maxLine && i > 1) {
                        sPage.add(line);
                        tmp += line.lineCost;
                    } else {
                        system.debug('====set new page,tmp:' + tmp + '_cost:' + line.lineCost);
                        sPage = new List<LineInfo>();
                        setPage.add(sPage);
                        sPage.add(line);
                        tmp = line.lineCost;
                        pCnt += 1;
                    }
                    total += line.totalPrice * qty;

                    if (is_hidden_user == true || is_dealer_user == true && qli.PricebookEntry.Hidden_flag__c == true) {
                        line.price = 0;
                        line.subTotal = 0;
                        line.totalPrice = 0;
                    }
                }
            }
            system.debug('=====pCnt:' + pCnt);
        }
    }

    // PDF明细行信息
    public class LineInfo {
        private Integer codeBreak = 10;
        private Integer descriptionBreak = 9;
        private Integer commentBreak = 9;

        public Integer lineCost {get; private set;}
        public QuoteLineItem qli {get; private set;}

        public Integer lineNo {get; private set;}
        public String productCode {get; private set;}
        public String productEC {get; private set;}
        public String description {get; private set;}
        public String comment {get; private set;}
        public Integer quantity {get; private set;}
        public Decimal price {get; private set;}
        public Decimal subTotal {get; private set;}
        public Decimal totalPrice {get; private set;}

        public Integer pageqty {get; private set;}

        public LineInfo(Integer i, QuoteLineItem info, Integer qty, boolean printPrice) {
            // 不显示价格时，每行可显示字符增加
            if (printPrice == false) {
                descriptionBreak = 15;
                commentBreak = 15;
            }
            // 计算数据所占行数
            lineCost = 1;
            productCode = info.Product2.ProductCode;
            if (productCode.startsWith('00000000000')) {
                productCode = productCode.substring(11);
            }
            productEC = info.Product2.Product_ECCode__c;
            Integer cost1 = productCode == null ? 1 : Math.mod(productCode.length(), codeBreak) == 0 ? productCode.length() / codeBreak : productCode.length() / codeBreak + 1;
            if (lineCost < cost1) {
                lineCost = cost1;
            }
            description = info.product2.Description;
            Integer cost2 = description == null ? 1 : Math.mod(description.length(), descriptionBreak) == 0 ? description.length() / descriptionBreak : description.length() / descriptionBreak + 1;
            if (lineCost < cost2) {
                lineCost = cost2;
            }
            comment = info.Description;
            Integer cost3 = comment == null ? 1 : Math.mod(comment.length(), commentBreak) == 0 ? comment.length() / commentBreak : comment.length() / commentBreak + 1;
            if (lineCost < cost3) {
                lineCost = cost3;
            }
            // 项目赋值
            qli = info;
            lineNo = i;
            //productCode = setBr(productCode, codeBreak);
            description = setBr(description, descriptionBreak);
            comment = setBr(comment, commentBreak);
            Decimal d_quantity = info.Quantity / qty;
            quantity = d_quantity.intValue();
            price = info.Custom_Price__c == null ? 0 : info.Custom_Price__c / qty / quantity;
            price = price.setScale(2, System.RoundingMode.HALF_UP);
            subTotal = info.Custom_Price__c == null ? 0 : info.Custom_Price__c / qty;
            subTotal = subTotal.setScale(2, System.RoundingMode.HALF_UP);
            totalPrice = info.Custom_Price__c == null ? 0 : info.Custom_Price__c / qty;
            totalPrice = totalPrice.setScale(2, System.RoundingMode.HALF_UP);

            pageqty = qty;
        }

        // 手动换行
        private String setBr(String orgstr, Integer breakcnt) {
            String tmp = '';
            if (orgstr == null) {
                orgstr = '';
            }
            for (Integer i = 0; i < orgstr.length() / breakcnt + 1; i++) {
                if (i == orgstr.length() / breakcnt) {
                    tmp += orgstr.substring(i * breakcnt);
                } else {
                    tmp += orgstr.substring(i * breakcnt, (i + 1) * breakcnt) + '<br/>';
                }
            }
            return tmp;
        }
    }
}