import React from 'react';
import AssetButtons from './asset-buttons';

import { RouteComponentProps } from 'react-router-dom';
import { PlaybackType, DrmType, PlayoutRequestData, PlayerState } from '@sky-uk-ott/client-lib-js-player-addons-common-player';
import { PlayerFramework } from '@sky-uk-ott/client-lib-js-ctv-framework-main';

type URLParams = { [key: string]: string };

type PlayerComponentState = {
    manifestUri: string;
    licensingUri?: string;
    deviceId?: string;
    drmType?: string;
    streamType?: string;
    ready: boolean;
};

const videoElementClassName = 'video-player';

const DRMTypes = {
    PlayReady: DrmType.PlayReady,
    Widevine: DrmType.Widewine,
    VGC: DrmType.VGC,
};

export default class Player extends React.Component<RouteComponentProps, PlayerComponentState> {
    public state = {
        ready: false,
    } as PlayerComponentState;

    public videoWrapperElement: HTMLElement;

    public componentDidMount() {
        const params = this.getQSParameters(this.props.location);
        this.setState({
            manifestUri: params.manifestUri || '',
            licensingUri: params.licensingUri || '',
            deviceId: params.deviceId || '',
            drmType: params.drmType || '',
            streamType: params.streamType || '',
        });
    }

    public render() {
        return (
            <div>
                <AssetButtons
                    history={history}
                    onUriSelection={this.handleUriSelection}
                    licensingUri={this.state.licensingUri || ''}
                    drmType={this.state.drmType || ''}
                    streamType={this.state.streamType || ''}
                    onUpdateManifestUri={this.handleUpdateManifestUri}
                    onUpdateLicensingUri={this.handleUpdateLicensingUri}
                    onUpdateDeviceId={this.handleUpdateDeviceId}
                    onUpdateDRMType={this.handleUpdateDRMType}
                    onUpdateStreamType={this.handleUpdateStreamType}
                    deviceId={this.state.deviceId}
                    manifestUri={this.state.manifestUri}
                    onLoadPlayer={this.handleLoadPlayer}
                />
                <div style={{ margin: '20px' }}>
                    <figure
                        style={{ margin: '0 auto' }}
                        ref={element => {
                            this.videoWrapperElement = element;
                        }}
                        id="videoContainer"
                        data-fullscreen="false"
                    />
                    {!this.state.manifestUri && (
                        <div style={{ marginTop: '10px' }} className="alert alert-danger" role="alert">
                            Please provide at least a Manifest Uri
                        </div>
                    )}
                </div>
            </div>
        );
    }
    private getQSParameters = (location): URLParams => {
        const manifestUriRegex = /manifestUri=([^&]*)/;
        const licensingUriRegex = /licensingUri=([^&]*)/;
        const deviceIdUriRegex = /deviceId=([^&]*)/;
        const drmTypeUriRegex = /drmType=([^&]*)/;
        const streamTypeUriRegex = /streamType=([^&]*)/;

        const queryString = location.search;
        const manifestUri = queryString.match(manifestUriRegex) ? queryString.match(manifestUriRegex)[1] : '';
        const licensingUri = queryString.match(licensingUriRegex) ? queryString.match(licensingUriRegex)[1] : '';
        const deviceId = queryString.match(deviceIdUriRegex) ? queryString.match(deviceIdUriRegex)[1] : '';
        const drmType = queryString.match(drmTypeUriRegex) ? queryString.match(drmTypeUriRegex)[1] : '';
        const streamType = queryString.match(streamTypeUriRegex) ? queryString.match(streamTypeUriRegex)[1] : '';
        return { manifestUri, licensingUri, deviceId, drmType, streamType };
    };

    private handleUriSelection = (_assetUrl: string, _licensingUrl: string) => {
        this.setState({ manifestUri: _assetUrl, licensingUri: _licensingUrl });
    };

    private handleUpdateManifestUri = (_manifestUri: string) => {
        this.setState({ manifestUri: _manifestUri }, this.handleUpdateQS);
    };

    private handleUpdateLicensingUri = (_licensingUri: string) => {
        this.setState({ licensingUri: _licensingUri }, this.handleUpdateQS);
    };

    private handleUpdateDeviceId = (_deviceId: string) => {
        this.setState({ deviceId: _deviceId }, this.handleUpdateQS);
    };

    private handleUpdateDRMType = (_drmType: string) => {
        this.setState({ drmType: _drmType }, this.handleUpdateQS);
    };

    private handleUpdateStreamType = (_streamType: string) => {
        this.setState({ streamType: _streamType }, this.handleUpdateQS);
    };

    private handleUpdateQS = () => {
        let search = `?manifestUri=${this.state.manifestUri}`;
        if (this.state.licensingUri) {
            search += `&licensingUri=${this.state.licensingUri}`;
        }
        if (this.state.deviceId) {
            search += `&deviceId=${this.state.deviceId}`;
        }
        if (this.state.drmType) {
            search += `&drmType=${this.state.drmType}`;
        }
        if (this.state.streamType) {
            search += `&streamType=${this.state.streamType}`;
        }
        this.props.history.replace(`${this.props.location.pathname}${search}`);
    };

    private handleLoadPlayer = async () => {
        if (PlayerFramework.player.currentState === PlayerState.Playing) {
            await PlayerFramework.player.endSession();
        }
        const playbackType = PlaybackType[this.state.streamType || 'Vod'];
        const playoutData: PlayoutRequestData = {
            type: playbackType,
            cdns: [
                {
                    url: this.state.manifestUri,
                    name: 'ovpDemo',
                },
            ],
            drmConfiguration: {
                licenceAcquisitionUrl: this.state.licensingUri,
                type: this.state.licensingUri && this.state.drmType ? DRMTypes[this.state.drmType] : null,
                deviceId: this.state.deviceId,
            },
            defaultAudioLanguage: 'en-US',
            position: playbackType === PlaybackType.Live ? Infinity : 0,
            autoplay: true,
            videoHTMLContainerInfo: {
                videoHTMLContainer: this.videoWrapperElement,
                videoElementClassName: videoElementClassName,
            },
        };
        await PlayerFramework.player.startSession(playoutData);
        const videoElement: HTMLVideoElement = document.getElementsByClassName(videoElementClassName)[0] as HTMLVideoElement;
        videoElement.controls = true;
    };
}
