// eslint-disable-next-line no-unused-vars
import { RouteComponentProps } from 'react-router';
import { Redirect, Link } from 'react-router-dom';
// eslint-disable-next-line no-unused-vars
import { rootType } from '../redux/reducers';
import { connect } from 'react-redux';
import React from 'react';
import Parse from 'parse';
import Flag from 'react-world-flags';
import {
  ResponsiveContainer,
  BarChart,
  CartesianGrid,
  XAxis,
  YAxis,
  Cell,
  Bar,
  Tooltip,
} from 'recharts';

import DefaultAvatars from './Game/DefaultAvatars';
import ReactMarkdown from 'react-markdown';
import EditProfile from './Lobby/EditProfile';
import Navbar from './Navbar';
import AvalonScrollbars from '../components/utils/AvalonScrollbars';
import countries from '../components/countries';

import '../styles/Profile.scss';

const SPY_ROLES = new Set(['morgana', 'oberon', 'mordred', 'assassin', 'spy']);
const UN_FLAG = `https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Flag_of_the_United_Nations.svg/800px-Flag_of_the_United_Nations.svg.png`;
const STONEWALL_FLAG =
  'https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Gay_Pride_Flag.svg/2560px-Gay_Pride_Flag.svg.png';
const gummy = DefaultAvatars.gummy;

const Percent = (n: number) => Math.trunc(n * 10000) / 100;

const CustomTooltip = ({ active, payload }: { active?: Boolean; payload?: any }) => {
  if (active) {
    const { name, Winrate, wins, total } = payload[0].payload;
    const v = `${name}: ${Winrate}% [ ${wins}W / ${total - wins}L ]`;

    return (
      <div className="tooltip">
        <p>{v}</p>
      </div>
    );
  }

  return <></>;
};

interface ProfileProps {
  username: string;
  myname?: any;
  style?: any;
}

interface ProfileState {
  username: string;
  avatars: {
    spy: string;
    res: string;
  };
  bio: string;
  nationality: string;
  games: number[];
  gameStats: {
    [role: string]: number[];
  };
  gameHistory: string[];
  gameShots: number[];
  gameRating: number;
  redirect: boolean;
  showSpy: boolean;
  showForm: boolean;
}

const mapState = (state: rootType, ownProps: any) => {
  const { style } = state;
  const myname = state.username;

  const { username } = ownProps.match.params;
  return {
    match: {
      params: {
        username,
        myname,
        style,
      },
    },
  };
};

class Profile extends React.PureComponent<
  RouteComponentProps<ProfileProps>,
  ProfileState
> {
  state: ProfileState = {
    username: '',
    // Personality
    avatars: {
      spy: 'to_define',
      res: 'to_define',
    },
    bio: '',
    nationality: 'United Nations',
    // Game
    games: [0, 0],
    gameStats: {
      merlin: [0, 0],
      percival: [0, 0],
      resistance: [0, 0],
      assassin: [0, 0],
      morgana: [0, 0],
      oberon: [0, 0],
      mordred: [0, 0],
      spy: [0, 0],
    },
    gameHistory: [],
    gameShots: [0, 0],
    gameRating: 1500,
    // From profile page
    redirect: false,
    showSpy: false,
    showForm: false,
  };
  mounted: boolean = true;

  componentDidMount = () => {
    this.getProfile();
  };

  componentWillUnmount = () => {
    this.mounted = false;
  };

  componentDidUpdate = (prevProps: RouteComponentProps<ProfileProps>) => {
    const { username } = this.props.match.params;
    const { username: prevUsername } = prevProps.match.params;

    if (username !== prevUsername) {
      this.getProfile();
    }
  };

  getProfile = () => {
    const { username } = this.props.match.params;

    Parse.Cloud.run('generalCommands', { call: 'getProfile', username }).then(
      (profile) => {
        if (!profile) {
          this.onProfileNotFound();
          return;
        }

        this.saveProfile(profile);
      }
    );
  };

  saveProfile = (profile: ProfileState) => {
    if (!this.mounted) return;

    const {
      style: { avatarStyle },
    } = this.props.match.params;

    const defaultA = avatarStyle ? DefaultAvatars.gummy : DefaultAvatars.classic;

    const yourAvatars = profile.avatars;
    const avatarUrls =
      yourAvatars.res === gummy.res && yourAvatars.spy === gummy.spy
        ? defaultA
        : yourAvatars;

    this.setState({ ...profile, avatars: avatarUrls });
  };

  onProfileNotFound = () => this.setState({ redirect: true });

  onHover = () => this.setState({ showSpy: true });

  onStopHover = () => this.setState({ showSpy: false });

  onFormToggle = () => this.setState({ showForm: !this.state.showForm });

  onEdit = (data: any) => {
    this.onFormToggle();

    Parse.Cloud.run('generalCommands', { call: 'editProfile', ...data })
      .then(this.saveProfile)
      .catch((err) => console.log(err));
  };

  initialHeight = Math.max(window.innerHeight, 630);

  render() {
    const { initialHeight } = this;
    const {
      myname,
      style: { themeLight },
    } = this.props.match.params;

    const theme = themeLight ? 'light' : 'dark';
    const data: any[] = [];

    // const { avatarStyle } = this.props.match.params.style;
    const {
      username,
      nationality,
      bio,
      gameRating,
      gameHistory,
      games,
      gameStats,
      gameShots,
      avatars,
      showSpy,
      redirect,
    } = this.state;

    for (const k in gameStats) {
      const stat = gameStats[k];

      data.push({
        name: k.charAt(0).toUpperCase() + k.slice(1),
        wins: stat[0],
        total: stat[1],
        Winrate: stat[1] === 0 ? 0 : Percent(stat[0] / stat[1]),
        color: SPY_ROLES.has(k) ? '#ff6384' : '#36a2eb',
      });
    }

    const country = countries.find((c) => c.text === nationality);
    const totalWon = games[0];
    const totalLost = games[1] - totalWon;
    const winRate = games[1] > 0 ? Percent(totalWon / games[1]) : 0;
    const shotRate = gameShots[1] > 0 ? Percent(gameShots[0] / gameShots[1]) : 0;

    let countryFlag = <img alt={'UN'} src={UN_FLAG} />;
    if (country && country.value != 'UN') {
      if (country.value == 'LGBT') {
        countryFlag = <img alt={'Stonewall'} src={STONEWALL_FLAG} />;
      } else {
        countryFlag = <Flag code={country.value} />;
      }
    }

    return redirect ? (
      <Redirect to="/profile-not-found" />
    ) : (
      <div id="Background-2" className={`full ${theme}`}>
        <Navbar username="" key={'Navbar'} />
        <AvalonScrollbars>
          <div id="Profile" style={{ minHeight: `${initialHeight}px` }}>
            <div className="row">
              <div id="user">
                <img
                  src={showSpy ? avatars.spy : avatars.res}
                  alt={'Avatar'}
                  onMouseOver={this.onHover}
                  onMouseLeave={this.onStopHover}
                />
                <div className="user-tag">
                  {countryFlag}
                  <p>
                    <b>{username}</b>
                    <br />
                    {nationality}
                  </p>
                </div>
              </div>
              <div id="bio" className="bubble">
                <AvalonScrollbars>
                  <ReactMarkdown
                    className="markdown"
                    allowedTypes={[
                      'text',
                      'paragraph',
                      'emphasis',
                      'strong',
                      'thematicBreak',
                      'blockquote',
                      'list',
                      'listItem',
                      'heading',
                    ]}
                  >
                    {bio}
                  </ReactMarkdown>
                </AvalonScrollbars>
              </div>
            </div>
            <div className="row">
              <div id="stats">
                <h1>STATISTICS</h1>
                <table>
                  <tbody>
                    <tr>
                      <th>Statistic</th>
                      <th>Value</th>
                    </tr>
                    <tr>
                      <td>Total Games Played</td>
                      <td>{games[1]}</td>
                    </tr>
                    <tr>
                      <td>Total Games Won</td>
                      <td>{totalWon}</td>
                    </tr>
                    <tr>
                      <td>Total Games Lost</td>
                      <td>{totalLost}</td>
                    </tr>
                    <tr>
                      <td>Total Win Rate</td>
                      <td>{winRate}%</td>
                    </tr>
                    <tr>
                      <td>Shot Accuracy</td>
                      <td>{shotRate}%</td>
                    </tr>
                    <tr>
                      <td>Rating</td>
                      <td>{gameRating}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div id="graph">
                <ResponsiveContainer width={'100%'} height={300}>
                  <BarChart
                    layout="vertical"
                    margin={{
                      top: 20,
                      right: 20,
                      bottom: 20,
                      left: 20,
                    }}
                    data={data}
                  >
                    <CartesianGrid strokeDasharray="1 1" />
                    <XAxis type="number" domain={[0, 100]} />
                    <YAxis type="category" width={100} dataKey="name" />
                    <Tooltip content={<CustomTooltip />} />
                    <Bar dataKey="Winrate" fill="#8884d8">
                      {data.map((entry, index) => (
                        <Cell key={`cell-${index}`} fill={entry.color} />
                      ))}
                    </Bar>
                  </BarChart>
                </ResponsiveContainer>
              </div>
            </div>
            <div className="row">
              <div id="history">
                <h1>GAME HISTORY</h1>
                <table>
                  <tbody>
                    <tr>
                      <th>Game</th>
                      <th>Role</th>
                      <th>Size</th>
                      <th>Winner</th>
                      <th>Date</th>
                    </tr>
                    {gameHistory
                      .slice(-10)
                      .reverse()
                      .map((g: any, i) => {
                        const date = new Date(g.date);
                        const month = ('00' + (date.getUTCMonth() + 1)).slice(-2);
                        const day = ('00' + date.getUTCDate()).slice(-2);
                        const year = date.getUTCFullYear();

                        return (
                          <tr key={'Game' + g.id}>
                            <td>
                              <Link to={'/game/' + g.id}>#{g.code}</Link>
                            </td>
                            <td>{g.role}</td>
                            <td>{g.size}</td>
                            <td>{g.winner ? 'Resistance' : 'Spy'}</td>
                            <td>
                              {year}-{month}-{day}
                            </td>
                          </tr>
                        );
                      })}
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </AvalonScrollbars>
        {myname === username ? (
          <button
            className="button-b edit-your-profile-with-this"
            type="button"
            onClick={this.onFormToggle}
          >
            <p>Edit Profile</p>
          </button>
        ) : null}
        {this.state.showForm ? (
          <EditProfile
            onExit={this.onFormToggle}
            text="Submit"
            nationality={nationality}
            bio={bio}
            title="EDIT YOUR PROFILE"
            onSelect={this.onEdit}
          />
        ) : null}
      </div>
    );
  }
}

export default connect(mapState, null)(Profile);