module IdCardPrinterService
    class CardsGenerator

        def initialize(employers_member_keys, layout, zip=false)
            @employers_member_keys = Array.wrap(employers_member_keys)
            @layout = layout
            @zip = zip
        end

        def call
            pl_plan_keys = @employers_member_keys.map { |emk| emk[:pl_plan_key] }
            IdCard::PrintData.where(pl_plan_key: pl_plan_keys).destroy_all
            IdCardPrinterService::CardDataFormatter.new(@employers_member_keys).call

            IdCard::PrintData.where(pl_plan_key: pl_plan_keys, primary_mb_member_key: nil).destroy_all

            pdf_array = []
            template_groups = break_up_by_template(pl_plan_keys)
            template_groups.each do |card_template, template_pl_plan_keys|
                batch = IdCard::PrintData.where(pl_plan_key: template_pl_plan_keys)
                jasper_batch_id = "#{template_pl_plan_keys.join('_')}-#{Time.current.utc.to_i}"
                batch.update!(jasper_batch_id: jasper_batch_id)
                if @layout == "PrintCard"
                    add_dependent_cards(batch)
                end
                batch_pdf = IdCardPrinterService::PdfBatchProcessor.new(card_template, jasper_batch_id, @layout).call
                pdf_array << batch_pdf
            end

            group_pdfs = combine_pdfs(pdf_array)
            group_pdfs

        end

        private

        def break_up_by_template(pl_plan_keys)
            batches_by_card_template = IdCard::Setup.where(pl_plan_key: pl_plan_keys).group_by(&:card_template)
                .transform_values { |setups| setups.map(&:pl_plan_key) }
                .compact_blank
        end

        def add_dependent_cards(batch)
            batch.where.not(dependent_1: [nil, ""]).find_each do |member_card|
                dependent_card = member_card.dup
                dependent_card.update(
                    full_name_last_name_first: member_card.full_name_last_name_first.concat(" dependent")
                )
                dependent_card.save
            end
        end

        def combine_pdfs(pdf_array)
            if @zip
                group_cards_pdf = Zip::OutputStream.write_buffer do |zio|
                    pdf_file = pdf_array.first
                    puts "-- CombinePdfPages --"
                    puts pdf_file.pages.count
                    pdf_file.pages.reverse.each do |page|
                        page_pdf = CombinePDF.new
                        page_pdf << page
                        page_data = page_pdf.to_pdf
                        full_name_last_name_first = get_watermark_field(page_data)
                        if full_name_last_name_first.present?
                            page_filename = "#{full_name_last_name_first.gsub(", ", "_")}_digital_card_#{Date.today}.pdf"
                            puts "-- Filename --"
                            puts page_filename
                            zio.put_next_entry(page_filename)
                            zio.write(page_data)
                        end
                    end
                end
            else
                group_cards_pdf = CombinePDF.new
                pdf_array.each { |pdf| group_cards_pdf << pdf }
            end
            group_cards_pdf
        end

        def get_watermark_field(page_data)
            watermark_field = ""
            reader = PDF::Reader.new(StringIO.new(page_data))
            puts "-- ReaderPages --"
            puts reader.pages.count
            page = reader.pages.first
            if watermark_match = page.text.match(/:WATERMARK:([^:]*):/)
                watermark_field = page.text.match(/:WATERMARK:([^:]*):/)[1].strip
            else
                puts "blank page"
            end
            watermark_field
        end
    end
end
