import { useEffect, useState } from "react";
import { ReactSortable, ReactSortableProps } from "react-sortablejs";
import { apiAuth, User } from "./api";
import { useSession } from "./Session";

type PlayerListProps = Partial<ReactSortableProps<any>> & {
  orderedList?: boolean;
};

function PlayerList(props: PlayerListProps) {
  return (
    <ReactSortable {...props} animation={200}>
      {props.list?.map((item, index) => (
        <div key={item.id} className="item">
          {props.orderedList
            ? index + 1 + ". " + item.display_name
            : item.display_name}
        </div>
      ))}
    </ReactSortable>
  );
}

interface PlayerInfoProps {
  user: User;
  players: User[];
}

export function Chemistry({ user, players }: PlayerInfoProps) {
  const index = players.indexOf(user);
  var otherPlayers = players.slice();
  otherPlayers.splice(index, 1);
  const [playersLeft, setPlayersLeft] = useState<User[]>([]);
  const [playersMiddle, setPlayersMiddle] = useState<User[]>(otherPlayers);
  const [playersRight, setPlayersRight] = useState<User[]>([]);

  useEffect(() => {
    setPlayersMiddle(otherPlayers);
  }, [players]);

  const [dialog, setDialog] = useState("dialog");

  async function handleSubmit() {
    const dialog = document.querySelector("dialog[id='ChemistryDialog']");
    (dialog as HTMLDialogElement).showModal();
    setDialog("sending...");
    let left = playersLeft.map(({ id }) => id);
    let middle = playersMiddle.map(({ id }) => id);
    let right = playersRight.map(({ id }) => id);
    const data = { user: user.id, hate: left, undecided: middle, love: right };
    const response = await apiAuth("chemistry", data, "POST");
    response ? setDialog(response) : setDialog("try sending again");
  }

  return (
    <>
      <div className="container">
        <div className="box three">
          <h2>😬</h2>
          {playersLeft.length < 1 && (
            <span className="grey hint">
              drag people here that you'd rather not play with
            </span>
          )}
          <PlayerList
            list={playersLeft}
            setList={setPlayersLeft}
            group={"shared"}
            className="dragbox"
          />
        </div>
        <div className="box three">
          <h2>🤷</h2>
          <PlayerList
            list={playersMiddle}
            setList={setPlayersMiddle}
            group={"shared"}
            className="middle dragbox"
          />
        </div>
        <div className="box three">
          <h2>😍</h2>
          {playersRight.length < 1 && (
            <span className="grey hint">
              drag people here that you love playing with from best to ... ok
            </span>
          )}
          <PlayerList
            list={playersRight}
            setList={setPlayersRight}
            group={"shared"}
            className="dragbox"
            orderedList
          />
        </div>
      </div>

      <button className="submit" onClick={() => handleSubmit()}>
        💾 <span className="submit_text">submit</span>
      </button>
      <dialog
        id="ChemistryDialog"
        onClick={(event) => {
          event.currentTarget.close();
        }}
      >
        {dialog}
      </dialog>
    </>
  );
}

export function MVP({ user, players }: PlayerInfoProps) {
  const [availablePlayers, setAvailablePlayers] = useState<User[]>(players);
  const [rankedPlayers, setRankedPlayers] = useState<User[]>([]);

  const [dialog, setDialog] = useState("dialog");

  useEffect(() => {
    setAvailablePlayers(players);
  }, [players]);

  async function handleSubmit() {
    const dialog = document.querySelector("dialog[id='MVPDialog']");
    (dialog as HTMLDialogElement).showModal();
    setDialog("sending...");
    let mvps = rankedPlayers.map(({ id }) => id);
    const data = { user: user.id, mvps: mvps };
    const response = await apiAuth("mvps", data, "POST");
    response ? setDialog(response) : setDialog("try sending again");
  }

  return (
    <>
      <div className="container">
        <div className="box two">
          <h2>🥏🏃</h2>
          {availablePlayers.length < 1 && (
            <span className="grey hint">all sorted 👍</span>
          )}
          <PlayerList
            list={availablePlayers}
            setList={setAvailablePlayers}
            group={{
              name: "mvp-shared",
              pull: function (to) {
                return to.el.classList.contains("putclone") ? "clone" : true;
              },
            }}
            className="dragbox"
          />
        </div>
        <div className="box two">
          <h1>🏆</h1>
          {rankedPlayers.length < 1 && (
            <span className="grey hint">
              carefully place as many of the <i>Most Valuable Players</i>{" "}
              (according to your humble opinion) in this box
            </span>
          )}
          <PlayerList
            list={rankedPlayers}
            setList={setRankedPlayers}
            group={{
              name: "mvp-shared",
              pull: function (to) {
                return to.el.classList.contains("putclone") ? "clone" : true;
              },
            }}
            className="dragbox"
            orderedList
          />
        </div>
      </div>

      <button className="submit" onClick={() => handleSubmit()}>
        💾 <span className="submit_text">submit</span>
      </button>
      <dialog
        id="MVPDialog"
        onClick={(event) => {
          event.currentTarget.close();
        }}
      >
        {dialog}
      </dialog>
    </>
  );
}

export default function Rankings() {
  const { user } = useSession();
  const [players, setPlayers] = useState<User[]>([]);
  const [openTab, setOpenTab] = useState("Chemistry");

  async function loadPlayers() {
    try {
      const data = await apiAuth("player/list", null, "GET");
      setPlayers(data as User[]);
    } catch (error) {
      console.error(error);
    }
  }

  useEffect(() => {
    loadPlayers();
  }, []);

  useEffect(() => {
    openPage(openTab, "aliceblue");
  }, [user]);

  function openPage(pageName: string, color: string) {
    // Hide all elements with class="tabcontent" by default */
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
      (tabcontent[i] as HTMLElement).style.display = "none";
    }
    // Remove the background color of all tablinks/buttons
    tablinks = document.getElementsByClassName("tablink");
    for (i = 0; i < tablinks.length; i++) {
      let button = tablinks[i] as HTMLElement;
      button.style.opacity = "50%";
    }
    // Show the specific tab content
    (document.getElementById(pageName) as HTMLElement).style.display = "block";
    // Add the specific color to the button used to open the tab content
    let activeButton = document.getElementById(
      pageName + "Button"
    ) as HTMLElement;
    activeButton.style.fontWeight = "bold";
    activeButton.style.opacity = "100%";
    document.body.style.backgroundColor = color;
    setOpenTab(pageName);
  }

  return (
    <>
      <div className="container navbar">
        <button
          className="tablink"
          id="ChemistryButton"
          onClick={() => openPage("Chemistry", "aliceblue")}
        >
          🧪 Chemistry
        </button>
        <button
          className="tablink"
          id="MVPButton"
          onClick={() => openPage("MVP", "aliceblue")}
        >
          🏆 MVP
        </button>
      </div>

      <span className="grey">
        assign as many or as few players as you want
        <br />
        and don't forget to <b>submit</b> (💾) when you're done :)
      </span>

      <div id="Chemistry" className="tabcontent">
        {user && <Chemistry {...{ user, players }} />}
      </div>
      <div id="MVP" className="tabcontent">
        {user && <MVP {...{ user, players }} />}
      </div>
    </>
  );
}
