import React from "react";
import AnnotationType from "./annotationColumn/AnnotationType";
import { MSAnnotationUtil } from "./AnnotationClient";
import { timeToString } from "./mediaColumn/timeline/_timeHelpers";
import Strings from "./_Strings";

import {
    METADATA,
    CLASSIFICATION,
    COMMENT,
    LINK,
    CUSTOM,
    SELECTION_TEMPORAL,
    SELECTION_SPATIAL,
    RESOURCE,
    MEDIAOBJECT,
    SEGMENT,
} from "../../util/AnnotationConstants";

// Render active annotations per type
export const renderPerType = (
    annotationsPerType,
    target,
    annotation,
    annotationClient,
    activeTypes,
    showForm
) => {
    // render types
    return (
        <div className="annotations">
            {activeTypes.map((type) => (
                <AnnotationType
                    key={type}
                    type={type}
                    target={target}
                    targetAnnotation={annotation}
                    annotations={annotationsPerType[type]}
                    annotationClient={annotationClient}
                    showForm={showForm}
                />
            ))}
        </div>
    );
};


// Get all annotations split by type
export const getAnnotationsPerType = (activeTypes, annotation) => {
    // annotations per Type
    const annotationsPerType = {};

    // fill with active types
    Object.values(activeTypes).forEach((type) => {
        annotationsPerType[type] = [];
    });

    // split annotations per type
    if (annotation && annotation.body) {
        annotation.body
            // remove empty bodies
            .filter((a) => a)
            // collect
            .forEach((a) => {
                // only add the annotations to active types
                if (a.annotationType in annotationsPerType) {
                    annotationsPerType[a.annotationType].push(a);
                }
            });
    }

    // render types
    return annotationsPerType;
};

// Exclude custom annotations from list
export const excludeCustomType = (annotations) =>{
    return annotations ?  annotations.filter((annotation)=>(annotation.annotationType !== CUSTOM)): [];
}

// Get full segment title
// e.g. "00:03 - 01:04 Watersnoodramp, Zeeland"
// e.g. "Watersnoodramp, Zeeland" with includeTime = false
export const getSegmentTitle = (segment, activeTypes, includeTime = true) => {
    // get segment title, and prefix a space if found
    let segmentTitle = getSegmentAnnotationsTitle(segment, activeTypes);
    segmentTitle = segmentTitle ? " " + segmentTitle : "";

    return includeTime
        ? getSelectionTitle(segment) + segmentTitle
        : segmentTitle;
};

// Get a title from segment annotations
// e.g. "Watersnoodramp, Zeeland"
export const getSegmentAnnotationsTitle = (
    segment,
    activeTypes = [METADATA, CLASSIFICATION, COMMENT, LINK]
) => {
    if (!segment.body) return "";

    let result = "";
    let rank = 0;

    const ranks = {
        [METADATA]: 4,
        [CLASSIFICATION]: 3,
        [COMMENT]: 2,
        [LINK]: 1,
    };

    // get title from
    segment.body
        // only active types, but always keep METADATA to use its title field
        .filter(
            (body) =>
                body &&
                (activeTypes.includes(body.annotationType) ||
                    body.annotationType == METADATA)
        )
        .some((body) => {
            // only add if rank is higher or if result is empty
            if (
                // lower rank
                ranks[body.annotationType] < rank ||
                // first run
                (!result && rank > 0)
            ) {
                return false;
            }

            let addition = "";
            // add correct title from each annotation type
            switch (body.annotationType) {
                case METADATA:
                    // get title index
                    let titleIndex = -1;
                    if (
                        body.properties.some((property, index) => {
                            if (property.key == "title") {
                                titleIndex = index;
                                return true;
                            }
                            return false;
                        })
                    ) {
                        if (body.properties[titleIndex].value) {
                            result = body.properties[titleIndex].value;
                            // break loop
                            return true;
                        }
                    }
                    break;
                case CLASSIFICATION:
                    addition = body.label;
                    break;
                case COMMENT:
                    addition = body.text ? body.text.slice(0, 100) : "";
                    break;
                case LINK:
                    addition = body.label;
                    break;
            }

            // add addition to result
            if (result && rank == ranks[body.annotationType]) {
                // append
                result += ", ";
                result += addition;
            } else {
                // replace
                result = addition;
            }

            rank = ranks[body.annotationType];
            return false;
        });

    // slice final result
    result = result ? result.slice(0, 100) : "";
    return result;
};

// Get Selection title
// e.g. "00:03 - 01:04"
export const getSelectionTitle = (segment) => {
    // get selection data
    const selection = MSAnnotationUtil.extractSelectionFromTarget(
        segment.target
    );
    if (!selection) {
        console.warn("Could not find selection for target", segment.target);
        return "▲ Invalid segment";
    }

    switch (selection.type) {
        case SELECTION_TEMPORAL: {
            // mm:ss or hh:mm:ss if hours > 0
            return (
                timeToString(selection.start) +
                " - " +
                timeToString(selection.end)
            );
        }
        case SELECTION_SPATIAL:
            const temp = [
                selection.rect.x,
                selection.rect.y,
                selection.rect.w,
                selection.rect.h,
            ];
            return "◰ " + temp.join(", ");
        default:
            return "";
    }
};

// Get title of given annotation
// Returns "Resource", the MediaObject source id or a segmentTitle e.g. "00:03 - 01:04 Watersnoodramp, Zeeland"
export const getAnnotationTargetTitle = (annotation) => {
    if (!annotation || !annotation.target || !annotation.target.type) {
        return "";
    }

    switch (annotation.target.type) {
        case RESOURCE:
            return Strings.ANNOTATION_TARGET_TITLE_RESOURCE;

        case MEDIAOBJECT:
            return annotation.target.source;

        case SEGMENT:
            return getSegmentTitle(annotation);

        default:
            return "Unknown annotation target";
    }
};
