/* eslint-disable @typescript-eslint/no-explicit-any */
import { useAtom } from "jotai";
import type { ssroutetype } from "../types";
import { CoolBg, CopyClassLink, Header } from "./DashPage";
import {
  AvailableAdminSymbols,
  copyDXLink,
  randomString,
  secondPathSegment,
} from "../stilltrash/trash";
import { useEffect, useRef, useState } from "react";
import {
  DengiButton,
  DengiEditable,
  DengiYesOrNoDialog,
  LoadingSpinner,
  TextPreloader,
} from "../stilltrash/dengi_components";
import {
  AdminCreateReq,
  AdminRemoveReq,
  AdminUpdateReq,
  ClassReq,
  ClassUpdateNameReq,
  DELETEClassRequest,
} from "../stilltrash/req_mgr";
import {
  BiCheckCircle,
  BiLink,
  BiPlus,
  BiPlusCircle,
  BiTrash,
  BiX,
} from "react-icons/bi";

export default function ClassProfilePage({
  passAtom,
  routeAtom,
  setsetRoute,
}: {
  passAtom: any;
  routeAtom: any;
  setsetRoute: ssroutetype;
}) {
  const [route, setRoute] = useAtom(routeAtom);
  const [pass, _setPass] = useAtom(passAtom);
  const classId = secondPathSegment(route as string);
  if (classId == "") setRoute("/dash/");
  return (
    <>
      <div className="w-full h-screen flex flex-col items-center justify-center gap-5 overflow-x-hidden z-2">
        <div className="w-screen h-screen flex flex-col sm:max-w-125 sm:max-h-[90vh] gap-3">
          <Header {...{ setsetRoute, setRoute }} back />
          <div className="bg-grain bg-zinc-800/50 p-5 items-center rounded-2xl not-md:w-[90%] flex flex-col gap-3">
            <ClassProfileEditor
              {...{ classId }}
              pass={pass as string}
              setRoute={(r) => setsetRoute(setRoute, r)}
            />
          </div>
        </div>
      </div>
      <CoolBg />
    </>
  );
}

function ClassProfileEditor({
  pass,
  classId,
  setRoute,
}: {
  pass: string;
  classId: string;
  setRoute: (r: string) => void;
}) {
  const [classData, setClassData] = useState<Record<string, string> | false>(
    false
  );
  const [adminsData, setAdminsData] = useState<
    Record<string, string>[] | false
  >(false);
  const [dataI, setDataI] = useState(0);
  useEffect(() => {
    ClassReq(pass, classId).then((i) => {
      if (i[0]) {
        setClassData(i[1]["class"]);
        setAdminsData(i[1]["admins"]);
      }
    });
  }, [classId, dataI]);

  return (
    <>
      <h1 className="flex gap-3 text-2xl items-center">
        управление классом <b>{classId}</b>{" "}
        {classData ? <b>({classData.userclassname})</b> : <TextPreloader />}
      </h1>
      <table className="max-w-80">
        <tbody className="*:*:min-w-20 *:*:h-10">
          <tr>
            <td className="">classId</td>
            <td className="font-mono text-center select-all selectable">
              {classId}
            </td>
          </tr>
          <tr>
            <td className="">название</td>
            <td className="w-40">
              <DengiEditable
                value={classData ? classData.userclassname : false}
                onSubmit={async (v, idle) => {
                  idle(true);
                  const r = await ClassUpdateNameReq(
                    pass,
                    classId,
                    v as string
                  );
                  if (r[1] === true) {
                    setClassData((prev) => ({
                      ...prev,
                      userclassname: v as string,
                    }));
                  }
                  idle(false);
                }}
              />
            </td>
          </tr>
        </tbody>
      </table>
      <div className="w-50 mt-5 flex gap-2 items-center justify-center">
        <CopyClassLink {...{ classId }} />
        {classData && (
          <RemoveClassButton
            {...{ classId, pass, setRoute, className: classData.userclassname }}
          />
        )}
      </div>
      <span className="h-px w-[80%] bg-zinc-700 block my-5 "></span>
      <span className="text-xl font-bold block">админы</span>
      <table className="w-full">
        <thead>
          <tr className="*:px-2">
            <th>имя</th>
            <th>id</th>
            <th>уров.</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {adminsData &&
            adminsData.map((i) => (
              <AdminProfileRow
                key={i.adminId}
                {...{
                  adminId: i.adminId,
                  pass: pass as string,
                  adminName: i.adminName,
                  adminLevel: i.adminPrems.toString(),
                  classId,
                  update: () => {
                    setDataI(dataI + 1);
                  },
                  setAdminFrId: (v: string) => {
                    setAdminsData(
                      (prev) =>
                        prev &&
                        prev.map((a: any) =>
                          a.adminId === i.adminId ? { ...a, adminName: v } : a
                        )
                    );
                  },
                }}
              />
            ))}
          {!adminsData && (
            <tr>
              <td>
                <span className="flex w-full justify-center">
                  <TextPreloader />
                </span>
              </td>
              <td>
                <span className="flex w-full justify-center">
                  <TextPreloader />
                </span>
              </td>
              <td>
                <span className="flex w-full justify-center">
                  <TextPreloader />
                </span>
              </td>
              <td>
                <LoadingSpinner size={20} />
              </td>
            </tr>
          )}
        </tbody>
      </table>
      {adminsData && (
        <CreateAdmin
          {...{
            update: () => {
              setDataI(dataI + 1);
            },
            classId,
            pass,
          }}
        />
      )}
    </>
  );
}

function AdminProfileRow({
  adminId,
  pass,
  adminName,
  classId,
  setAdminFrId,
  adminLevel,
  update,
}: {
  adminId: string;
  pass: string;
  adminName: string;
  classId: string;
  setAdminFrId: (v: string) => void;
  adminLevel: string;
  update: () => void;
}) {
  return (
    <tr className="h-12">
      <td className="px-2">
        <DengiEditable
          value={adminName}
          onSubmit={async (v, i) => {
            i(true);
            const r = await AdminUpdateReq(pass, adminId, "name", v as string);
            if (r[1] === true) {
              setAdminFrId(v as string);
            }
            i(false);
          }}
        />
      </td>
      <td className="px-2">
        <DengiEditable value={adminId} password={true} disabled />
      </td>
      <td className="text-center">
        <AdminLevelPicker
          {...{
            value: adminLevel,
            pass,
            adminId,
          }}
        />
      </td>
      <td className="inline-flex gap-1 items-center justify-center">
        <CopyAdminLink {...{ classId, adminId }} />
        <RemoveAdminButton {...{ adminId, pass, adminName, update }} />
      </td>
    </tr>
  );
}

const AdminLevelPicker = ({
  adminId,
  pass,
  value,
}: {
  adminId: string;
  pass: string;
  value: string;
}) => {
  const [val, setVal] = useState(value);
  const [idle, setIdle] = useState(false);
  return (
    <form className="flex items-center justify-center">
      {!idle ? (
        <select
          className="bg-zinc-800 p-1.5 rounded-xl text-center"
          value={val}
          onChange={async (e) => {
            setIdle(true);
            const v = (e.target as HTMLSelectElement).value;
            const r = await AdminUpdateReq(pass, adminId, "level", v);
            if (r[1] === true) {
              setVal(v);
            }
            setIdle(false);
          }}
        >
          <option value="-1">-1</option>
          <option value="1">1</option>
          <option value="2">2</option>
        </select>
      ) : (
        <LoadingSpinner size={20} />
      )}
    </form>
  );
};

const RemoveAdminButton = ({
  adminId,
  pass,
  adminName,
  update,
}: {
  adminId: string;
  pass: string;
  adminName: string;
  update: () => void;
}) => {
  const [showDiag, setShowDiag] = useState(false);
  const [deleting, setDeleting] = useState(false);

  return (
    <>
      <DengiYesOrNoDialog
        show={showDiag}
        content={{
          //@ts-ignore
          message: (
            <p>
              вы точно хотите удалить админа <b>{adminName}</b>?
            </p>
          ),
          yesBtn: "да",
          noBtn: "нет",
          yesIcon: <BiTrash />,
          noIcon: <BiX size={20} />,
          bgDissmis: true,
          yesBtnStyle: "bg-red-500! text-white! md:hover:bg-red-600!",
        }}
        onAnswer={async (answ: boolean) => {
          setShowDiag(false);
          if (answ) {
            setDeleting(true);
            const r = await AdminRemoveReq(pass, adminId);
            if (r[1] === true) {
              update();
            }
          }
        }}
      />
      <DengiButton
        onClick={() => {
          if (deleting) return;
          setShowDiag(true);
        }}
      >
        {deleting ? <LoadingSpinner size={20} /> : <BiTrash />}
      </DengiButton>
    </>
  );
};

const RemoveClassButton = ({
  pass,
  classId,
  setRoute,
  className,
}: {
  pass: string;
  classId: string;
  setRoute: (r: string) => void;
  className: string;
}) => {
  const [showDiag, setShowDiag] = useState(false);
  const [deleting, setDeleting] = useState(false);

  return (
    <>
      <DengiYesOrNoDialog
        show={showDiag}
        content={{
          //@ts-ignore
          message: (
            <p>
              вы точно хотите удалить класс{" "}
              <b>
                {classId} ({className})
              </b>
              ?
            </p>
          ),
          yesBtn: "да",
          noBtn: "нет",
          yesIcon: <BiTrash />,
          noIcon: <BiX size={20} />,
          bgDissmis: true,
          yesBtnStyle: "bg-red-500! text-white! md:hover:bg-red-600!",
        }}
        onAnswer={async (answ: boolean) => {
          setShowDiag(false);
          if (answ) {
            setDeleting(true);
            const r = await DELETEClassRequest(pass, classId);
            if (r[1] === true) {
              setRoute("/dash/class");
            }
            setDeleting(false);
          }
        }}
      />
      <DengiButton
        onClick={() => {
          if (deleting) return;
          setShowDiag(true);
        }}
      >
        {deleting ? <LoadingSpinner size={20} /> : <BiTrash />}
      </DengiButton>
    </>
  );
};

const CopyAdminLink = ({
  classId,
  adminId,
}: {
  classId: string;
  adminId: string;
}) => {
  const [linkCopied, setLinkCopied] = useState(false);
  const copy = () => {
    copyDXLink(classId, adminId).then((a) => {
      if (a) {
        setLinkCopied(true);
        setTimeout(() => {
          setLinkCopied(false);
        }, 2000);
      }
    });
  };
  return (
    <>
      <DengiButton onClick={() => copy()}>
        {linkCopied ? <BiCheckCircle /> : <BiLink />}
      </DengiButton>
    </>
  );
};

function CreateAdmin({
  pass,
  classId,
  update,
}: {
  pass: string;
  update: () => void;
  classId: string;
}) {
  const [creating, setCreating] = useState(false);
  const [adminId, setAdminId] = useState("");
  const [adminName, setAdminName] = useState("");
  const [levelVal, setLevelVal] = useState("1");
  const [locked, setLocked] = useState(false);
  const form = useRef(null);
  return (
    <>
      <div className="flex w-full gap-1">
        <span className="w-full" />
        {creating && (
          <form
            className="flex gap-2 max-w-100"
            ref={form}
            onSubmit={async (e) => {
              e.preventDefault();
              if (locked || adminId.length < 5) return;
              setLocked(true);
              const c = await AdminCreateReq(
                pass,
                classId,
                adminId,
                adminName,
                levelVal
              );
              if (c[1] == true) {
                update();
                setCreating(false);
              }
              setLocked(false);
            }}
          >
            <input
              className="bg-zinc-900 rounded-2xl border border-zinc-500/50 px-2 max-w-35"
              placeholder="имя"
              required
              value={adminName}
              disabled={locked}
              maxLength={50}
              onInput={(e) =>
                setAdminName((e.target as HTMLInputElement).value.trimStart())
              }
            />
            <input
              className="bg-zinc-900 rounded-2xl border border-zinc-500/50 px-2 max-w-35"
              placeholder="adminId"
              value={adminId}
              required
              disabled={locked}
              maxLength={20}
              minLength={5}
              min={5}
              onInput={(e) => {
                let val = (e.target as HTMLInputElement).value;
                let nval = "";
                val.split("").forEach((i) => {
                  if (AvailableAdminSymbols.includes(i)) {
                    nval = nval + i;
                  }
                });
                (e.target as HTMLInputElement).value = nval;
                setAdminId(nval);
              }}
            />
            <select
              className="bg-zinc-800 p-1.5 rounded-xl text-center"
              value={levelVal}
              required
              onChange={async (e) => {
                const v = (e.target as HTMLSelectElement).value;
                setLevelVal(v);
              }}
            >
              <option value="-1">-1</option>
              <option value="1">1</option>
              <option value="2">2</option>
            </select>
            <button>
              <DengiButton>
                {locked ? <LoadingSpinner size={20} /> : <BiPlus />}
              </DengiButton>
            </button>
          </form>
        )}
        <DengiButton
          disabled={locked}
          onClick={() => {
            setCreating(!creating);
            setAdminName("");
            setAdminId(randomString(8, AvailableAdminSymbols));
          }}
        >
          <span className={`${creating ? "rotate-45" : ""} transition`}>
            <BiPlusCircle />
          </span>
        </DengiButton>
      </div>
    </>
  );
}
