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 { CommonPlayerComponent } from '@sky-uk-ott/client-lib-react-player-component';
import { Controls } from './Controls';

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

type PlayerComponentState = {
    manifestUri?: string;
    licensingUri?: string;
    deviceId?: string;
    drmType?: string;
    streamType?: string;
    ready: boolean;
    playoutRequest?: PlayoutRequestData;
    videoContainerRef?: HTMLElement;

    play: { value: boolean };

    fullscreen: boolean;

    showControls: boolean;
};

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

export default class Player extends React.Component<RouteComponentProps, PlayerComponentState> {
    private videoContainerRef: HTMLElement;
    constructor(props: RouteComponentProps) {
        super(props);
        this.state = { ready: false, play: { value: true }, fullscreen: false, showControls: false };
    }

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

    public render() {
        return (
            <>
                <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}
                />
                <CommonPlayerComponent
                    style={{
                        margin: '20px',
                        backgroundColor: 'black',
                        position: 'relative',
                        left: 0,
                        top: 0,
                        bottom: 0,
                        right: 0,
                    }}
                    playoutRequest={this.state.playoutRequest}
                    play={this.state.play}
                    fullscreen={this.state.fullscreen}
                    onFullscreenExited={this.handleFullscreenExited}
                    onStateChanged={this.handlePlayerStateChanged}
                >
                    {this.state.showControls && (
                        <Controls
                            style={{ position: 'absolute', top: 0, left: 0, bottom: 0, right: 0 }}
                            onPlay={this.onPlay}
                            onPause={this.onPause}
                            onFullscreen={this.onFullscreen}
                            isFullscreen={this.state.fullscreen}
                        />
                    )}
                </CommonPlayerComponent>
            </>
        );
    }

    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 () => {
        const playbackType = PlaybackType[this.state.streamType || 'Vod'];
        const playoutRequest: 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,
        };

        this.setState({ playoutRequest });
    };

    /* Player events */

    private handleFullscreenExited = () => this.setState({ fullscreen: false });
    private handlePlayerStateChanged = state => this.setState({ showControls: state !== PlayerState.Loading && state !== PlayerState.Stopped });

    /* Controls events */

    private onPlay = () => this.setState({ play: { value: true } });
    private onPause = () => this.setState({ play: { value: false } });
    private onFullscreen = () => this.setState(state => ({ fullscreen: !state.fullscreen }));
}
