import React, { Component } from "react";
import { EventName, GetProfitLossMessage, NewTickMessage, PutProfitLossMessage } from "../types";
import { socket } from "../index";
import { DateTime } from "luxon";

type QuoteStatusProps = {
    percentage?: boolean,
    quote_symbol?: string,
    amount: number,
    subtitle: string,
    sign?: boolean
}

export class QuoteStatus extends Component<QuoteStatusProps> {
    private whole: number;
    private decimal: number;
    private sign: string;
    private signClass: string;

    constructor(props: QuoteStatusProps) {
        super(props);

        this.whole = 0;
        this.decimal = 0;
        this.sign = "";
        this.signClass = "";

        this.deriveProps()
    }

    deriveProps() {
        this.whole = Math.abs(Math.trunc(this.props.amount))
        this.decimal = Math.trunc(this.props.amount % 1 * 100)
        this.sign = this.props.amount > 0 ? "+" : "-"

        this.signClass = this.props.amount > 0 ? "text-green-500" : "text-red-500"
    }

    renderSign() {
        if (this.props.sign) {
            return (
                <span
                    className={this.signClass}>{this.sign}</span>
            )
        }
        return null
    }

    symbolOrPercentageRender() {
        if (this.props.percentage) {
            return (
                <>
                    <span className="text-4xl text-bold align-top">
                        {this.renderSign()}</span>
                    <span className="text-5xl">{Math.abs(this.props.amount).toFixed(2)}</span>
                    <span className="text-3xl align-top">%</span>
                </>
            )
        } else {
            return (
                <>
                    <span className="text-4xl text-bold align-top">{this.renderSign()}{this.props.quote_symbol}</span>
                    <span className="text-5xl">{this.whole.toLocaleString()}</span>
                    <span className="text-3xl align-top">.{Math.abs(this.decimal)}</span>
                </>
            )
        }
    }

    render() {
        return (
            <>
                <div className="text-gray-700 mb-2">
                    {this.symbolOrPercentageRender()}
                </div>
                <div className="text-sm uppercase text-gray-300 tracking-wide">
                    {this.props.subtitle}
                </div>
            </>
        )
    }
}

type DateButtonProps = {
    label: string,
    onClick: any,
    selected_default?: boolean
}

type DateButtonState = {
    selected: boolean,
}

class DateButton extends Component<DateButtonProps, DateButtonState> {
    private classSelected: string = "appearance-none py-4 text-blue-600 border-b border-blue-600 mr-3";
    private classNotSelected: string = "appearance-none py-4 text-gray-600 border-b border-transparent hover:border-gray-800 mr-3";
    private currentClass: string = "";

    state = {
        selected: false
    }
    
    constructor(props: DateButtonProps) {
        super(props);

        if (this.props.selected_default) {
            this.state = {
                selected: this.props.selected_default
            }
        }

        this.updateClass()
    }

    onClick() {
        this.setState({ selected: !this.state.selected }, this.updateClass)

        this.props.onClick()
    }

    updateClass() {
        this.currentClass = this.state.selected ? this.classSelected : this.classNotSelected
    }

    render() {
        return (
            <button key={this.props.label} type="button"
                className={this.currentClass} onClick={this.onClick.bind(this)}>
                {this.props.label}
            </button>
        )
    }
}

const PeriodUnit = {
    SECOND: "second",
    MINUTE: "minute",
    HOUR: "hour",
    DAY: "day",
    WEEK: "week",
    MONTH: "month",
    YEAR: "year"
}

type StatusBarState = {
    pl_period_unit: string,
    pl_period_amount: number,
    pl: number,
    pl_perc: number
}

export class Statusbar extends Component<NewTickMessage, StatusBarState> {

    constructor(props: NewTickMessage) {
        super(props);

        this.state = {
            pl_period_unit: PeriodUnit.WEEK,
            pl_period_amount: 1,
            pl: 0.0,
            pl_perc: 0.0
        }

        this.emitGetProfitLoss = this.emitGetProfitLoss.bind(this)
    }

    componentDidMount() {
        socket.on(EventName.PutProfitLoss, (data: PutProfitLossMessage) => {
            this.setState({
                pl: data.pl,
                pl_perc: data.pl_perc
            })
        })

        socket.on(EventName.FirstConnect, this.emitGetProfitLoss)
        socket.on(EventName.NewTick, this.emitGetProfitLoss)
    }


    durationObjectfromStr(str: string) {
        switch (str) {
            case PeriodUnit.MINUTE:
                return {
                    minutes: this.state.pl_period_amount
                }
            case PeriodUnit.HOUR:
                return {
                    hours: this.state.pl_period_amount
                }
            case PeriodUnit.DAY:
                return {
                    days: this.state.pl_period_amount
                }
            case PeriodUnit.WEEK:
                return {
                    weeks: this.state.pl_period_amount
                }
            case PeriodUnit.MONTH:
                return {
                    months: this.state.pl_period_amount
                }
            case PeriodUnit.YEAR:
                return {
                    years: this.state.pl_period_amount
                }
            default:
                return {}
        }
    }

    emitGetProfitLoss() {
        const message: GetProfitLossMessage = {
            start: DateTime.local().minus(this.durationObjectfromStr(this.state.pl_period_unit)).toMillis(),
            end: DateTime.local().toMillis()
        }

        socket.emit(EventName.GetProfitLoss, message)
    }

    changeProfitLossPeriod(amount: number, unit: string) {
        this.setState({
            pl_period_amount: amount,
            pl_period_unit: unit
        }, this.emitGetProfitLoss)
    }

    render() {
        return (
            <div className="bg-white border-t border-b sm:border-l sm:border-r sm:rounded-lg shadow flex-grow mb-6">
                <div className="bg-gray-50 rounded-tl-lg rounded-tr-lg border-b px-6">
                    <div className="flex justify-between -mb-px">
                        <div className="lg:hidden text-blue-600 py-4 text-lg">
                            Price Charts
                        </div>
                        <div className="hidden lg:flex">
                            <button type="button"
                                className="appearance-none py-4 text-blue-600 border-b border-blue-dark mr-6">
                                Bitcoin
                            </button>
                        </div>
                        <div className="flex text-sm">
                            <DateButton key={PeriodUnit.MINUTE} label={"1m"}
                                onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.MINUTE)} />
                            <DateButton key={PeriodUnit.DAY} label={"1D"}
                                onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.DAY)} />
                            <DateButton key={PeriodUnit.WEEK} label={"1W"} selected_default={true}
                                onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.WEEK)} />
                            <DateButton key={PeriodUnit.MONTH} label={"1M"}
                                onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.MONTH)} />
                            <DateButton key={PeriodUnit.YEAR} label={"1Y"}
                                onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.YEAR)} />
                            {/*<DateButton label={"ALL"} onClick={() => this.changeProfitLossPeriod(1, PeriodUnit.MINUTE)}/>*/}
                        </div>
                    </div>
                </div>
                <div className="flex items-center px-6 lg:hidden">
                    <div className="flex-grow flex-no-shrink py-6">
                        <div className="text-gray-700 mb-2">
                            <span className="text-3xl align-top">CA$</span>
                            <span className="text-5xl">21,404</span>
                            <span className="text-3xl align-top">.74</span>
                        </div>
                        <div className="text-green-300 text-sm">
                            &uarr; CA$12,955.35 (154.16%)
                        </div>
                    </div>
                    <div className="flex-shrink w-32 inline-block relative">
                        <select
                            className="block appearance-none w-full bg-white border border-grey-light px-4 py-2 pr-8 rounded">
                            <option>BTC</option>
                        </select>
                        <div className="pointer-events-none absolute pin-y pin-r flex items-center px-2 text-gray-300">
                            <svg className="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg"
                                viewBox="0 0 20 20">
                                <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" />
                            </svg>
                        </div>
                    </div>
                </div>
                <div className="hidden lg:flex">
                    <div className="w-1/3 text-center py-8">
                        <div className="border-r">
                            <QuoteStatus key={this.props.price} quote_symbol={"USD"} amount={this.props.price}
                                subtitle={"Bitcoin price"} />
                        </div>
                    </div>
                    <div className="w-1/3 text-center py-8">
                        <div className="border-r">
                            <QuoteStatus key={this.state.pl} quote_symbol={"USD"} sign={true} amount={this.state.pl}
                                subtitle={"since last ".concat(this.state.pl_period_unit)} />
                        </div>
                    </div>
                    <div className="w-1/3 text-center py-8">
                        <div>
                            <QuoteStatus key={this.state.pl_perc} percentage={true} sign={true}
                                amount={this.state.pl_perc}
                                subtitle={"since last ".concat(this.state.pl_period_unit)} />
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}