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

const { Column } = Table;
const { Option } = Select;

var changes = {}
var updating = false
var userCategories = {}
var userCategory = ""

class Scoreboard extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      scores: [],
      graphData: [{ "": 0 }],
      top10: [""] * 10,
      loadingGraph: false,
      loadingTable: false,
      liveUpdates: false,
      categoryListOptions: []
    };
  }

  componentDidMount = async () => {
    let scoreboardData = window.scoreboardData
    if (typeof scoreboardData === "undefined") {
      changes = await this.getChanges()
      window.scoreboardData = changes
    }
    else {
      userCategories = window.userCategories
      changes = scoreboardData
    }
    userCategory = "none"

    // Render whatever data we have either: stored in global window/retrieved from Fetch for fast loading of scoreboard
    this.sortPlotRenderData(JSON.parse(JSON.stringify(changes)))
    let categoryListOptions = []
    for (let i = 0; i < window.categoryList.length; i++) {
      categoryListOptions.push(
        <Option value={window.categoryList[i]}>{window.categoryList[i]}</Option>
      )
    }
    categoryListOptions.unshift(<Option value="none">All Players</Option>)
    this.setState({ categoryListOptions: categoryListOptions })

    this.connectWebSocket() //Connect to socket server for live scoreboard and this will update the scoreboard with the latest data

    //Update last solved timing
    setInterval(() => { this.lastSolveTiming() }, 60 * 1000)

  }

  lastSolveTiming() {
    if (!updating) {
      // this uses absolute timing, so the drift from setInterval does not matter
      let scoreArray = this.state.scores
      for (let x = 0; x < scoreArray.length; x++) {

        if ("timestamp" in scoreArray[x] && scoreArray[x].timestamp !== "0") {
          //console.log(scoreArray[x])
          scoreArray[x].position = String(x + 1) + "."
          const dateTime = Math.abs(new Date() - new Date(scoreArray[x].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 > 1 ? " minutes " : " minute ") + finalTime
          }
          if (hours !== 0) {
            finalTime = hours.toString() + (hours > 1 ? " hours " : " hour ") + finalTime
          }
          if (days !== 0) {
            finalTime = days.toString() + (days > 1 ? " days " : " day ") + finalTime
          }
          if (months !== 0) {
            finalTime = months.toString() + (months > 1 ? " months " : " month ") + finalTime
          }
          if (years !== 0) {
            finalTime = years.toString() + (years > 1 ? " years " : " year ") + finalTime
          }
          scoreArray[x].time = finalTime

        }
        else {
          scoreArray[x].time = "No solves yet"
        }
      }
      this.setState({ scores: scoreArray })
    }
  }

  connectWebSocket() {
    const proto = window.location.protocol === "http:" ? "ws:" : "wss:"
    const address = process.env.NODE_ENV === "development" ? "ws://localhost:20001/" : proto + "//" + window.location.host + "/api/"
    let webSocket = new WebSocket(address)
    webSocket.onmessage = (e) => {
      let data = JSON.parse(e.data)
      if (data.type === "score") {
        updating = true
        const payloadArray = data.data // List of transactions to update
        for (let y = 0; y < payloadArray.length; y++) {
          let userFound = false
          const payload = payloadArray[y] // Current transaction to update

          userLoop:
          for (let x = 0; x < changes.users.length; x++) { // Iterate through user list

            if (changes.users[x]._id === payload.author) { // User found
              userFound = true
              const currentUserChanges = changes.users[x].changes
              let transactionFound = false
              for (let i = 0; i < currentUserChanges.length; i++) { // Iterate through changes (transactions of user)
                if (currentUserChanges[i]._id === payload._id) {
                  transactionFound = true
                  currentUserChanges[i] = payload // If transaction found, update transaction with the new payload
                  break userLoop;
                }
              }
              if (!transactionFound) changes.users[x].changes.push({ author: payload.author, points: payload.points, timestamp: payload.timestamp, _id: payload._id })
              break
            }
          }

          if (!userFound) {
            // User is a new user not on the scoreboard for whatever reason
            changes.users.push({ _id: payload.author, changes: [{ author: payload.author, points: payload.points, timestamp: payload.timestamp, _id: payload._id }] })
          }
        }


        window.scoreboardData = changes
        window.lastChallengeID = payloadArray[0].lastChallengeID
        this.sortPlotRenderData(JSON.parse(JSON.stringify(changes)))
      }
      else if (data.type === "user-category-update") {
        window.latestUserCategoryUpdateID = data.latestUserCategoryUpdateID
        window.userCategories = data.userCategories
        userCategories = data.userCategories
        this.sortPlotRenderData(JSON.parse(JSON.stringify(window.scoreboardData)))
      }
      else if (data.type === "team-update") {
        window.teamUpdateID = data.teamUpdateID
        window.scoreboardData = data.data
        this.sortPlotRenderData(JSON.parse(JSON.stringify(data.data)))
      }
      else if (data.type === "init") {
        if (data.data === "bad-auth") message.error("Error connecting to live updates")
        else if (data.data === "missing-auth") message.error("Error connecting to live updates")
        else if (data.data === "up-to-date") this.setState({ liveUpdates: true })

        else if (data.data === "max-connections") {
          message.warn("Your account has more than the concurrent number of socket connections allowed. Disconnecting...")
        }
        else {

          if (data.msg === "team-update") {
            window.teamUpdateID = data.teamUpdateID
            window.scoreboardData = data.data
            this.sortPlotRenderData(JSON.parse(JSON.stringify(data.data)))
          }
          else if (data.msg === "user-category-update") {
            window.latestUserCategoryUpdateID = data.latestUserCategoryUpdateID
            window.userCategories = data.userCategories
            userCategories = data.userCategories
            this.sortPlotRenderData(JSON.parse(JSON.stringify(window.scoreboardData)))
          }
          else {
            lastChallengeID = parseInt(data.data.lastChallengeID)
            const payloadArray = data.data // List of transactions to update
            for (let y = 0; y < payloadArray.length; y++) {
              let userFound = false
              const payload = payloadArray[y] // Current transaction to update
              userLoop:
              for (let x = 0; x < changes.users.length; x++) { // Iterate through user list

                if (changes.users[x]._id === payload.author) { // User found
                  userFound = true
                  const currentUserChanges = changes.users[x].changes
                  let transactionFound = false
                  for (let i = 0; i < currentUserChanges.length; i++) { // Iterate through changes (transactions of user)
                    if (currentUserChanges[i]._id === payload._id) {
                      transactionFound = true
                      currentUserChanges[i] = payload // If transaction found, update transaction with the new payload
                      break userLoop;
                    }
                  }
                  if (!transactionFound) changes.users[x].changes.push({ author: payload.author, points: payload.points, timestamp: payload.timestamp, _id: payload._id })
                  break
                }
              }

              if (!userFound) {
                // User is a new user not on the scoreboard for whatever reason
                changes.users.push({ _id: payload.author, changes: [{ author: payload.author, points: payload.points, timestamp: payload.timestamp, _id: payload._id }] })
              }
            }


            window.scoreboardData = changes
            window.lastChallengeID = data.lastChallengeID
            this.sortPlotRenderData(JSON.parse(JSON.stringify(changes)))
            this.setState({ liveUpdates: true })
          }

        }
      }
    }
    webSocket.onopen = (e) => {
      webSocket.send(JSON.stringify({ type: "init", data: { auth: window.IRSCTFToken, lastChallengeID: window.lastChallengeID, teamUpdateID: window.teamUpdateID, latestUserCategoryUpdateID: window.latestUserCategoryUpdateID } }))
      this.props.handleWebSocket(webSocket)
    }
    webSocket.onerror = (e) => {
      console.error(e)
    }
    webSocket.onclose = (e) => {

      this.setState({ liveUpdates: false })
      if (e.code !== 1000) {
        console.log('Socket closed. Attempting to reconnect in 5 seconds', e.reason);
        setTimeout(() => { this.connectWebSocket() }, 5000)
      }
    };
  }

  sortPlotRenderData(data) {
    let formattedData = []
    let finalPoint = {}
    let scoreArray = []
    let tempScoreTimeStampDict = {}

    if (userCategory !== "none") {
      const newUserData = []

      for (let i = 0; i < data.users.length; i++) {
        if (data.users[i]._id in userCategories) {
          if (userCategories[data.users[i]._id] === userCategory) newUserData.push(data.users[i])
        }
        else if (data.users[i].isTeam) {
          let allUsersRightCat = true
          for (let x = 0; x < data.users[i].members.length; x++) {
            if (userCategories[data.users[i].members[x]] !== userCategory) {
              allUsersRightCat = false 
              break
            }
          }
          if (allUsersRightCat) newUserData.push(data.users[i])
        }
        
      }
      data.users = newUserData
    }

    //Process timestamps - find the last solve timing and create scoreArray
    for (let i = 0; i < data.users.length; i++) {
      let scores2 = data.users[i].changes

      // some users might have empty "changes" as they have yet to solve anything
      // so we have to include their username first into the dictionary
      tempScoreTimeStampDict[data.users[i]._id] = { timestamp: "0", points: 0 }
      for (let x = 0; x < scores2.length; x++) {
        if (tempScoreTimeStampDict[data.users[i]._id].timestamp !== "0") {
          let d1 = new Date(tempScoreTimeStampDict[data.users[i]._id].timestamp)
          let d2 = new Date(scores2[x].timestamp)

          if (d1 < d2 && scores2[x].points > 0) tempScoreTimeStampDict[data.users[i]._id].timestamp = scores2[x].timestamp
          tempScoreTimeStampDict[data.users[i]._id].points += scores2[x].points

        }
        else {
          if (scores2[x].points === 0) tempScoreTimeStampDict[data.users[i]._id] = { timestamp: "0", points: scores2[x].points, isTeam: data.users[i].isTeam, members: data.users[i].members }
          else tempScoreTimeStampDict[data.users[i]._id] = { timestamp: scores2[x].timestamp, points: scores2[x].points, isTeam: data.users[i].isTeam, members: data.users[i].members }
        }
      }
    }

    //console.log(timestamp)
    // More processing & sort by timestamp
    for (const username in tempScoreTimeStampDict) {
      scoreArray.push({ username: username, timestamp: tempScoreTimeStampDict[username].timestamp, score: tempScoreTimeStampDict[username].points, isTeam: tempScoreTimeStampDict[username].isTeam, members: tempScoreTimeStampDict[username].members })
    }
    scoreArray = orderBy(scoreArray, ["score", "timestamp"], ["desc", "asc"])

    // Plot graph data and get top 10 scores
    let top10scores = {}
    let top10initialScores = {}
    let pointDict = {}
    let top10 = []
    const iterateTill = scoreArray.length > 10 ? 10 : scoreArray.length
    for (let i = 0; i < iterateTill; i++) {
      top10initialScores[scoreArray[i].username] = 0
      pointDict[scoreArray[i].username] = 0
      top10scores[scoreArray[i].username] = scoreArray[i].score
      top10.push(scoreArray[i].username)
    }

    finalPoint = top10scores
    finalPoint["Time"] = new Date().toLocaleString("en-US", { timeZone: "Asia/Singapore" })
    for (let i = 0; i < data.users.length; i++) {
      let currentPoint = {}

      if (data.users[i]._id in top10scores) {
        let scores = data.users[i].changes
        let pointsSoFar = 0

        for (let x = 0; x < scores.length; x++) {
          pointsSoFar += scores[x].points
          currentPoint["name"] = data.users[i]._id
          currentPoint["points"] = pointsSoFar
          currentPoint["Time"] = scores[x].timestamp
          formattedData.push(Object.assign({}, currentPoint))
        }

      }
    }

    // Fill position + solve time ago
    for (let x = 0; x < scoreArray.length; x++) {

      scoreArray[x].position = String(x + 1) + "."
      if ("timestamp" in scoreArray[x] && scoreArray[x].timestamp !== "0") {
        //console.log(scoreArray[x])

        const dateTime = Math.abs(new Date() - new Date(scoreArray[x].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 > 1 ? " minutes " : " minute ") + finalTime
        }
        if (hours !== 0) {
          finalTime = hours.toString() + (hours > 1 ? " hours " : " hour ") + finalTime
        }
        if (days !== 0) {
          finalTime = days.toString() + (days > 1 ? " days " : " day ") + finalTime
        }
        if (months !== 0) {
          finalTime = months.toString() + (months > 1 ? " months " : " month ") + finalTime
        }
        if (years !== 0) {
          finalTime = years.toString() + (years > 1 ? " years " : " year ") + finalTime
        }
        scoreArray[x].time = finalTime

      }
      else {
        scoreArray[x].time = "No solves yet"
      }
    }


    formattedData = orderBy(formattedData, ["Time"], ["asc"])
    //console.log(formattedData)
    let finalData = []

    finalData.push(top10initialScores)
    for (let i = 0; i < formattedData.length; i++) {

      pointDict[formattedData[i].name] = formattedData[i].points
      pointDict["Time"] = new Date(formattedData[i].Time).toLocaleString("en-US", { timeZone: "Asia/Singapore" })

      let copy = Object.assign({}, pointDict)

      finalData.push(copy)
    }

    finalData.push(finalPoint)
    this.setState({ graphData: finalData, loadingGraph: false, scores: scoreArray, loadingTable: false, top10: top10 })
    updating = false
  }

  getFinalScores = async () => {
    this.setState({ loadingGraph: true, loadingTable: true })
    const finalData = await fetch(window.ipAddress + "/v1/scores", {
      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) {
        return data
      }
      else {
        message.error({ content: "Oops. Unknown error" })
      }


    }).catch((error) => {
      message.error({ content: "Oops. There was an issue connecting with the server" });
    })
    return finalData
  }


  getChanges = async () => {
    const finalData = await fetch(window.ipAddress + "/v1/scoreboard", {
      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) {
        window.lastChallengeID = data.lastChallengeID
        window.teamUpdateID = data.teamUpdateID
        window.latestUserCategoryUpdateID = data.latestUserCategoryUpdateID
        window.userCategories = data.userCategories
        window.categoryList = data.categoryList

        userCategories = data.userCategories

        return { users: data.users }
      }
      else {
        message.error({ content: "Oops. Unknown error" })
      }


    }).catch((error) => {
      console.log(error)
      message.error({ content: "Oops. There was an issue connecting with the server" });
    })
    return finalData
  }

  handleCategoryChange = (value) => {
    userCategory = value
    this.setState({ loadingGraph: true, loadingTable: true })
    this.sortPlotRenderData(JSON.parse(JSON.stringify(window.scoreboardData)))
  }






  render() {
    return (
      <Layout className="layout-style">
        <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} debounce={200}>
            <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>
                <linearGradient id="color2" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#7c4a15" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#f8cf8d" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color3" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#7c5914" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#f8df8b" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color4" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#536d13" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#e4f88b" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color5" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#306317" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#b2e58b" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color6" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#146262" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#84e2d8" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color7" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#164c7e" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#8dcff8" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color8" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#203175" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#a8c1f8" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color9" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#3e2069" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#cda8f0" stopOpacity={0.1} />
                </linearGradient>
                <linearGradient id="color10" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#75204f" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#f8a8cc" 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={this.state.top10[0]} stroke="#d32029" fillOpacity={1} fill="url(#color1)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[1]} stroke="#d87a16" fillOpacity={1} fill="url(#color2)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[2]} stroke="#d89614" fillOpacity={1} fill="url(#color3)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[3]} stroke="#8bbb11" fillOpacity={1} fill="url(#color4)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[4]} stroke="#49aa19" fillOpacity={1} fill="url(#color5)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[5]} stroke="#13a8a8" fillOpacity={1} fill="url(#color6)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[6]} stroke="#177ddc" fillOpacity={1} fill="url(#color7)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[7]} stroke="#2b4acb" fillOpacity={1} fill="url(#color8)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[8]} stroke="#642ab5" fillOpacity={1} fill="url(#color9)" />
              <Area isAnimationActive={false} type="monotone" dataKey={this.state.top10[9]} stroke="#cb2b83" fillOpacity={1} fill="url(#color10)" />
              <Area isAnimationActive={false} type="monotone" dataKey="Hi" stroke="#8884d8" fillOpacity={1} fill="url(#colorPv)" />
            </AreaChart>
          </ResponsiveContainer>
          {this.state.loadingGraph && (
            <div style={{ position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
              <Ellipsis color="#177ddc" size={120} ></Ellipsis>
            </div>
          )}
        </div>

        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          {this.state.liveUpdates ?
            <div style={{ display: "flex", alignItems: "center", flexDirection: "row", justifyContent: "flex-end" }}><h4>Live Scoreboard </h4> <Ripple color="#a61d24" size={40} /></div> :
            <div style={{ display: "flex", alignItems: "center", flexDirection: "row", justifyContent: "flex-end" }}><h4>Connecting Live Scoreboard </h4> <Ellipsis color="#177ddc" size={40} /></div>
          }
          <div style={{ display: "flex", alignContent: "center" }}>
            <h1><ApartmentOutlined /> Category: </h1>
            <Select loading={this.state.loadingGraph || this.state.loadingTable} defaultValue="none" style={{ width: "20ch", backgroundColor: "#1f1f1f", marginLeft: "1ch" }} onChange={(value) => { this.handleCategoryChange(value) }}>
              {this.state.categoryListOptions}
            </Select>
          </div>
        </div>

        {!this.state.loadingTable && (
          <div style={{ height: "70%", width: "100%", minWidth: "70vw" }}>
            <Table style={{ marginTop: "2vh" }} dataSource={this.state.scores} pagination={{ pageSize: 20 }} 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%" }}>There are no users created/There are no users in this category</h1>
                </div>
              )
            }}>
              <Column title="Position" dataIndex="position" key="position" />
              <Column title="Username" dataIndex="username" key="username"
                render={(text, row, index) => {
                  if (row.isTeam) {
                    return (
                      <Link to={"/Team/" + text}><a style={{ fontSize: "110%", fontWeight: 700, display: "flex", alignItems: "center" }}>
                        <Avatar.Group
                          maxCount={3}
                          maxStyle={{ marginRight: "1ch" }}
                        >
                          {row.members.map((member) => {
                            return (<Avatar src={"/static/profile/" + member + ".webp"} style={{ marginRight: "1ch" }} />)
                          })}
                        </Avatar.Group>
                        <span>{text} <TeamOutlined /></span>
                      </a>
                      </Link>);
                  }
                  else {
                    return <Link to={"/Profile/" + text}><a style={{ fontSize: "110%", fontWeight: 700 }}><Avatar src={"/static/profile/" + text + ".webp"} style={{ marginRight: "1ch" }} /><span>{text}</span></a></Link>;
                  }
                }}
              />
              <Column title="Score" dataIndex="score" key="score" />
              <Column title="Last Solve" dataIndex="time" key="time" />
            </Table>
          </div>
        )}
      </Layout>
    );
  }
}

export default Scoreboard;