package com.knecon.fforesight.service.layoutparser.processor.model.outline;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.iqser.red.service.redaction.v1.server.model.document.nodes.GenericSemanticNode;
import com.knecon.fforesight.service.layoutparser.processor.model.AbstractPageBlock;
import com.knecon.fforesight.service.layoutparser.processor.model.PageBlockType;
import com.knecon.fforesight.service.layoutparser.processor.model.image.ClassifiedImage;
import com.knecon.fforesight.service.layoutparser.processor.model.text.TextPageBlock;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class SectionTreeEntry {

    public enum Type {
        SECTION,
        SUPER_SECTION,
        TOC_SECTION
    }

    @EqualsAndHashCode.Include
    private TextPageBlock headline;
    private List<SectionTreeEntry> children = new ArrayList<>();
    private SectionTreeEntry parent;

    private List<AbstractPageBlock> sectionBlocks = new ArrayList<>();
    private List<ClassifiedImage> images = new ArrayList<>();

    private GenericSemanticNode section;


    public SectionTreeEntry(TextPageBlock headline) {

        this.headline = headline;
    }


    public Type getType() {

        if (!Objects.isNull(headline) && headline.getClassification().equals(PageBlockType.TABLE_OF_CONTENTS_HEADLINE)) {
            return Type.TOC_SECTION;
        }
        if (children.isEmpty()) {
            return Type.SECTION;
        }
        return Type.SUPER_SECTION;
    }


    public void addChild(SectionTreeEntry sectionTreeEntry) {

        children.add(sectionTreeEntry);
        sectionTreeEntry.setParent(this);
    }


    public SectionTreeEntry getSiblingBefore() {

        if (parent != null) {
            int index = parent.getChildren().indexOf(this);
            if (index > 0) {
                return parent.getChildren().get(index - 1);
            }
        }
        return null;
    }


    public SectionTreeEntry getSiblingAfter() {

        if (parent != null) {
            int index = parent.getChildren().indexOf(this);
            if (index >= 0 && index < parent.getChildren().size() - 1) {
                return parent.getChildren().get(index + 1);
            }
        }
        return null;
    }


    public boolean contains(TextPageBlock block) {

        if (headline.equals(block)) {
            return true;
        }
        for (SectionTreeEntry child : children) {
            if (child.contains(block)) {
                return true;
            }
        }
        return false;
    }


    public boolean contains(SectionTreeEntry tocItem) {

        if (this.equals(tocItem)) {
            return true;
        }
        for (SectionTreeEntry child : children) {
            if (child.contains(tocItem)) {
                return true;
            }
        }
        return false;
    }


    public List<AbstractPageBlock> getNonEmptySectionBlocks() {

        return sectionBlocks.stream()
                .filter(pageBlock -> !pageBlock.isEmpty())
                .collect(Collectors.toList());
    }


    @Override
    public String toString() {

        return "OutlineObjectTreeNode{" + "textPageBlock=" + headline + '}';
    }

}
