import { AxiosResponse } from 'axios';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import swal from 'sweetalert';
import settings from '../../config/settings';
import { AmplitudeEvents } from '../../events/amplitudeEvents';
import { ChoiceCardShownEvent } from '../../models/amplitude/ChoiceCardShownEvent';
import { ChoiceCardWatchAndEarnSelectedEvent } from '../../models/amplitude/ChoiceCardWatchAndEarnSelectedEvent';
import { ChoiceCardWatchNonstopSelectedEvent } from '../../models/amplitude/ChoiceCardWatchNonstopSelectedEvent';
import { Content } from '../../models/content/content';
import { AbpResponse } from '../../models/http/abpResponse';
import { ResultBase } from '../../models/http/resultBase';
import nonstop from '../../nonstop';
import connectService from '../../services/connectService';
import contentService from '../../services/contentService';
import eventEmitter from '../../services/eventEmitter';
import purchaseService from '../../services/purchaseService';
import { PresentableView } from '../abstract/presentableView';
import { ChoiceCard } from './ChoiceCard';

export class ChoiceCardView extends PresentableView {
    protected logTag: string = 'ChoiceCardView';
    private injectedElem: HTMLElement;

    private content: Content | null;

    constructor(private contentId: string, private inElement: HTMLElement, private isContinueWatching: boolean) {
        super();
    }

    public async presentSelf(): Promise<boolean> {
        this.content = await contentService.getContent(this.contentId);
        if (!this.content) {
            this.onWatchStandard(false);
            return false;
        }
        if (this.content.isPurchased) {
            this.onWatchNonstop(false);
            return false;
        }
        if (!this.content.isEligibleToEarn) {
            this.onWatchStandard(false);
            return false;
        }
        if (!this.content.isAffordable) {
            this.onWatchStandard(false);
            return false;
        }
        if (!this.content.isEligibleToBuy) {
            this.onWatchStandard(false);
            return false;
        }
        this.injectedElem = document.createElement('div');
        this.inElement.appendChild(this.injectedElem);
        ReactDOM.render(
            <ChoiceCard
                content={this.content}
                isContinueWatching={this.isContinueWatching}
                onWatchStandard={(timedOut) => this.onWatchStandardSelected(timedOut)}
                onWatchNonstop={() => this.handleNonstopClick()}
            />
            , this.injectedElem);
        eventEmitter.broadcastEvent(AmplitudeEvents.ChoiceCardShown, new ChoiceCardShownEvent(this.content.price, this.content.contentTitle, this.content.contentType, this.content.amplitudeEpisodeNumber, this.content.episodeTitle));
        return true;
    }

    private async handleNonstopClick() {
        if (!this.content) {
            this.onWatchStandard(false);
        } else {
            const purchaseResult = await purchaseService.purchaseContent(this.contentId, this.content.price, this.handlePurchaseError);
            if (!purchaseResult) {
                this.onWatchStandard(false);
            } else {
                connectService.currentUser = purchaseResult.user;
                this.onWatchNonstop(true);
            }
        }
    }

    private onWatchStandardSelected(timedOut: boolean) {
        const wasSelected = !timedOut;
        this.onWatchStandard(wasSelected, timedOut);
    }

    private onWatchStandard(wasSelected: boolean, timedOut: boolean = false) {
        eventEmitter.broadcastEvent(nonstop.Events.OnWatchStandard, null, this.inElement);
        if (this.content && (wasSelected || timedOut)) {
            const triggerType = wasSelected ? 'Watch & Earn Selected' : 'Timeout';
            const event = new ChoiceCardWatchAndEarnSelectedEvent(this.content.price, this.content.contentTitle, this.content.contentType, this.content.amplitudeEpisodeNumber, this.content.episodeTitle, triggerType);
            eventEmitter.broadcastEvent(AmplitudeEvents.ChoiceCardWatchAndEarnSelected, event);
        }
        this.dismissSelf(this.injectedElem, settings.animateCssAnimationDurationMs);
    }

    private onWatchNonstop(wasSelected: boolean) {
        eventEmitter.broadcastEvent(nonstop.Events.OnWatchNonstop, null, this.inElement);
        if (this.content && wasSelected) {
            eventEmitter.broadcastEvent(AmplitudeEvents.ChoiceCardWatchNonstopSelected, new ChoiceCardWatchNonstopSelectedEvent(this.content.price, this.content.contentTitle, this.content.contentType, this.content.amplitudeEpisodeNumber, this.content.episodeTitle));
        }
        this.dismissSelf(this.injectedElem, settings.animateCssAnimationDurationMs);
    }

    private handlePurchaseError(rawResponse: AxiosResponse<AbpResponse<ResultBase>>): void {
        swal(rawResponse.data.result.message);
    }
}