import { useState, useRef, useEffect } from "react";
import { useAtom } from "jotai";
import { motion, AnimatePresence } from "motion/react";
import Logo from "../assets/logo.svg";
import { Switch, LoadingSpinner } from "../trash/trash-components";
import { BiHide, BiShow, BiSolidErrorCircle, BiBlock } from "react-icons/bi";
import { LoginReq, AdminReq } from "../trash/req_mgr";
import { API_BASE_URL } from "../App";
import { b64d } from "../trash/helpers";
import { AvailableAdminSymbols, AvailableSymbols } from "../trash/dengi";

export function LoginPage({
  classIDAtom,
  adminAtom,
  setsetRoute,
  routeAtom,
  secondPathSegment,
}) {
  const [enteredId, setEnteredId] = useState("");
  const [isAdmin, setIsAdmin] = useState(false);
  const [adminEnteredId, setEnteredAId] = useState("");
  const [userId, setUserId] = useAtom(classIDAtom);
  const [route, setRoute] = useAtom(routeAtom);
  const [isLogining, setLogining] = useState(false); // disables all inputs, shows
  const [errorText, setErrorText] = useState("");
  const [adminId, setAdminId] = useAtom(adminAtom);
  /** @type {string} */
  let autolog = secondPathSegment(route);

  const formSubmit = async (
    event = null,
    cid = enteredId,
    aid = adminEnteredId,
    isa = isAdmin
  ) => {
    event && event.preventDefault();
    setLogining(true);
    setErrorText("");
    const l = await LoginReq(API_BASE_URL, cid);
    if (l[0] === 1) {
      if (!isa) {
        setUserId(l[1]["classid"]);
        setsetRoute(setRoute, "/app");
      } else {
        const al = await AdminReq(API_BASE_URL, aid);
        // console.log(al);
        if (al[0] === 1) {
          // yes, I know that check must go on backend, but im stupid lazy piece of shit 💀💀💀
          // TODO: FIX LATER
          if (l[1]["classid"] == al[1]["adminClass"]) {
            setUserId(l[1]["classid"]);
            setAdminId(al[1]["adminId"]);
            setsetRoute(setRoute, "/app");
          } else {
            // you are not from here
            // console.log(al);
            setErrorText("админ не найден");
          }
        } else {
          setErrorText(al[1]);
        }
      }
    } else {
      setErrorText(l[1]);
    }

    setLogining(false);
  };

  if (userId !== "") {
    setsetRoute(setRoute, "/app");
    return;
  } else if (adminId !== "") {
    setAdminId(""); // NOTE: adminId with no userID is insecure
  }
  // eslint-disable-next-line react-hooks/rules-of-hooks
  useEffect(() => {
    // NOTE: this hook shouldn't called if user already
    // loggined, so i doesn't violating rules of hooks

    if (autolog && autolog != "") {
      let name, admin;
      if (autolog.includes(";")) {
        // /name;admin
        let a = autolog.split(";");
        name = a[0];
        admin = b64d(a[1]);
      } else {
        // /name
        name = autolog;
      }
      setEnteredId(name);
      admin && setEnteredAId(admin);
      formSubmit(null, name, admin, Boolean(admin));
    }
  }, [autolog]);

  return (
    <div className="w-full h-screen flex flex-col items-center justify-center bg-gradient-to-br from-white/50 to-transparent to-50% gap-5 overflow-hidden">
      <AnimatePresence mode="popLayout">
        {errorText.length > 0 && (
          <motion.div
            initial={{ y: 50, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: 50, opacity: 0 }}
            layout="position"
            className="p-2 bg-gradient-to-r from-zinc-900 to-white/40 text-white rounded-xl w-[90vw] max-w-[600px] flex gap-2 items-center justify-between"
          >
            <BiSolidErrorCircle className="fill-red-300" size={20} />
            <span>
              ошибка:{" "}
              <span className="font-extrabold font-mono selectable">
                {errorText}
              </span>
            </span>
            <div className="cursor-pointer" onClick={() => setErrorText("")}>
              <BiBlock size={20} />
            </div>
          </motion.div>
        )}
      </AnimatePresence>
      <motion.div
        className="flex flex-col rounded-2xl w-[90vw]  items-center justify-center py-3 max-w-[600px] bg-grain focus-within:border-white/10 border border-transparent transition-colors relative"
        initial={{
          y: 30,
          opacity: 0,
        }}
        layout="position"
        animate={{ y: 0, opacity: 1 }}
      >
        <img src={Logo} alt="logo dengi" width={200} />
        <h1 className="text-zinc-600">добро пожаловать.</h1>
        <h2 className="text-3xl font-light">вход</h2>
        <form
          action="#"
          className="mt-2 flex flex-col gap-3 *:outline-none *:border *:border-transparent *:focus:border-white"
          onSubmit={formSubmit}
        >
          <input
            type="text"
            name="d"
            autoComplete="off"
            value={enteredId}
            onInput={async (event) => {
              /** @type {string} */
              let val = event.target.value;
              let nval = "";
              val.split("").forEach((i) => {
                // console.log(i);
                if (AvailableSymbols.includes(i)) {
                  // console.log(true);
                  nval = nval + i;
                }
              });
              nval = nval.replaceAll(" ", "").toUpperCase().substring(0, 10);
              event.target.value = nval;
              setEnteredId(nval);
            }}
            className="bg-zinc-800/50 p-2 rounded-2xl w-full min-w-[206px]"
            placeholder="id класса"
            disabled={isLogining}
            minLength={3}
          />
          <span className="w-full flex gap-2 items-center justify-center ">
            <Switch
              type="checkbox"
              onChange={(e) => setIsAdmin(e)}
              disabled={isLogining}
              name=""
            />
            админка
          </span>
          <CoolInputWithHide
            {...{ enabled: isAdmin, setEnteredAId, isLogining, adminEnteredId }}
          />
          <CoolLoginButton display={enteredId.length > 2} />
        </form>
        {enteredId.length > 2 && !isLogining && (
          <div className="text-xs my-3 text-zinc-500">
            входя, вы принимаете{" "}
            <a
              target="_blank"
              href="./terms.html"
              className="text-white border-b border-transparent lg:hover:border-white transition-colors"
            >
              пользовательское соглашение
            </a>
          </div>
        )}
      </motion.div>
      <AnimatePresence mode="popLayout">
        {isLogining && (
          <motion.div
            initial={{ y: -40, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            className="p-2 w-[90vw] max-w-[600px] border-2 rounded-xl border-zinc-500 flex gap-2 items-center justify-center hover:border-white transition-colors bg-grain"
            layout="position"
          >
            <LoadingSpinner size={15} />
            загрузка...
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

function CoolLoginButton({ display, isLogining }) {
  const logbuttonRef = useRef(null);

  return (
    <AnimatePresence mode="popLayout">
      {display && (
        <motion.button
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          ref={logbuttonRef}
          exit={{ y: 40, opacity: 0, rotate: 20 }}
          onMouseMove={(e) => {
            const rect = e.target.getBoundingClientRect();
            e.target.style.setProperty(
              "--tw-gradient-via-position",
              `${((e.clientX - rect.left) / rect.width) * 100}%`
            );
          }}
          className="bg-gradient-to-r  from-neutral-900 to-zinc-900 p-2 rounded-xl not-disabled:cursor-pointer transition-colors duration-200 not-disabled:hover:via-white via-30% not-disabled:hover:text-black disabled:via-white disabled:via-0%! disabled:animate-pulse"
          disabled={isLogining}
        >
          войти
        </motion.button>
      )}
    </AnimatePresence>
  );
}
function CoolInputWithHide({
  isLogining,
  setEnteredAId,
  adminEnteredId,
  enabled,
}) {
  const [showAId, setShowAID] = useState(false);
  return (
    <AnimatePresence mode="popLayout">
      {enabled && (
        <motion.div
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          exit={{ y: 10, opacity: 0 }}
          className="flex *:outline-none *:border *:border-transparent *:focus:border-white"
        >
          <input
            type={!showAId ? "password" : "text"}
            name="ad"
            className="bg-zinc-800/50 p-2 rounded-l-2xl"
            placeholder="id админки"
            autoComplete="off"
            disabled={isLogining}
            value={adminEnteredId}
            required
            onInput={(e) => {
              /** @type {string}*/
              let val = e.target.value;
              let nval = "";
              val.split("").forEach((i) => {
                if (AvailableAdminSymbols.includes(i)) {
                  nval = nval + i;
                }
              });
              e.target.value = nval;
              setEnteredAId(nval);
            }}
          />
          <motion.div
            layoutCrossfade
            className={
              " p-2 rounded-r-2xl border-l border-l-zinc-500 transition-colors " +
              (showAId ? " bg-white" : " bg-zinc-800/50")
            }
            onClick={() => setShowAID(!showAId)}
          >
            {!showAId ? (
              <BiShow color="#fff" size={23} />
            ) : (
              <BiHide color="#000" size={23} />
            )}
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}
