"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";

import { BottomToast, type BottomToastNotice } from "@/components/bottom-toast";
import {
  buildMailboxEmail,
  isValidMailboxLocalPart,
  normalizeMailboxLocalPart,
} from "@/lib/mailbox-address";

type PrimaryEmailChangeResponse = {
  message?: string;
  ok?: boolean;
  result?: {
    newEmail?: string;
  };
};

type KavenixPrimaryEmailChangeButtonProps = {
  cleanedAt: string | null;
  domain: string;
  domainId: number;
  mailboxEmail: string | null;
};

export function KavenixPrimaryEmailChangeButton({
  cleanedAt,
  domain,
  domainId,
  mailboxEmail,
}: KavenixPrimaryEmailChangeButtonProps) {
  const router = useRouter();
  const [busy, setBusy] = useState(false);
  const [confirmed, setConfirmed] = useState(false);
  const [localPart, setLocalPart] = useState(mailboxEmail?.split("@")[0] ?? "");
  const [open, setOpen] = useState(false);
  const [toast, setToast] = useState<BottomToastNotice | null>(null);
  const currentEmail = mailboxEmail ?? "";
  const normalizedLocalPart = normalizeMailboxLocalPart(localPart);
  const nextEmail = buildMailboxEmail(normalizedLocalPart, domain);
  const canOpen = !cleanedAt && Boolean(currentEmail);
  const canSubmit =
    !busy &&
    confirmed &&
    isValidMailboxLocalPart(normalizedLocalPart) &&
    nextEmail !== currentEmail.trim().toLowerCase();

  useEffect(() => {
    if (!open) {
      return;
    }

    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === "Escape" && !busy) {
        setOpen(false);
        setConfirmed(false);
      }
    }

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [busy, open]);

  useEffect(() => {
    if (!toast) {
      return;
    }

    const timeoutId = window.setTimeout(() => setToast(null), 4600);
    return () => window.clearTimeout(timeoutId);
  }, [toast]);

  function showDialog() {
    if (!canOpen) {
      return;
    }

    setLocalPart(currentEmail.split("@")[0] ?? "");
    setConfirmed(false);
    setOpen(true);
  }

  function closeDialog() {
    if (busy) {
      return;
    }

    setOpen(false);
    setConfirmed(false);
  }

  async function submitChange() {
    if (!canSubmit) {
      return;
    }

    setBusy(true);

    try {
      const response = await fetch(`/api/kavenix/domains/${domainId}/primary-email`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ localPart: normalizedLocalPart }),
      });
      const payload = (await response.json()) as PrimaryEmailChangeResponse;

      if (!response.ok || payload.ok !== true) {
        throw new Error(payload.message || "대표 메일을 변경하지 못했습니다.");
      }

      const changedEmail = payload.result?.newEmail || nextEmail;
      setLocalPart(changedEmail.split("@")[0] ?? normalizedLocalPart);
      setOpen(false);
      setConfirmed(false);
      setToast({
        message: payload.message || "대표 메일을 변경했습니다.",
        tone: "success",
      });
      router.refresh();
    } catch (error) {
      setToast({
        message: error instanceof Error ? error.message : "대표 메일을 변경하지 못했습니다.",
        tone: "error",
      });
    } finally {
      setBusy(false);
    }
  }

  return (
    <>
      <button
        type="button"
        onClick={showDialog}
        disabled={!canOpen}
        className={`inline-flex h-9 items-center justify-center rounded-[10px] px-3 text-[12px] font-semibold transition-colors ${
          canOpen
            ? "cursor-pointer bg-[#edf4ff] text-[#2f6df6] hover:bg-[#dfeaff]"
            : "cursor-not-allowed bg-[#f4f6fa] text-[#9aa8bf]"
        }`}
      >
        대표 메일 변경
      </button>

      {open ? (
        <div
          className="fixed inset-0 z-[10050] flex items-center justify-center bg-[#0f1f38]/34 px-4 py-8 backdrop-blur-[3px]"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target) {
              closeDialog();
            }
          }}
        >
          <section
            role="dialog"
            aria-modal="true"
            aria-labelledby={`primary-email-title-${domainId}`}
            className="w-full max-w-[520px] overflow-hidden rounded-[24px] border border-white/90 bg-white text-left shadow-[0_28px_80px_rgba(18,32,65,0.22)]"
          >
            <div className="px-5 pb-4 pt-5 sm:px-6 sm:pt-6">
              <p className="text-[12px] font-semibold text-[#2f6df6]">대표 계정</p>
              <h2
                id={`primary-email-title-${domainId}`}
                className="mt-1.5 text-[20px] font-semibold tracking-[-0.045em] text-[#16233c]"
              >
                대표 메일 주소 변경
              </h2>
              <p className="mt-2 text-[13px] leading-6 text-[#667894]">
                로그인 계정과 실제 Mailcow 메일함 주소를 함께 변경합니다. 기존 메일, 폴더, 비밀번호는 그대로 유지됩니다.
              </p>

              <div className="mt-5 rounded-[16px] bg-[#f7f9fd] px-4 py-3.5">
                <p className="text-[11px] font-semibold text-[#7d8da7]">현재 대표 메일</p>
                <p className="mt-1 break-all text-[14px] font-semibold text-[#30425f]">{currentEmail}</p>
              </div>

              <label className="mt-4 block" htmlFor={`primary-email-local-part-${domainId}`}>
                <span className="text-[12px] font-semibold text-[#536681]">변경할 주소</span>
                <span className="mt-2 flex h-12 items-center overflow-hidden rounded-[13px] border border-[#dbe5f7] bg-white focus-within:border-[#8eb2ff] focus-within:ring-2 focus-within:ring-[#dce8ff]">
                  <input
                    id={`primary-email-local-part-${domainId}`}
                    value={localPart}
                    onChange={(event) => setLocalPart(event.target.value)}
                    autoComplete="off"
                    spellCheck={false}
                    className="min-w-0 flex-1 bg-transparent px-3.5 text-[14px] font-semibold text-[#1f2d46] outline-none placeholder:text-[#a0aec0]"
                    placeholder="메일 주소 앞부분"
                  />
                  <span className="shrink-0 border-l border-[#e7edf7] bg-[#f8faff] px-3.5 text-[13px] font-medium text-[#607390]">
                    @{domain}
                  </span>
                </span>
              </label>

              {normalizedLocalPart && !isValidMailboxLocalPart(normalizedLocalPart) ? (
                <p className="mt-2 text-[12px] leading-5 text-[#d3484e]">
                  영문 소문자, 숫자, 점(.), 밑줄(_), 하이픈(-)만 사용할 수 있으며 특수문자로 시작하거나 끝낼 수 없습니다.
                </p>
              ) : (
                <p className="mt-2 break-all text-[12px] text-[#70819d]">변경 후: {nextEmail}</p>
              )}
            </div>

            <div className="mx-5 rounded-[15px] border border-[#dce8ff] bg-[#f4f8ff] px-4 py-3.5 text-[12px] leading-5 text-[#4c6182] sm:mx-6">
              변경 후에는 새 주소로 로그인하고 IMAP/SMTP 앱의 사용자 이름도 새 주소로 바꿔야 합니다. 이전 주소는 즉시 폐기되어 더 이상 메일을 수신하지 않습니다.
            </div>

            <label className="mx-5 mt-3 flex cursor-pointer items-start gap-3 px-1 py-2 sm:mx-6">
              <input
                type="checkbox"
                checked={confirmed}
                onChange={(event) => setConfirmed(event.target.checked)}
                className="mt-0.5 h-4 w-4 rounded border-[#cbd6e8] text-[#2f6df6] focus:ring-[#9ebcff]"
              />
              <span className="text-[13px] leading-5 text-[#425573]">
                로그인 주소와 실제 메일함 주소가 함께 변경되는 것을 확인했습니다.
              </span>
            </label>

            <div className="mt-4 flex items-center justify-end gap-2 border-t border-[#edf1f6] px-5 py-4 sm:px-6">
              <button
                type="button"
                onClick={closeDialog}
                disabled={busy}
                className="h-10 cursor-pointer rounded-[10px] px-4 text-[13px] font-semibold text-[#667894] transition-colors hover:bg-[#f3f6fb] disabled:cursor-not-allowed"
              >
                취소
              </button>
              <button
                type="button"
                onClick={submitChange}
                disabled={!canSubmit}
                className={`h-10 rounded-[10px] px-4 text-[13px] font-semibold text-white transition-colors ${
                  canSubmit
                    ? "cursor-pointer bg-[#2f6df6] hover:bg-[#245de3]"
                    : "cursor-not-allowed bg-[#aabce0]"
                }`}
              >
                {busy ? "변경 중..." : "대표 메일 변경"}
              </button>
            </div>
          </section>
        </div>
      ) : null}

      {toast ? <BottomToast notice={toast} onClose={() => setToast(null)} /> : null}
    </>
  );
}
