import React from 'react';
import { Layout, message, Empty, Divider, Avatar, Table } from 'antd';
import { AreaChart, Area, Tooltip, XAxis, YAxis, CartesianGrid, Label, ResponsiveContainer } from "recharts";
import { Ellipsis } from 'react-spinners-css';
import orderBy from 'lodash.orderby'
import {
    FileUnknownTwoTone,
    FrownOutlined
} from '@ant-design/icons';
import { Link } from 'react-router-dom';

const { Column } = Table;


class Profile extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            score: 0,
            challenges: [],
            targetUser: "",
            loading: true,
            userScore: "Loading...",
            graphData: [],
        }
    }

    componentDidMount() {
        const username = this.props.match.params.user;
        if (typeof username !== "undefined") {
            this.setState({ targetUser: username })
            this.unpackChallengesData(username);
        }
        else {
            this.setState({ targetUser: this.props.username })
            this.unpackChallengesData(this.props.username);
        }

    }

    //Marvel in glory at the hideous mess of tangled backend handling.
    //Gawk at the terrible use of index-based for loops when streams exist now
    //Try, and fail, to interpret the sheer rubbish that is this method.
    //But it works. And that is enough for me to bury it forever.
    //- Leonard.
    //- Tkai: Archived since 2020
    unpackChallengesData = async (username) => {
        fetch(window.ipAddress + "/v1/scoreboard/" + username, {
            method: 'get',
            headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
        }).then((results) => {
            return results.json(); //return data in JSON (since its JSON data)
        }).then((data) => {
            if (data.success === true) {

                if (data.hidden !== true) {
                    let challengeDS = []
                    let challengeArray = orderBy(data.scores, ["timestamp"], ["desc"])
                    let challengeArrayReversed = orderBy(data.scores, ["timestamp"], ["asc"])
                    let graphData = []
                    let graphPoint = {}
                    let scoreTotal = 0

                    graphData.push({
                        Score: 0,
                        Time: "0"
                    })

                    for (let x = 0; x < challengeArray.length; x++) {
                        if (challengeArrayReversed[x].points !== 0) {
                            //Plot graph
                            scoreTotal += challengeArrayReversed[x].points
                            graphPoint = {
                                Score: scoreTotal,
                                Time: new Date(challengeArrayReversed[x].timestamp).toLocaleString("en-US", { timeZone: "Asia/Singapore" })
                            }
                            graphData.push(graphPoint)
                        }

                        if (challengeArray[x].points !== 0) {
                            //Handle table
                            let currentDS = {
                                key: String(x),
                                challenge: "",
                                score: "",
                                time: "",
                                challengeID: ""
                            }
                            const currentStuff = challengeArray[x]
                            //Current record is a hint
                            if (currentStuff.type === "hint") currentDS.challenge = "Purchased Hint For: " + currentStuff.challenge
                            else currentDS.challenge = currentStuff.challenge
                            if ("challengeID" in currentStuff) currentDS.challengeID = currentStuff.challengeID
                            currentDS.score = currentStuff.points
                            //console.log(currentStuff.timestamp)
                            const dateTime = Math.abs(new Date() - new Date(currentStuff.timestamp)) / 1000 //no. of seconds since the challenge was completed/hint bought
                            let minutes = Math.ceil(dateTime / 60)
                            let hours = 0
                            let days = 0
                            let months = 0
                            let years = 0
                            if (minutes >= 60) {
                                hours = Math.floor(minutes / 60)
                                minutes = minutes - hours * 60

                                if (hours >= 24) {
                                    days = Math.floor(hours / 24)
                                    hours = hours - days * 24

                                    if (days >= 30) {
                                        months = Math.floor(days / 30)
                                        days = days - months * 30

                                        if (months >= 12) {
                                            years = Math.floor(months / 12)
                                            months = months - years * 12
                                        }
                                    }
                                }
                            }
                            let finalTime = " ago."
                            if (minutes !== 0) {
                                finalTime = minutes.toString() + " minutes " + finalTime
                            }
                            if (hours !== 0) {
                                finalTime = hours.toString() + " hours " + finalTime
                            }
                            if (days !== 0) {
                                finalTime = days.toString() + " days " + finalTime
                            }
                            if (months !== 0) {
                                finalTime = months.toString() + " months " + finalTime
                            }
                            if (years !== 0) {
                                finalTime = years.toString() + " years " + finalTime
                            }
                            currentDS.time = finalTime

                            challengeDS.push(currentDS)
                        }
                    }

                    //push finalPoint
                    graphPoint = {
                        Score: scoreTotal,
                        Time: new Date().toLocaleString("en-US", { timeZone: "Asia/Singapore" })
                    }
                    graphData.push(graphPoint)
                    this.setState({ userScore: scoreTotal, graphData: graphData, scores: challengeDS })
                    //console.log(graphData)
                }
                else this.setState({ userScore: "Hidden" })

            }
            else {
                if (data.error === "not-found") {
                    message.error("The user '" + username + "' was not found")
                    console.error(data.error)
                }
                else {
                    message.error("Something went wrong looking up " + username)
                    console.error(data.error)
                }
                this.setState({ targetUser: "", userScore: 0 })

            }
        }).catch((error) => {
            console.log(error);
            message.error({ content: "Something went wrong fetching your challenges." })
        })
        this.setState({ loading: false })
    }

    render() {
        return (
            <Layout className="layout-style">


                {this.state.loading && (
                    <div style={{ position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
                        <Ellipsis color="#177ddc" size={120} ></Ellipsis>
                    </div>
                )}
                {
                    !this.state.targetUser && !this.state.loading && (
                        <div style={{ height: "100%", width: "100%" }}>
                            <br /><br /><br />
                            <Empty
                                image={<FrownOutlined />}
                                imageStyle={{ fontSize: "500%", color: "#177ddc" }}
                                description={<h1>We were unable to find the user "{this.props.match.params.user}"</h1>}
                            />
                        </div>
                    )
                }
                {
                    this.state.targetUser && !this.state.loading && (
                        <Layout style={{ height: "100%", width: "100%", padding: "3%", backgroundColor: "rgba(0, 0, 0, 0)" }}>
                            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                                <div style={{ display: "flex" }}>
                                    <div style={{ display: "flex", marginRight: "5ch", alignItems: "center", justifyItems: "center" }}>
                                        <Avatar style={{ backgroundColor: "transparent", marginRight: "3ch", width: "10ch", height: "10ch" }} size='large' src={"/static/profile/" + this.state.targetUser + ".webp"} />
                                        <h1 style={{ fontSize: "5ch" }}>{this.state.targetUser}</h1>
                                    </div>
                                    <div>
                                        <h1 style={{ fontSize: "5ch", color: "#faad14" }}><span style={{ color: "#d48806", fontSize: "1.5ch" }}><u>Score:</u> </span>{this.state.userScore}</h1>
                                    </div>
                                </div>
                            </div>
                            <Divider />
                            <h1 style={{ fontSize: "3ch" }}>Score History</h1>
                            <div style={{ height: 375, width: "100%", backgroundColor: "rgba(0, 0, 0, 0.3)", border: "5px solid transparent", borderRadius: "20px", padding: "10px", margin: "10px" }}>
                                <ResponsiveContainer width="90%" height={350}>
                                    <AreaChart height={350} data={this.state.graphData}
                                        margin={{ top: 10, right: 15, left: 15, bottom: 15 }}>

                                        <defs>
                                            <linearGradient id="color1" x1="0" y1="0" x2="0" y2="1">
                                                <stop offset="5%" stopColor="#791a1f" stopOpacity={0.3} />
                                                <stop offset="95%" stopColor="#f89f9a" stopOpacity={0.1} />
                                            </linearGradient>
                                        </defs>
                                        <XAxis dataKey="Time">
                                            <Label offset={-5} position="insideBottom" style={{ fill: 'rgba(207, 207, 207, 1)' }}>
                                                Time
                                            </Label>
                                        </XAxis>
                                        <YAxis >
                                            <Label offset={-10} position='insideLeft' style={{ fill: 'rgba(207, 207, 207, 1)' }}>
                                                Score
                                            </Label>
                                        </YAxis>
                                        <CartesianGrid strokeDasharray="3 3" />

                                        <Tooltip labelStyle={{ backgroundColor: "#1c2b3e" }} contentStyle={{ backgroundColor: "#1c2b3e" }} wrapperStyle={{ backgroundColor: "#1c2b3e" }} />
                                        <Area isAnimationActive={false} type="monotone" dataKey="Score" stroke="#d32029" fillOpacity={1} fill="url(#color1)" />
                                    </AreaChart>
                                </ResponsiveContainer>

                            </div>
                            <Table style={{ marginTop: "2vh" }} dataSource={this.state.scores} pagination={{ pageSize: 10 }} locale={{
                                emptyText: (
                                    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
                                        <FileUnknownTwoTone style={{ color: "#177ddc", fontSize: "400%", zIndex: 1 }} />
                                        <h1 style={{ fontSize: "200%" }}>{this.state.targetUser} has not completed any challenges/bought any hints</h1>
                                    </div>
                                )
                            }}>
                                <Column width={1} title="Challenge/Hint" dataIndex="challenge" key="challenge"
                                    render={(text, row, index) => {
                                        if (row.challengeID !== "") return <Link to={"/Challenges/" + row.challengeID}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                                        else return (<span>{text}</span>);
                                    }} />
                                <Column width={30} title="Score Change" dataIndex="score" key="score" />
                                <Column width={30} title="Solved Timestamp" dataIndex="time" key="time" />
                            </Table>
                        </Layout>

                    )
                }
            </Layout>
        )
    }
}




export default Profile;