import { jwtDecode, JwtPayload } from "jwt-decode";
import { FormEvent, useEffect, useState } from "react";
import { baseUrl, Gender } from "./api";
import { useNavigate } from "react-router";

interface PassToken extends JwtPayload {
  username: string;
  name: string;
  team_id: number;
}

export const Register = () => {
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");
  const [gender, setGender] = useState<Gender>();
  const [number, setNumber] = useState("");
  const [email, setEmail] = useState("");
  const [teamName, setTeamName] = useState("");
  const [teamID, setTeamID] = useState<number>();
  const [password, setPassword] = useState("");
  const [passwordr, setPasswordr] = useState("");
  const [passwordHint, setPasswordHint] = useState("");
  const [token, setToken] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const navigate = useNavigate();

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const token = params.get("token");
    if (token) {
      setToken(token);
      try {
        const payload = jwtDecode<PassToken>(token);
        if (payload.sub === "register") {
          if (payload.team_id) setTeamID(payload.team_id);
        } else {
          setError("not a valid token for registration");
        }
        if (payload.name) setTeamName(payload.name);
      } catch (InvalidTokenError) {
        setError("not a valid token");
      }
    } else setError("no token found");
  }, []);

  function passwordCheck() {
    if (password === passwordr) {
      setPasswordHint("");
    } else setPasswordHint("passwords do not match");
  }

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    if (password === passwordr) {
      const req = new Request(`${baseUrl}api/register`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          display_name: name,
          username: username,
          email: email,
          number: number,
          gender: gender,
          team_id: teamID,
          token: token,
          password: password,
        }),
      });
      let resp: Response;
      try {
        resp = await fetch(req);
      } catch (e) {
        throw new Error(`request failed: ${e}`);
      }
      setLoading(false);

      if (resp.ok) {
        console.log(resp);
        navigate("/", {
          replace: true,
          state: { username: username, password: password },
        });
      }

      if (!resp.ok) {
        const { detail } = await resp.json();
        if (detail) setError(detail);
        else setError("unauthorized");
        throw new Error("Unauthorized");
      }
    } else setError("the passwords did not match");
  }

  return (
    <section className="section">
      <div className="container is-max-tablet">
        <h1 className="title">
          Register {teamName && `in team "${teamName}"`}
        </h1>
        <form onSubmit={handleSubmit}>
          <div className="field">
            <div className="field">
              <label className="label">name</label>
              <div className="control">
                <input
                  className="input"
                  type="text"
                  required
                  value={name}
                  onChange={(e) => {
                    setName(e.target.value);
                    setError("");
                  }}
                />
              </div>
            </div>
            <div className="field">
              <label className="label">username</label>
              <div className="control">
                <input
                  className="input"
                  type="text"
                  required
                  value={username}
                  onChange={(e) => {
                    setUsername(e.target.value);
                    setError("");
                  }}
                />
              </div>
            </div>
            <div className="field">
              <label className="label">password</label>
              <input
                className="input"
                type={"password"}
                id="password"
                name="password"
                placeholder="password"
                minLength={8}
                value={password}
                required
                onChange={(evt) => {
                  setError("");
                  setPassword(evt.target.value);
                }}
              />
            </div>
            <div className="field">
              <label className="label">repeat password</label>
              <input
                className={"input" + (passwordHint ? " is-danger" : "")}
                type={"password"}
                id="password-repeat"
                name="password-repeat"
                placeholder="repeat password"
                minLength={8}
                value={passwordr}
                required
                onChange={(evt) => {
                  setError("");
                  setPasswordr(evt.target.value);
                  passwordCheck();
                }}
              />
              <p className={"help is-danger"}>{passwordHint}</p>
            </div>
            <hr />
            <div className="field">
              <label className="label">
                gender <small>(optional)</small>
              </label>
              <div className="control">
                <div className="select">
                  <select
                    name="gender"
                    value={gender}
                    onChange={(e) => {
                      setGender(e.target.value as Gender);
                      setError("");
                    }}
                  >
                    <option value={undefined}></option>
                    <option value="fmp">FMP</option>
                    <option value="mmp">MMP</option>
                  </select>
                </div>
              </div>
            </div>
            <div className="field">
              <label className="label">
                number <small>(optional)</small>
              </label>
              <div className="control">
                <input
                  className="input"
                  type="text"
                  value={number}
                  onChange={(e) => {
                    setNumber(e.target.value);
                    setError("");
                  }}
                />
              </div>
            </div>
            <div className="field">
              <label className="label">
                email <small>(optional)</small>
              </label>
              <div className="control">
                <input
                  className="input"
                  type="email"
                  value={email}
                  onChange={(e) => {
                    setEmail(e.target.value);
                    setError("");
                  }}
                />
              </div>
              <p className={"help" + (error ? " is-danger" : " is-success")}>
                {error}
              </p>
            </div>
          </div>
          <div className="field is-grouped is-grouped-centered">
            <button className="button is-light is-success">register</button>
          </div>
        </form>
      </div>
    </section>
  );
};
