package com.knecon.fforesight.service.layoutparser.processor.services.classification;

import org.springframework.stereotype.Service;

import com.knecon.fforesight.service.layoutparser.processor.model.AbstractPageBlock;
import com.knecon.fforesight.service.layoutparser.processor.model.ClassificationDocument;
import com.knecon.fforesight.service.layoutparser.processor.model.ClassificationPage;
import com.knecon.fforesight.service.layoutparser.processor.model.PageBlockType;
import com.knecon.fforesight.service.layoutparser.processor.model.text.TextPageBlock;
import com.knecon.fforesight.service.layoutparser.processor.utils.MarkedContentUtils;
import com.knecon.fforesight.service.layoutparser.processor.utils.PositionUtils;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;

@Service
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class HeaderFooterClassificationService {

    public void classifyHeadersAndFooters(ClassificationDocument document) {

        for (ClassificationPage page : document.getPages()) {
            for (AbstractPageBlock pageBlock : page.getTextBlocks()) {
                if (pageBlock instanceof TextPageBlock textBlock) {
                    classifyBlock(document, page, textBlock);
                }
            }
        }

    }


    private static void classifyBlock(ClassificationDocument document, ClassificationPage page, TextPageBlock textBlock) {

        if (MarkedContentUtils.intersects(textBlock, page.getMarkedContentBboxPerType(), MarkedContentUtils.HEADER)
            || PositionUtils.isOverBodyTextFrame(page.getBodyTextFrame(), textBlock, page.getRotation()) && smallerFontThanDocAverage(document, textBlock)) {

            textBlock.setClassification(PageBlockType.HEADER);

        } else if (MarkedContentUtils.intersects(textBlock, page.getMarkedContentBboxPerType(), MarkedContentUtils.FOOTER)
                   || PositionUtils.isUnderBodyTextFrame(page.getBodyTextFrame(), textBlock, page.getRotation()) && smallerFontThanDocAverage(document, textBlock)) {

            textBlock.setClassification(PageBlockType.FOOTER);
        }
    }


    private static boolean smallerFontThanDocAverage(ClassificationDocument document, TextPageBlock textBlock) {

        return document.getFontSizeCounter().getMostPopular() == null || textBlock.getHighestFontSize() <= document.getFontSizeCounter().getMostPopular();
    }

}
