import './scss/style.scss';

import { VERSION } from './constants';
import { NonstopEvents } from './events/publicEvents';
import { NonstopConfig } from './models/configuration/nonstopConfig';
import { Report } from './models/content/report';
import { WatchNonstopResult } from './models/content/watchNonstopResult';
import { PerformTaskResult } from './models/tasks/performTaskResult';
import { Reward } from './models/tasks/reward';
import { TaskDetails } from './models/tasks/taskDetails';
import { TaskInput } from './models/tasks/taskInput';
import { TaskType } from './models/tasks/taskType';
import { User } from './models/users/user';
import { UserInput } from './models/users/UserInput';
import { PointsWidgetConfig } from './models/views/pointswidgetconfig';
import amplitudeService from './services/amplitudeService';
import animationService from './services/animationService';
import cardService from './services/cardService';
import configurationService from './services/configurationService';
import connectService from './services/connectService';
import contentService from './services/contentService';
import purchaseService from './services/purchaseService';
import userService from './services/userService';
import { PointsWidget } from './views/pointsWidget';

class Nonstop {
    public static sharedInstance = new Nonstop();
    public Events = new NonstopEvents();
    public version = VERSION;

    public config: NonstopConfig;

    public initialize(config: NonstopConfig) {
        const isConfigValid = configurationService.validateConfiguration(config);
        if (isConfigValid) {
            this.config = config;
        }
        animationService.getAnimations();
        amplitudeService.init();
        __webpack_public_path__ = config.cdnUrl;
    }

    public async login(userInput: UserInput, suppressAnimation: boolean = false): Promise<User> {
        return userService.login(userInput, suppressAnimation);
    }

    public async logout() {
        userService.logout();
    }

    public async userPerformedTask(task: TaskInput): Promise<PerformTaskResult> {
        return await userService.userPerformedTask(task);
    }

    public isConnected(): boolean {
        return connectService.isConnected;
    }

    public currentUser(): User | null {
        return connectService.currentUser;
    }

    public isWatchingNonstop(): boolean {
        return connectService.isWatchingNonstop;
    }

    public async getTaskDetails(taskType: TaskType): Promise<TaskDetails | null> {
        return userService.getTaskDetails(taskType);
    }

    public async shouldWatchNonstop(contentId: string, forPreview?: boolean): Promise<WatchNonstopResult | null> {
        return forPreview ? purchaseService.getContentNonstopStatus(contentId) : purchaseService.shouldWatchNonstop(contentId);
    }

    public async completeContent(contentId: string): Promise<Report | null> {
        return contentService.completeContent(contentId);
    }

    public async presentChoiceCard(contentId: string, inElement: HTMLElement, isContinueWatching: boolean): Promise<boolean> {
        return cardService.presentChoiceCard(contentId, inElement, isContinueWatching);
    }

    public async presentPointsWidget(inElement: HTMLElement, withConfig: PointsWidgetConfig = new PointsWidgetConfig()) {
        return cardService.presentPointsWidget(inElement, withConfig);
    }

    public exceedPointsLimit() {
        connectService.hasExceededPointsLimit = true;
        connectService.pointsLimitMessage = 'Max points reached for today';
        PointsWidget.updateAll();
    }

    public async presentNonstopHome(inElement: HTMLElement, withBaseUrl: string): Promise<void> {
        const nonstopHomeService = await import(/* webpackChunkName: 'nonstop-home' */ './services/nonstopHomeService');
        nonstopHomeService.default.presentNonstopHome(inElement, withBaseUrl);
    }

    public async playAnimation(animationName: string, points: number) {
        const reward = new Reward();
        reward.animationName = animationName;
        reward.pointsAwarded = points;
        reward.pointsAwardedDisplay = String(points);
        return await cardService.presentRewardCard(TaskType.SignUp, reward);
    }

    public async getAnimations() {
        return await animationService.getAnimations();
    }

}

export default Nonstop.sharedInstance as Nonstop;