import apiClient from "@/services/api";
import { cn } from "@/utils/class-merge";
import { EyeIcon, EyeSlashIcon, XCircleIcon } from "@heroicons/react/24/outline";
import { FunctionComponent } from "preact";
import { useEffect, useState } from "preact/hooks";
import {
  InputSwitch,
  InputSwitchPassThroughMethodOptions,
  InputSwitchPassThroughOptions,
} from "primereact/inputswitch";
import { SubmitHandler, useForm } from "react-hook-form";
import Button from "./ui/Button";
import ModalWindow, { ModalWindowProps } from "./ui/Modal";

interface ISettings {
  login: string;
  oldPassword: string;
  newPassword: string;
  tgId: string;
}

export interface IAPIResponse {
  profile: IAPIProfile;
}

export interface IAPIProfile {
  username: string;
  email: string;
  status: string;
  avatar_url: string;
  telegram_notifications: boolean;
  telegram_chat_id: string;
}

export interface IAPIUpdateSettingsResponse {
  success: boolean;
  username: string;
  email: string;
  avatar_url: string;
  password_changed: boolean;
}

const SwitchStyles: InputSwitchPassThroughOptions = {
  root: ({ props }: InputSwitchPassThroughMethodOptions) => ({
    className: cn("inline-block relative", "w-12 h-7", {
      "opacity-60 select-none pointer-events-none cursor-default": props.disabled,
    }),
  }),
  input: {
    className: cn("absolute appearance-none top-0 left-0 size-full p-0 m-0 opacity-0 z-10 outline-none cursor-pointer"),
  },
  slider: ({ props }: InputSwitchPassThroughMethodOptions) => ({
    className: cn(
      "absolute cursor-pointer top-0 left-0 right-0 bottom-0 border border-transparent",
      "transition-colors duration-200 rounded-2xl",
      "focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] ",
      "before:absolute before:content-'' before:top-1/2 before:bg-white  before:w-5 before:h-5 before:left-1 before:-mt-2.5 before:rounded-full before:transition-duration-200",
      {
        "bg-gray-200 hover:bg-gray-300": !props.checked,
        "bg-[rgba(251,194,199,0.53)] before:transform before:translate-x-5": props.checked,
      }
    ),
  }),
};

const ModalSettings: FunctionComponent<ModalWindowProps> = ({ isOpen, setIsOpen, onClose, ...rest }) => {
  const { handleSubmit, register, setValue, reset } = useForm<ISettings>({
    defaultValues: {
      login: "",
      oldPassword: "",
      newPassword: "",
    },
    mode: "onChange",
  });

  const changeSettings: SubmitHandler<ISettings> = async (data: ISettings) => {
    interface IReq {
      username?: string;
      current_password?: string;
      password?: string;
    }
    const req: IReq = {
      username: data.login || undefined,
      current_password: data.oldPassword || undefined,
      password: data.newPassword || undefined,
    };

    const response = await apiClient<IAPIUpdateSettingsResponse>("/api/settings/edit_profile/", {
      method: "PATCH",
      body: JSON.stringify(req),
    });
    if (!response.success) console.error("Error changing settings");

    if (enableNotification && data.tgId) {
      await apiClient("/api/settings/save_chat_id/", {
        method: "PATCH",
        body: JSON.stringify({ telegram_chat_id: data.tgId }),
      });
      if (oldEnabledNotif !== enableNotification) {
        await apiClient("/api/settings/toggle_telegram_notifications/", { method: "PATCH" });
      }
    }

    handleClose();
  };

  const [enableNotification, setEnableNotification] = useState(false);
  const [login, setLogin] = useState("");
  const [showOldPassword, setShowOldPassword] = useState(false);
  const [showNewPassword, setShowNewPassword] = useState(false);
  const [oldEnabledNotif, setOldEnabledNotif] = useState(false);
  const [tgId, setTgId] = useState("");

  useEffect(() => {
    const getSettings = async () => {
      const response = await apiClient<IAPIResponse>("/api/settings/view_settings/", { method: "GET" });
      setEnableNotification(response.profile.telegram_notifications);
      setOldEnabledNotif(response.profile.telegram_notifications);
      setLogin(response.profile.username);
      setTgId(response.profile.telegram_chat_id);
    };
    if (isOpen) getSettings();
  }, [isOpen]);

  const handleClose = () => {
    setIsOpen!(false);
    setEnableNotification(false);
    reset();
    if (onClose) onClose();
  };

  return (
    <ModalWindow setIsOpen={setIsOpen} isOpen={isOpen} onClose={handleClose} {...rest} className="h-fit! md:w-[40%]!">
      <form onSubmit={handleSubmit(changeSettings)} class="flex w-full flex-col gap-4">
        <div class="flex flex-col items-start gap-2">
          <span class="ms-5 text-sm">Имя</span>
          <div class="flex w-full flex-row items-center rounded-[4rem] bg-[rgba(251,194,199,0.53)] px-5 py-3 leading-8">
            <input class="flex-1 outline-0" {...register("login")} placeholder={login} />
            <XCircleIcon class="size-6 cursor-pointer" onClick={() => setValue("login", "")} />
          </div>
        </div>
        <div class="flex flex-col items-start gap-2">
          <span class="ms-5 text-sm">Старый пароль</span>
          <div class="flex w-full flex-row items-center gap-1 rounded-[4rem] bg-[rgba(251,194,199,0.53)] px-5 py-3 leading-8">
            <input
              class="flex-1 outline-0"
              {...register("oldPassword")}
              placeholder="Новый пароль"
              type={showOldPassword ? "text" : "password"}
            />
            {showOldPassword ? (
              <EyeIcon class="size-6 cursor-pointer" onClick={() => setShowOldPassword(false)} />
            ) : (
              <EyeSlashIcon class="size-6 cursor-pointer" onClick={() => setShowOldPassword(true)} />
            )}
            <XCircleIcon class="size-6 cursor-pointer" onClick={() => setValue("oldPassword", "")} />
          </div>
        </div>
        <div class="flex flex-col items-start gap-2">
          <span class="ms-5 text-sm">Новый пароль</span>
          <div class="flex w-full flex-row items-center gap-1 rounded-[4rem] bg-[rgba(251,194,199,0.53)] px-5 py-3 leading-8">
            <input
              class="flex-1 outline-0"
              {...register("newPassword", {
                minLength: { value: 8, message: "Пароль должен быть не менее 8 символов" },
              })}
              placeholder="Новый пароль"
              type={showNewPassword ? "text" : "password"}
            />
            {showNewPassword ? (
              <EyeIcon class="size-6 cursor-pointer" onClick={() => setShowNewPassword(false)} />
            ) : (
              <EyeSlashIcon class="size-6 cursor-pointer" onClick={() => setShowNewPassword(true)} />
            )}
            <XCircleIcon class="size-6 cursor-pointer" onClick={() => setValue("newPassword", "")} />
          </div>
        </div>
        <div class="flex flex-row items-center justify-between rounded-[4rem] px-5 py-4 ring-3 ring-[rgba(251,194,199,0.53)]">
          <span>Уведомления</span>
          <InputSwitch
            pt={SwitchStyles}
            checked={enableNotification}
            onChange={(e) => setEnableNotification(e.value)}
          />
        </div>
        <div class={cn({ hidden: !enableNotification })}>
          <div class="flex flex-col items-start gap-2">
            <span class="ms-5 text-sm">Telegram ID</span>
            <div class="flex w-full flex-row items-center rounded-[4rem] px-5 py-3 leading-8 ring-2 ring-[rgba(206,232,251,0.7)]">
              <input class="flex-1 outline-0" {...register("tgId")} placeholder={tgId} />
              <XCircleIcon class="size-6 cursor-pointer" onClick={() => setValue("tgId", "")} />
            </div>
          </div>
        </div>
        <Button type="submit">Сохранить</Button>
      </form>
    </ModalWindow>
  );
};

ModalSettings.displayName = "ModalSettings";

export default ModalSettings;
