import { jwtDecode, JwtPayload } from "jwt-decode";
import { useEffect, useState } from "react";
import { apiAuth, baseUrl } from "./api";
import { useNavigate } from "react-router";
import { Eye, EyeSlash } from "./Icons";
import { useSession } from "./Session";

interface SetPassToken extends JwtPayload {
  name: string;
}

export const SetPassword = () => {
  const [name, setName] = useState("after getting your token.");
  const [username, setUsername] = useState("");
  const [currentPassword, setCurrentPassword] = useState("");
  const [password, setPassword] = useState("");
  const [passwordr, setPasswordr] = useState("");
  const [token, setToken] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const [visible, setVisible] = useState(false);
  const navigate = useNavigate();
  const { user } = useSession();

  useEffect(() => {
    if (user) {
      setUsername(user.username);
      setName(user.display_name);
    } else {
      const params = new URLSearchParams(window.location.search);
      const token = params.get("token");
      if (token) {
        setToken(token);
        try {
          const payload = jwtDecode<SetPassToken>(token);
          if (payload.name) setName(payload.name);
          else if (payload.sub) setName(payload.sub);
          else setName("Mr. I-have-no Token");
          payload.sub && setUsername(payload.sub);
        } catch (InvalidTokenError) {
          setName("Mr. I-have-no-valid Token");
        }
      }
    }
  }, []);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (password === passwordr) {
      setLoading(true);
      if (user) {
        const resp = await apiAuth(
          "player/change_password",
          { current_password: currentPassword, new_password: password },
          "POST"
        );
        setLoading(false);
        if (resp.detail) setError(resp.detail);
        else {
          setError(resp);
          setTimeout(() => navigate("/"), 2000);
        }
      } else {
        const req = new Request(`${baseUrl}api/set_password`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ 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) {
          if (resp.status === 401) {
            const { detail } = await resp.json();
            if (detail) setError(detail);
            else setError("unauthorized");
            throw new Error("Unauthorized");
          }
        }
      }
    } else setError("passwords are not the same");
  }

  return (
    <>
      {user ? (
        <h2> change your password </h2>
      ) : (
        <h2>
          set your password,
          <br />
          {name}
        </h2>
      )}
      {!user && username && (
        <span>
          your username is: <i>{username}</i>
        </span>
      )}
      <form onSubmit={handleSubmit}>
        <div
          style={{
            display: "flex",
            alignItems: "center",
          }}
        >
          <div
            style={{
              marginLeft: "48px",
              marginRight: "8px",
              display: "flex",
              justifyContent: "center",
              flexDirection: "column",
            }}
          >
            {user && (
              <div>
                <input
                  type={visible ? "text" : "password"}
                  id="password"
                  name="password"
                  placeholder="current password"
                  minLength={8}
                  value={currentPassword}
                  required
                  onChange={(evt) => {
                    setError("");
                    setCurrentPassword(evt.target.value);
                  }}
                />
                <hr
                  style={{
                    margin: "8px",
                    borderStyle: "inset",
                    display: "block",
                  }}
                />
              </div>
            )}
            <div>
              <input
                type={visible ? "text" : "password"}
                id="password"
                name="password"
                placeholder="password"
                minLength={8}
                value={password}
                required
                onChange={(evt) => {
                  setError("");
                  setPassword(evt.target.value);
                }}
              />
            </div>
            <div>
              <input
                type={visible ? "text" : "password"}
                id="password-repeat"
                name="password-repeat"
                placeholder="repeat password"
                minLength={8}
                value={passwordr}
                required
                onChange={(evt) => {
                  setError("");
                  setPasswordr(evt.target.value);
                }}
              />
            </div>
          </div>
          <div
            style={{
              background: "unset",
              fontSize: "xx-large",
              cursor: "pointer",
            }}
            onClick={() => setVisible(!visible)}
          >
            {visible ? <Eye /> : <EyeSlash />}
          </div>
        </div>
        <div>{error && <span style={{ color: "red" }}>{error}</span>}</div>
        <button type="submit" value="login" style={{ fontSize: "small" }}>
          submit
        </button>
        {loading && <span className="loader" />}
      </form>
    </>
  );
};
