import React from 'react';
import PropTypes from 'prop-types';
import TimeUtil from '../../../util/TimeUtil';
import FlexPlayerUtil from '../../../util/FlexPlayerUtil';

import { VIEW_LIST, VIEW_WORDCLOUD } from '../ContentAnnotationsColumn';
import TimedList from './TimedList';
import WordCloud from './WordCloud';
import { sanitize } from '../../shared/WordCloudHelpers';
import MediaEvents from '../_MediaEvents';

/*
	This component shows Segments in a TimedList or WordCloud
*/

export default class Segments extends React.Component {
    constructor(props) {
        super(props);
    }

    /* ----------------------- RENDER LIST -------------------*/

    renderList(mediaObject, searchTerm, mediaEvents) {
        // convert segments to item list for TimedList
        const items = mediaObject.segments
            .filter(segment => !segment.programSegment)
            .sort((a, b) => a.start - b.start)
            .map((segment, index) => ({
                id: 'ca_seg_li_' + index,
                start:
                    FlexPlayerUtil.timeRelativeToOnAir(
                        segment.start,
                        mediaObject
                    ) * 1000,
                end:
                    FlexPlayerUtil.timeRelativeToOnAir(
                        segment.end,
                        mediaObject
                    ) * 1000,
                startLabel: TimeUtil.formatMillisToTime(
                    FlexPlayerUtil.timeRelativeToOnAir(
                        segment.start,
                        mediaObject
                    ) * 1000
                ).replace(/^00:/g, ''), // remove prefixed 00: hours (as most videos are < 1h)
                endLabel: TimeUtil.formatMillisToTime(
                    FlexPlayerUtil.timeRelativeToOnAir(
                        segment.end,
                        mediaObject
                    ) * 1000
                ).replace(/^00:/g, ''), // remove prefixed 00: hours (as most videos are < 1h)
                data: segment.title
            }));

        return (
            <TimedList
                items={items}
                mediaEvents={mediaEvents}
                searchTerm={searchTerm}
            />
        );
    }

    /* ----------------------- RENDER WORDCLOUD -------------------*/

    renderWordCloud(mediaObject, searchTerm, mediaEvents) {
        // prepare segments
        const segments = mediaObject.segments
            .filter(segment => !segment.programSegment)
            .sort((a, b) => a.start - b.start);

        // get raw word list from segment titles
        const words = segments.reduce(
            (w, segment) => w.concat(segment.title.split(' ')),
            []
        );

        // When click on a word, onSeek the player to the next occurence of the given word
        // Start on the start of the ASR item for context
        const onWordClick = word => {
            // get current player position
            const pos = mediaEvents.getData(MediaEvents.PLAYER_POS);

            // get next occurence
            let hit = null;
            segments.some(segment => {
                const segmentStart = FlexPlayerUtil.timeRelativeToOnAir(
                    segment.start,
                    mediaObject
                );
                // if segment in the future, or no first hit
                if (segmentStart > pos || hit == null) {
                    // sanitize the words
                    const words = sanitize(segment.title);
                    word = word.replace('_', ' ');

                    // if word exists
                    if (words.indexOf(word) !== -1) {
                        // store first hit
                        if (!hit) {
                            hit = segment;
                        }
                        // if future hit, store and return
                        if (segmentStart > pos) {
                            hit = segment;
                            return true;
                        }
                    }
                }
                return false;
            });

            // check if an item was hit
            if (hit != null) {
                // Update player by triggering SET_PLAYER_POS event
                this.props.mediaEvents.trigger(
                    MediaEvents.SET_PLAYER_POS,
                    FlexPlayerUtil.timeRelativeToOnAir(hit.start, mediaObject)
                );
            }
        };

        return (
            <WordCloud
                words={words}
                mediaEvents={mediaEvents}
                size={100}
                searchTerm={searchTerm}
                onClick={onWordClick}
            />
        );
    }

    /* ----------------------- RENDER -------------------*/

    render = () => {
        const mediaObject = this.props.activeMediaObject;

        if (!mediaObject || !mediaObject.segments) {
            return null;
        }

        switch (this.props.view) {
            case VIEW_LIST:
                return this.renderList(
                    mediaObject,
                    this.props.searchTerm,
                    this.props.mediaEvents
                );
            case VIEW_WORDCLOUD:
                return this.renderWordCloud(
                    mediaObject,
                    this.props.searchTerm,
                    this.props.mediaEvents
                );
            default:
                return null;
        }
    };
}

Segments.propTypes = {
    searchTerm: PropTypes.string.isRequired,
    view: PropTypes.string.isRequired,
    activeMediaObject: PropTypes.object.isRequired,
    mediaEvents: PropTypes.object.isRequired
};
