package com.knecon.fforesight.service.layoutparser.processor.model.graph.nodes;

import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.knecon.fforesight.service.layoutparser.internal.api.data.redaction.LayoutEngine;
import com.knecon.fforesight.service.layoutparser.internal.api.data.redaction.NodeType;
import com.knecon.fforesight.service.layoutparser.processor.model.graph.DocumentTree;
import com.knecon.fforesight.service.layoutparser.processor.model.graph.entity.RedactionEntity;
import com.knecon.fforesight.service.layoutparser.processor.model.graph.textblock.TextBlock;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Data
@Builder
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Section implements GenericSemanticNode {

    @Builder.Default
    Set<LayoutEngine> engines = new HashSet<>(Set.of(LayoutEngine.ALGORITHM));
    List<Integer> treeId;

    TextBlock textBlock;
    @EqualsAndHashCode.Exclude
    DocumentTree documentTree;

    @Builder.Default
    @EqualsAndHashCode.Exclude
    Set<RedactionEntity> entities = new HashSet<>();

    @EqualsAndHashCode.Exclude
    Map<Page, Rectangle2D> bBoxCache;


    @Override
    public NodeType getType() {

        return NodeType.SECTION;
    }


    public boolean hasTables() {

        return streamAllSubNodesOfType(NodeType.TABLE).findAny()
                .isPresent();
    }


    @Override
    public TextBlock getTextBlock() {

        if (textBlock == null) {
            textBlock = GenericSemanticNode.super.getTextBlock();
        }
        return textBlock;
    }


    @Override
    public String toString() {

        return treeId.toString() + ": " + NodeType.SECTION + ": " + this.getTextBlock().buildSummary();
    }


    public Headline getHeadline() {

        return streamChildrenOfType(NodeType.HEADLINE)//
                .map(node -> (Headline) node)//
                .findFirst()//
                .orElseGet(() -> getParent().getHeadline());
    }


    @Override
    public Map<Page, Rectangle2D> getBBox() {

        if (bBoxCache == null) {
            bBoxCache = GenericSemanticNode.super.getBBox();
        }
        return bBoxCache;
    }

}
