import { Component, ReactNode } from 'react';
import * as React from 'react';
import { StaticContext, withRouter } from 'react-router';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
import { EarnRowItem } from '../../models/nonstophome/earnRowItem';
import { EarnRowItemType } from '../../models/nonstophome/earnRowItemType';
import { NonstopEarnResult } from '../../models/nonstophome/nonstopEarnResult';
import { NonstopHistoryResult } from '../../models/nonstophome/nonstopHistoryResult';
import { NonstopHomeTab } from '../../models/nonstophome/nonstophometab';
import { NonstopHowItWorksResult } from '../../models/nonstophome/nonstopHowItWorksResult';
import { OtherWayToEarn } from '../../models/nonstophome/otherWayToEarn';
import { PerformTaskResult } from '../../models/tasks/performTaskResult';
import amplitudeEventModificationService from '../../services/amplitudeEventModificationService';
import { EnterCode } from './EnterCode';
import NonstopEarn from './NonstopEarn';
import { NonstopHistory } from './NonstopHistory';
import { NonstopHowItWorks } from './NonstopHowItWorks';
import { OtherWayToEarnInfo } from './OtherWayToEarnInfo';
import { Promo } from './Promo';

interface IOtherWayToEarnInfoRouteProps {
    earnMethodId: string;
}

interface IPromoRouteProps {
    promoId: string;
}

interface INonstopHomeProps extends RouteComponentProps<any> {
    userHistory: NonstopHistoryResult;
    earnResult: NonstopEarnResult;
    howItWorks: NonstopHowItWorksResult;
    baseUrl: string;

    checkCode: (code: string) => Promise<PerformTaskResult>;
    refreshTab: (newTab: NonstopHomeTab) => void;
}

class NonstopHome extends Component<INonstopHomeProps, {}> {
    private currentTab: NonstopHomeTab;

    constructor(props: INonstopHomeProps) {
        super(props);
        this.currentTab = NonstopHomeTab.Earn;
        amplitudeEventModificationService.setNonstopArrivalUrl(this.props.location.pathname);
    }

    public componentDidUpdate(previousProps: INonstopHomeProps) {
        if (this.props.location.pathname !== previousProps.location.pathname) {
            this.onRouteChanged();
        }
    }

    public render(): React.ReactNode {
        return (
            <Switch>
                <Route exact path='/' render={(props) => this.renderNonstopEarn(props)} />
                <Route path='/promo/:promoId' render={(props) => this.renderPromo(props)} />
                <Route path='/code' render={(props) => this.renderEnterCode(props)} />
                <Route path='/earn-method/:earnMethodId' render={(props) => this.renderEarnMethod(props)} />
                <Route path='/history' render={(props) => this.renderNonstopHistory(props)} />
                <Route path='/how-it-works' render={(props) => this.renderNonstopHowItWorks(props)} />
            </Switch>
        );
    }

    private renderNonstopEarn(props: RouteComponentProps<any, StaticContext, any>): ReactNode {
        return (
            <NonstopEarn
                {...props}
                earnResult={this.props.earnResult}
            />
        );
    }

    private renderNonstopHistory(props: RouteComponentProps<any, StaticContext, any>): ReactNode {
        return (
            <NonstopHistory
                {...props}
                userHistory={this.props.userHistory}
                earnResult={this.props.earnResult}
            />
        );
    }

    private renderNonstopHowItWorks(props: RouteComponentProps<any, StaticContext, any>): ReactNode {
        return (
            <NonstopHowItWorks
                {...props}
                howItWorks={this.props.howItWorks}
                earnResult={this.props.earnResult}
            />
        );
    }

    private renderEnterCode(props: RouteComponentProps<any, StaticContext, any>): ReactNode {
        return (
            <EnterCode
                {...props}
                checkCode={this.props.checkCode}
                onExit={() => this.goToNonstopEarn()}
            />
        );
    }

    private renderPromo(props: RouteComponentProps<IPromoRouteProps, StaticContext, any>): ReactNode {
        return (
            <Promo
                {...props}
                earnRowItem={this.getPromoFromId(props.match.params.promoId)}
                onExit={() => this.goToNonstopEarn()}
            />
        );
    }

    private renderEarnMethod(props: RouteComponentProps<IOtherWayToEarnInfoRouteProps, StaticContext, any>): ReactNode {
        return (
            <OtherWayToEarnInfo
                {...props}
                earnMethod={this.getEarnMethodFromId(props.match.params.earnMethodId)}
                onExit={() => this.goToNonstopEarn()}
            />
        );
    }

    private onRouteChanged() {
        window.scrollTo(0, 0);
        this.updateCurrentTab(this.props.location.pathname);
        this.props.refreshTab(this.currentTab);
        amplitudeEventModificationService.onRouteChange();
    }

    private updateCurrentTab(currentPath: string) {
        let currentTab = this.currentTab;
        switch (currentPath) {
            case '/':
                currentTab = NonstopHomeTab.Earn;
                break;
            case '/history':
                currentTab = NonstopHomeTab.History;
                break;
            case '/how-it-works':
                currentTab = NonstopHomeTab.HowItWorks;
                break;
        }
        this.currentTab = currentTab;
    }

    private goToNonstopEarn() {
        this.props.history.push('/');
    }

    private getPromoFromId(promoId: string): EarnRowItem | null {
        let foundItem;
        for (const currentRow of this.props.earnResult.rows) {
            for (const currentItem of currentRow.items) {
                if (currentItem.type === EarnRowItemType.Promo && currentItem.promoId === promoId) {
                    foundItem = currentItem;
                    break;
                }
            }
            if (foundItem) {
                break;
            }
        }
        return foundItem || null;
    }

    private getEarnMethodFromId(earnMethodId: string): OtherWayToEarn | null {
      const matchingMethod = this.props.earnResult.otherWaysToEarn.filter((x) => x.id === earnMethodId);
      if (matchingMethod && matchingMethod.length) {
        return matchingMethod[0];
      } else {
        return null;
      }
    }
}

export default withRouter(NonstopHome);
