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

import java.util.List;
import java.util.regex.Pattern;

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.PositionUtils;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class ClarifyndClassificationService {

    public void classifyDocument(ClassificationDocument document) {

        List<Double> headlineFontSizes = document.getFontSizeCounter().getValuesInReverseOrder();

        log.debug("Document FontSize counters are: {}", document.getFontSizeCounter().getCountPerValue());

        HeadlineClassificationService headlineClassificationService = new HeadlineClassificationService();

        for (ClassificationPage page : document.getPages()) {
            classifyPage(headlineClassificationService, page, document, headlineFontSizes);
        }
    }


    private void classifyPage(HeadlineClassificationService headlineClassificationService,
                              ClassificationPage page,
                              ClassificationDocument document,
                              List<Double> headlineFontSizes) {

        for (AbstractPageBlock textBlock : page.getTextBlocks()) {
            if (textBlock instanceof TextPageBlock) {
                classifyBlock(headlineClassificationService, (TextPageBlock) textBlock, page, document, headlineFontSizes);
            }
        }
    }


    private void classifyBlock(HeadlineClassificationService headlineClassificationService,
                               TextPageBlock textBlock,
                               ClassificationPage page,
                               ClassificationDocument document,
                               List<Double> headlineFontSizes) {

        var bodyTextFrame = page.getBodyTextFrame();

        if (textBlock.getClassification() != null && textBlock.getClassification().isHeadline()) {
            headlineClassificationService.setLastHeadlineFromOutline(textBlock);
            return;
        }
        if (textBlock.getClassification() != null && (textBlock.getClassification().equals(PageBlockType.HEADER)
                                                      || textBlock.getClassification().equals(PageBlockType.FOOTER)
                                                      || textBlock.getClassification().equals(PageBlockType.TABLE_OF_CONTENTS_ITEM))) {
            return;
        }
        if (document.getFontSizeCounter().getMostPopular() == null) {
            textBlock.setClassification(PageBlockType.PARAGRAPH);
            return;
        }
        if (page.getPageNumber() == 1 //
            && (PositionUtils.getHeightDifferenceBetweenChunkWordAndDocumentWord(textBlock, document.getTextHeightCounter().getMostPopular()) > 2.5
                && textBlock.getHighestFontSize() > document.getFontSizeCounter().getMostPopular() || page.getTextBlocks().size() == 1)) {
            if (!Pattern.matches("[0-9]+", textBlock.toString())) {
                PageBlockType headlineType = HeadlineClassificationService.headlineClassByFontSize(textBlock, headlineFontSizes);
                headlineClassificationService.classifyHeadline(textBlock, headlineType);
                document.setHeadlines(true);
            }
        } else if (textBlock.getMostPopularWordFontSize() > document.getFontSizeCounter().getMostPopular()
                   && PositionUtils.getApproxLineCount(textBlock) < 4.9
                   && (textBlock.getMostPopularWordStyle().equals("bold")
                       || !document.getFontStyleCounter().getCountPerValue().containsKey("bold")
                          && textBlock.getMostPopularWordFontSize() > document.getFontSizeCounter().getMostPopular() + 1)
                   && textBlock.getWords().get(0).getFontSize()>= textBlock.getMostPopularWordFontSize()) {

            PageBlockType headlineType = HeadlineClassificationService.headlineClassByFontSize(textBlock, headlineFontSizes);
            headlineClassificationService.classifyHeadline(textBlock, headlineType);
            document.setHeadlines(true);
        } else if (!textBlock.getText().startsWith("Figure ")
                   && PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock)
                   && textBlock.getMostPopularWordStyle().equals("bold")
                   && !document.getFontStyleCounter().getMostPopular().equals("bold")
                   && PositionUtils.getApproxLineCount(textBlock) < 2.9
                   && textBlock.getWords().get(0).getFontSize() >= textBlock.getMostPopularWordFontSize()) {

            PageBlockType headlineType = HeadlineClassificationService.headlineClassByFontSize(textBlock, headlineFontSizes);
            headlineClassificationService.classifyHeadline(textBlock, headlineType);
            document.setHeadlines(true);
        } else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock)
                   && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter().getMostPopular()
                   && textBlock.getMostPopularWordStyle().equals("bold")
                   && !document.getFontStyleCounter().getMostPopular().equals("bold")) {
            textBlock.setClassification(PageBlockType.PARAGRAPH_BOLD);
        } else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock)
                   && textBlock.getMostPopularWordFont().equals(document.getFontCounter().getMostPopular())
                   && textBlock.getMostPopularWordStyle().equals(document.getFontStyleCounter().getMostPopular())
                   && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter().getMostPopular()) {
            textBlock.setClassification(PageBlockType.PARAGRAPH);
        } else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock)
                   && textBlock.getMostPopularWordFontSize() == document.getFontSizeCounter().getMostPopular()
                   && textBlock.getMostPopularWordStyle().equals("italic")
                   && !document.getFontStyleCounter().getMostPopular().equals("italic")
                   && PositionUtils.getApproxLineCount(textBlock) < 2.9) {
            textBlock.setClassification(PageBlockType.PARAGRAPH_ITALIC);
        } else if (PositionUtils.isWithinBodyTextFrame(bodyTextFrame, textBlock)) {
            textBlock.setClassification(PageBlockType.PARAGRAPH_UNKNOWN);
        } else {
            textBlock.setClassification(PageBlockType.PARAGRAPH);
        }
    }

}

