"use client";

import { useEffect, useEffectEvent, useState, type FormEvent } from "react";
import { BottomToast } from "@/components/bottom-toast";
import { StaticUiLocalizer } from "@/components/static-ui-localizer";
import type { DomainSetupAssistanceSummary } from "@/lib/domain-setup-assistance";
import type { DomainSetupPromotionPreview } from "@/lib/domain-setup-promotions";
import {
  DOMAIN_SETUP_ASSISTANCE_NET_FEE,
  getDomainSetupAssistanceNetAmount,
} from "@/lib/pricing";

const providerOptions = [
  "가비아",
  "카페24",
  "후이즈",
  "호스팅KR",
  "닷네임코리아",
  "GoDaddy",
  "아임웹",
  "퍼스트몰",
  "기타",
] as const;

const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
const ASSISTANCE_DRAFT_STORAGE_KEY = "official-mail:domain-assistance-draft";

type AssistanceDraft = {
  accountIdentifier: string;
  accountPassword: string;
  consented: boolean;
  customProvider: string;
  note: string;
  notificationEmail: string;
  paymentConsented: boolean;
  promotionCode: string;
  provider: (typeof providerOptions)[number];
};

type PaymentMethodState = {
  label: string | null;
  registered: boolean;
};

function CloseIcon() {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      className="h-5 w-5"
      aria-hidden="true"
    >
      <path d="m6 6 12 12" />
      <path d="m18 6-12 12" />
    </svg>
  );
}

function AssistanceIcon({ className = "h-5 w-5" }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      strokeLinejoin="round"
      className={className}
      aria-hidden="true"
    >
      <path d="M5.2 8.1 12 3.8l6.8 4.3v7.8L12 20.2l-6.8-4.3z" />
      <path d="m8.5 11.8 2.2 2.2 4.8-4.8" />
    </svg>
  );
}

function statusLabel(status: DomainSetupAssistanceSummary["status"]) {
  if (status === "in_progress") {
    return "설정 진행 중";
  }

  if (status === "completed") {
    return "설정 완료";
  }

  if (status === "cancelled") {
    return "신청 취소";
  }

  return "신청 접수됨";
}

function formatDate(value: string) {
  const date = new Date(value);

  if (Number.isNaN(date.getTime())) {
    return "";
  }

  return new Intl.DateTimeFormat("ko-KR", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date);
}

function displayStatusMessage(value: string | null) {
  return value?.replace(/\*\*/g, "").trim() || "별도의 취소 사유가 등록되지 않았습니다.";
}

export function DomainSetupAssistance({
  canRequest,
  defaultNotificationEmail,
  domain,
}: {
  canRequest: boolean;
  defaultNotificationEmail: string;
  domain: string;
}) {
  const [request, setRequest] = useState<DomainSetupAssistanceSummary | null>(null);
  const [cancellationReasonOpen, setCancellationReasonOpen] = useState(false);
  const [formOpen, setFormOpen] = useState(false);
  const [termsOpen, setTermsOpen] = useState(false);
  const [provider, setProvider] = useState<(typeof providerOptions)[number]>("가비아");
  const [customProvider, setCustomProvider] = useState("");
  const [accountIdentifier, setAccountIdentifier] = useState("");
  const [accountPassword, setAccountPassword] = useState("");
  const [notificationEmail, setNotificationEmail] = useState(
    defaultNotificationEmail.trim().toLowerCase(),
  );
  const [note, setNote] = useState("");
  const [consented, setConsented] = useState(false);
  const [paymentConsented, setPaymentConsented] = useState(false);
  const [promotionCode, setPromotionCode] = useState("");
  const [promotionPreview, setPromotionPreview] =
    useState<DomainSetupPromotionPreview | null>(null);
  const [checkingPromotion, setCheckingPromotion] = useState(false);
  const [paymentMethod, setPaymentMethod] = useState<PaymentMethodState>({
    label: null,
    registered: false,
  });
  const [showPassword, setShowPassword] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [toast, setToast] = useState<{ message: string; tone: "error" | "success" } | null>(
    null,
  );
  const activeRequest = request?.status === "pending" || request?.status === "in_progress";
  const displayedFinalFee = promotionPreview
    ? getDomainSetupAssistanceNetAmount(promotionPreview.finalAmount)
    : DOMAIN_SETUP_ASSISTANCE_NET_FEE;
  const displayedDiscount = DOMAIN_SETUP_ASSISTANCE_NET_FEE - displayedFinalFee;

  const applyDraft = (draft: AssistanceDraft) => {
    setProvider(draft.provider);
    setCustomProvider(draft.customProvider);
    setAccountIdentifier(draft.accountIdentifier);
    setAccountPassword(draft.accountPassword);
    setNotificationEmail(draft.notificationEmail);
    setNote(draft.note);
    setConsented(draft.consented);
    setPaymentConsented(draft.paymentConsented);
    setPromotionCode(draft.promotionCode ?? "");
    setPromotionPreview(null);
  };

  const resetForm = () => {
    setAccountIdentifier("");
    setAccountPassword("");
    setNotificationEmail(defaultNotificationEmail.trim().toLowerCase());
    setNote("");
    setConsented(false);
    setPaymentConsented(false);
    setPromotionCode("");
    setPromotionPreview(null);
  };

  const loadAssistanceOverview = async (signal?: AbortSignal) => {
    const response = await fetch("/api/mailbox/domain-setup-assistance", {
      cache: "no-store",
      signal,
    });

    if (!response.ok) {
      return null;
    }

    const payload = (await response.json()) as {
      paymentMethod?: PaymentMethodState;
      request?: DomainSetupAssistanceSummary | null;
    };
    setRequest(payload.request ?? null);
    setPaymentMethod(payload.paymentMethod ?? { label: null, registered: false });
    return payload;
  };

  const submitDraft = async (draft: AssistanceDraft) => {
    const normalizedProvider =
      draft.provider === "기타" ? draft.customProvider.trim() : draft.provider;
    const response = await fetch("/api/mailbox/domain-setup-assistance", {
      body: JSON.stringify({
        accountIdentifier: draft.accountIdentifier,
        accountPassword: draft.accountPassword,
        consented: draft.consented,
        note: draft.note,
        notificationEmail: draft.notificationEmail,
        paymentConsented: draft.paymentConsented,
        promotionCode: draft.promotionCode,
        provider: normalizedProvider,
      }),
      headers: { "Content-Type": "application/json" },
      method: "POST",
    });
    const payload = (await response.json().catch(() => null)) as {
      message?: string;
      request?: DomainSetupAssistanceSummary;
    } | null;

    if (!response.ok || !payload?.request) {
      throw new Error(payload?.message || "설정 대행 신청 접수에 실패했습니다.");
    }

    setRequest(payload.request);
    resetForm();
    window.sessionStorage.removeItem(ASSISTANCE_DRAFT_STORAGE_KEY);
    setFormOpen(false);
    setToast({
      message:
        payload.request.feeAmount === 0
          ? "프로모션이 적용되어 결제 없이 설정 대행 신청이 접수되었습니다."
          : `신청이 접수되었습니다. 연결 완료 후 설정 대행비 ${getDomainSetupAssistanceNetAmount(payload.request.feeAmount).toLocaleString("ko-KR")}원(VAT 별도)이 등록한 카드로 결제됩니다.`,
      tone: "success",
    });
  };

  const checkPromotion = async (code: string) => {
    const normalizedCode = code.trim().toUpperCase();

    if (!normalizedCode) {
      setPromotionPreview(null);
      throw new Error("프로모션 코드를 입력해주세요.");
    }

    setCheckingPromotion(true);

    try {
      const response = await fetch("/api/mailbox/domain-setup-assistance/promotion", {
        body: JSON.stringify({ code: normalizedCode }),
        headers: { "Content-Type": "application/json" },
        method: "POST",
      });
      const payload = (await response.json().catch(() => null)) as {
        message?: string;
        promotion?: DomainSetupPromotionPreview;
      } | null;

      if (!response.ok || !payload?.promotion) {
        throw new Error(payload?.message || "프로모션 코드를 확인하지 못했습니다.");
      }

      setPromotionCode(payload.promotion.code);
      setPromotionPreview(payload.promotion);
      return payload.promotion;
    } finally {
      setCheckingPromotion(false);
    }
  };

  const submitDraftAfterBilling = useEffectEvent(async (draft: AssistanceDraft) => {
    await submitDraft(draft);
  });

  useEffect(() => {
    const controller = new AbortController();

    void (async () => {
      const searchParams = new URLSearchParams(window.location.search);
      const isAssistanceBillingReturn =
        searchParams.get("billingIntent") === "domain-assistance";
      const registrationSucceeded =
        searchParams.get("success") === "billing-registration-returned";
      const registrationFailed =
        searchParams.get("error") === "billing-registration-failed";
      const storedDraft = window.sessionStorage.getItem(ASSISTANCE_DRAFT_STORAGE_KEY);
      let draft: AssistanceDraft | null = null;

      if (isAssistanceBillingReturn && storedDraft) {
        try {
          draft = JSON.parse(storedDraft) as AssistanceDraft;
          applyDraft(draft);
          setFormOpen(true);
        } catch {
          window.sessionStorage.removeItem(ASSISTANCE_DRAFT_STORAGE_KEY);
        }
      }

      if (isAssistanceBillingReturn) {
        const url = new URL(window.location.href);
        url.searchParams.delete("billingIntent");
        url.searchParams.delete("success");
        url.searchParams.delete("error");
        window.history.replaceState(null, "", `${url.pathname}${url.search}${url.hash}`);
      }

      if (registrationFailed && draft) {
        await loadAssistanceOverview(controller.signal).catch(() => null);
        setToast({
          message: "결제카드 등록이 완료되지 않았습니다. 카드 등록 후 다시 신청해주세요.",
          tone: "error",
        });
        return;
      }

      const attempts = registrationSucceeded && draft ? 15 : 1;

      for (let attempt = 0; attempt < attempts; attempt += 1) {
        const overview = await loadAssistanceOverview(controller.signal).catch(() => null);

        if (overview?.paymentMethod?.registered && registrationSucceeded && draft) {
          setSubmitting(true);
          try {
            await submitDraftAfterBilling(draft);
          } catch (error) {
            setToast({
              message:
                error instanceof Error ? error.message : "설정 대행 신청 접수에 실패했습니다.",
              tone: "error",
            });
          } finally {
            setSubmitting(false);
          }
          return;
        }

        if (attempt < attempts - 1) {
          await new Promise((resolve) => window.setTimeout(resolve, 1000));
        }
      }

      if (registrationSucceeded && draft) {
        setToast({
          message: "결제카드 등록을 확인 중입니다. 잠시 후 신청 버튼을 다시 눌러주세요.",
          tone: "error",
        });
      }
    })();

    return () => controller.abort();
  }, []);

  useEffect(() => {
    if (!formOpen && !termsOpen) {
      return;
    }

    const previousOverflow = document.body.style.overflow;
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key !== "Escape") {
        return;
      }

      if (termsOpen) {
        setTermsOpen(false);
      } else {
        setFormOpen(false);
      }
    };

    document.body.style.overflow = "hidden";
    window.addEventListener("keydown", handleKeyDown);

    return () => {
      document.body.style.overflow = previousOverflow;
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [formOpen, termsOpen]);

  useEffect(() => {
    if (!formOpen && !termsOpen) {
      return;
    }

    const channel = (
      window as Window & {
        ChannelIO?: (command: string) => void;
      }
    ).ChannelIO;

    if (typeof channel !== "function") {
      return;
    }

    channel("hideChannelButton");
    return () => channel("showChannelButton");
  }, [formOpen, termsOpen]);

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

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

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    if (submitting) {
      return;
    }

    const normalizedProvider = provider === "기타" ? customProvider.trim() : provider;

    if (!normalizedProvider || !accountIdentifier.trim() || !accountPassword.trim()) {
      setToast({ message: "도메인 구매처와 계정정보를 모두 입력해주세요.", tone: "error" });
      return;
    }

    const normalizedNotificationEmail = notificationEmail.trim().toLowerCase();

    if (!normalizedNotificationEmail) {
      setToast({ message: "완료 알림을 받을 이메일 주소를 입력해주세요.", tone: "error" });
      return;
    }

    if (!EMAIL_PATTERN.test(normalizedNotificationEmail)) {
      setToast({ message: "올바른 이메일 주소를 입력해주세요.", tone: "error" });
      return;
    }

    if (!consented) {
      setToast({ message: "개인정보 수집·이용에 동의해주세요.", tone: "error" });
      return;
    }

    if (!paymentConsented) {
      setToast({ message: "연결 완료 후 자동결제에 동의해주세요.", tone: "error" });
      return;
    }

    let appliedPromotion = promotionPreview;

    if (promotionCode.trim()) {
      try {
        appliedPromotion = await checkPromotion(promotionCode);
      } catch (error) {
        setPromotionPreview(null);
        setToast({
          message: error instanceof Error ? error.message : "프로모션 코드를 확인해주세요.",
          tone: "error",
        });
        return;
      }
    }

    const draft: AssistanceDraft = {
      accountIdentifier,
      accountPassword,
      consented,
      customProvider,
      note,
      notificationEmail: normalizedNotificationEmail,
      paymentConsented,
      promotionCode: appliedPromotion?.code ?? "",
      provider,
    };

    setSubmitting(true);

    try {
      const latestOverview = await loadAssistanceOverview();

      if (!latestOverview?.paymentMethod?.registered) {
        window.sessionStorage.setItem(ASSISTANCE_DRAFT_STORAGE_KEY, JSON.stringify(draft));
        const response = await fetch("/api/payments/toss-pay/billing/register", {
          body: JSON.stringify({ intent: "domain-assistance" }),
          headers: { "Content-Type": "application/json" },
          method: "POST",
        });
        const payload = (await response.json().catch(() => null)) as {
          message?: string;
          registration?: { checkoutUri?: string };
        } | null;
        const checkoutUri = payload?.registration?.checkoutUri;

        if (!response.ok || !checkoutUri) {
          throw new Error(payload?.message || "결제카드 등록 화면을 열지 못했습니다.");
        }

        window.location.assign(checkoutUri);
        return;
      }

      await submitDraft(draft);
    } catch (error) {
      setToast({
        message: error instanceof Error ? error.message : "설정 대행 신청 접수에 실패했습니다.",
        tone: "error",
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <StaticUiLocalizer>
      <>
      <div className="mx-auto w-full max-w-[880px] px-3 pb-14 sm:px-6 sm:pb-16 lg:px-8 lg:pb-20">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div className="flex min-w-0 items-start gap-3">
            <span className="mt-0.5 inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[#2f6df6] text-white shadow-[0_10px_26px_rgba(47,109,246,0.24)]">
              <AssistanceIcon className="h-[17px] w-[17px]" />
            </span>
            <div className="min-w-0">
              <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
                <p className="text-[14px] font-semibold tracking-[-0.03em] text-[#263957]">
                  그래도 잘 모르시겠나요?
                </p>
                <span className="text-[12px] font-semibold text-[#2f6df6]">
                  1회 {DOMAIN_SETUP_ASSISTANCE_NET_FEE.toLocaleString("ko-KR")}원
                  <span className="ml-1 text-[10px] font-medium text-[#70819d]">(VAT 별도)</span>
                </span>
              </div>
              <p className="mt-1 text-[12px] leading-5 text-[#667b9d]">
                도메인 연결 설정 대행 서비스도 제공하고 있어요. 연결 완료 후 등록된 카드로 설정비가 결제됩니다.
              </p>
              {request ? (
                <div className="mt-1.5 flex flex-wrap items-center gap-x-1.5 gap-y-1 text-[12px] font-semibold">
                  <span className={request.status === "cancelled" ? "text-[#d64a5f]" : "text-[#526784]"}>
                    {statusLabel(request.status)}
                  </span>
                  <span className="text-[#8a99b2]">·</span>
                  <span className="text-[#526784]">{request.provider}</span>
                  <span className="text-[#8a99b2]">·</span>
                  <span className="text-[#526784]">{formatDate(request.requestedAt)}</span>
                  {request.status === "cancelled" ? (
                    <button
                      type="button"
                      onClick={() => setCancellationReasonOpen(true)}
                      className="ml-1 cursor-pointer text-[#2f6df6] underline decoration-[#a9c4ff] underline-offset-[3px] transition-colors hover:text-[#1f58d8]"
                    >
                      취소 사유 보기
                    </button>
                  ) : null}
                </div>
              ) : null}
            </div>
          </div>
          <button
            type="button"
            disabled={activeRequest || !canRequest}
            onClick={() => setFormOpen(true)}
            className="ml-12 h-9 shrink-0 cursor-pointer rounded-[9px] bg-[#162f62] px-3.5 text-[12px] font-semibold text-white shadow-[0_8px_22px_rgba(22,47,98,0.18)] transition-all hover:-translate-y-px hover:bg-[#203e78] disabled:cursor-not-allowed disabled:bg-[#b8c4d8] disabled:shadow-none sm:ml-0"
          >
            {activeRequest
              ? statusLabel(request.status)
              : canRequest
                ? "연결 설정 맡기기"
                : "도메인 저장 후 신청"}
          </button>
        </div>
      </div>

      {formOpen ? (
        <div
          className="fixed inset-0 z-[10020] flex items-end justify-center bg-[#111827]/32 p-0 backdrop-blur-[2px] sm:items-center sm:p-5"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target) {
              setFormOpen(false);
            }
          }}
        >
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="domain-assistance-title"
            className="max-h-[92dvh] w-full overflow-y-auto rounded-t-[22px] bg-white shadow-[0_30px_80px_rgba(18,32,65,0.24)] sm:max-w-[620px] sm:rounded-[22px]"
          >
            <div className="relative isolate flex items-start justify-between gap-4 overflow-hidden border-b border-[#dfe8f7] bg-[radial-gradient(circle_at_86%_20%,rgba(47,109,246,0.14),transparent_32%),linear-gradient(115deg,#f8fbff_0%,#eef5ff_100%)] px-5 py-5 sm:px-6">
              <div aria-hidden="true" className="pointer-events-none absolute -right-8 -top-14 h-32 w-32 rounded-full border border-[#b8d0ff]/45" />
              <div className="relative flex min-w-0 items-start gap-3">
                <span className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[#2f6df6] text-white shadow-[0_10px_24px_rgba(47,109,246,0.22)]">
                  <AssistanceIcon className="h-[18px] w-[18px]" />
                </span>
                <div className="min-w-0">
                  <h2 id="domain-assistance-title" className="text-[20px] font-semibold tracking-[-0.04em] text-[#16233c]">
                    도메인 연결 설정 대행
                  </h2>
                  <p className="mt-1.5 text-[13px] leading-6 text-[#70819d]">
                    {domain || "등록된 도메인"}의 DNS 연결을 대신 설정합니다.
                  </p>
                </div>
              </div>
              <button
                type="button"
                aria-label="설정 대행 신청 닫기"
                onClick={() => setFormOpen(false)}
                className="inline-flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full text-[#8190a8] transition-colors hover:bg-[#f3f6fb] hover:text-[#2f6df6]"
              >
                <CloseIcon />
              </button>
            </div>

            <form onSubmit={handleSubmit} autoComplete="off" className="px-5 py-5 sm:px-6">
              <div className="-mx-5 -mt-5 border-b border-[#e5edf9] bg-[#f8fbff] px-5 py-4 sm:-mx-6 sm:px-6">
                <div className="flex flex-wrap items-center gap-2">
                  <p className="text-[14px] font-semibold text-[#263957]">설정 대행비</p>
                  {promotionPreview ? (
                    <span className="text-[12px] text-[#8a99b2] line-through">
                      {DOMAIN_SETUP_ASSISTANCE_NET_FEE.toLocaleString("ko-KR")}원
                    </span>
                  ) : null}
                  <span className="text-[14px] font-semibold text-[#2f6df6]">
                    {displayedFinalFee.toLocaleString("ko-KR")}원
                    {displayedFinalFee > 0 ? "(VAT 별도)" : ""}
                  </span>
                  {promotionPreview && displayedDiscount > 0 ? (
                    <span className="text-[12px] font-semibold text-[#238653]">
                      {displayedDiscount.toLocaleString("ko-KR")}원 할인
                    </span>
                  ) : null}
                </div>
                <p className="mt-1 text-[12px] leading-5 text-[#667b9d]">
                  설정 대행비는 {DOMAIN_SETUP_ASSISTANCE_NET_FEE.toLocaleString("ko-KR")}원(VAT 별도)입니다. 신청할 때는 결제되지 않으며, DNS 연결 완료 확인 후 등록한 카드로 자동 결제됩니다.
                </p>
              </div>

              <div className="mt-5 flex items-center justify-between gap-4 rounded-[12px] border border-[#dce7fa] bg-[#f7faff] px-4 py-3.5">
                <div className="min-w-0">
                  <p className="text-[13px] font-semibold text-[#263957]">결제카드</p>
                  <p className="mt-1 truncate text-[12px] text-[#70819d]">
                    {paymentMethod.registered
                      ? paymentMethod.label || "등록된 결제수단"
                      : "신청 버튼을 누르면 카드 등록부터 진행합니다."}
                  </p>
                </div>
                <span className={`shrink-0 text-[12px] font-semibold ${paymentMethod.registered ? "text-[#238653]" : "text-[#2f6df6]"}`}>
                  {paymentMethod.registered ? "등록 완료" : "등록 필요"}
                </span>
              </div>

              <div className="mt-3">
                <label htmlFor="domain-assistance-promotion" className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                  프로모션 코드 <span className="font-normal text-[#8a99b2]">선택</span>
                </label>
                <div className="flex gap-2">
                  <input
                    id="domain-assistance-promotion"
                    value={promotionCode}
                    maxLength={64}
                    autoCapitalize="characters"
                    spellCheck={false}
                    onChange={(event) => {
                      setPromotionCode(event.target.value.toUpperCase());
                      setPromotionPreview(null);
                    }}
                    placeholder="프로모션 코드 입력"
                    className="h-11 min-w-0 flex-1 rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] font-semibold uppercase tracking-[0.03em] text-[#1a2943] outline-none placeholder:font-normal placeholder:tracking-normal placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                  <button
                    type="button"
                    disabled={checkingPromotion || !promotionCode.trim()}
                    onClick={() => {
                      void checkPromotion(promotionCode)
                        .then((promotion) => {
                          setToast({
                            message: `${promotion.label} 프로모션이 적용되었습니다.`,
                            tone: "success",
                          });
                        })
                        .catch((error) => {
                          setPromotionPreview(null);
                          setToast({
                            message: error instanceof Error ? error.message : "프로모션 코드를 확인해주세요.",
                            tone: "error",
                          });
                        });
                    }}
                    className="om-btn-secondary h-11 shrink-0 cursor-pointer rounded-[10px] px-4 text-[13px] shadow-none disabled:cursor-not-allowed disabled:opacity-50"
                  >
                    {checkingPromotion ? "확인 중" : "적용"}
                  </button>
                </div>
                {promotionPreview ? (
                  <p className="mt-2 text-[12px] font-semibold text-[#238653]">
                    {promotionPreview.label} · 최종 공급가 {displayedFinalFee.toLocaleString("ko-KR")}원{displayedFinalFee > 0 ? "(VAT 별도)" : ""}
                  </p>
                ) : null}
              </div>

              <div className="grid gap-4 py-5 sm:grid-cols-2">
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">도메인 구매처·관리처</span>
                  <select
                    value={provider}
                    onChange={(event) => setProvider(event.target.value as (typeof providerOptions)[number])}
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3 text-[14px] text-[#1a2943] outline-none focus:border-[#bcd1ff]"
                  >
                    {providerOptions.map((option) => (
                      <option key={option} value={option}>{option}</option>
                    ))}
                  </select>
                </label>
                {provider === "기타" ? (
                  <label className="block">
                    <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">관리처 이름</span>
                    <input
                      required
                      value={customProvider}
                      onChange={(event) => setCustomProvider(event.target.value)}
                      placeholder="관리 서비스를 입력하세요"
                      className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                    />
                  </label>
                ) : (
                  <div className="hidden sm:block" aria-hidden="true" />
                )}
                <div className="sm:col-span-2">
                  <p className="text-[12px] leading-5 text-[#667b9d]">
                    오피셜메일 로그인 정보가 아니라, 위에서 선택한 도메인 구매처·관리처에 로그인할 때 사용하는 계정을 입력해주세요.
                  </p>
                </div>
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">도메인 구매처 로그인 아이디</span>
                  <input
                    required
                    name="domain-provider-account-identifier"
                    autoComplete="off"
                    value={accountIdentifier}
                    onChange={(event) => setAccountIdentifier(event.target.value)}
                    placeholder={`${provider === "기타" ? "관리처" : provider} 로그인 아이디`}
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                </label>
                <div className="block">
                  <label htmlFor="domain-assistance-password" className="mb-2 block text-[13px] font-semibold text-[#4f6284]">도메인 구매처 로그인 비밀번호</label>
                  <div className="relative">
                    <input
                      id="domain-assistance-password"
                      name="domain-provider-account-password"
                      required
                      type={showPassword ? "text" : "password"}
                      autoComplete="new-password"
                      value={accountPassword}
                      onChange={(event) => setAccountPassword(event.target.value)}
                      placeholder="가능하면 임시 비밀번호를 입력해주세요"
                      className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 pr-14 text-[14px] text-[#1a2943] outline-none placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                    />
                    <button
                      type="button"
                      aria-label={showPassword ? "비밀번호 숨기기" : "비밀번호 보기"}
                      onClick={() => setShowPassword((current) => !current)}
                      className="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer text-[12px] font-semibold text-[#2f6df6]"
                    >
                      {showPassword ? "숨김" : "보기"}
                    </button>
                  </div>
                </div>
                <label className="block sm:col-span-2">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                    완료 알림 이메일
                  </span>
                  <input
                    required
                    type="email"
                    inputMode="email"
                    autoComplete="email"
                    value={notificationEmail}
                    maxLength={320}
                    onChange={(event) => setNotificationEmail(event.target.value)}
                    placeholder="name@example.com"
                    className="h-11 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 text-[14px] text-[#1a2943] outline-none placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                  <span className="mt-1.5 block text-[12px] leading-5 text-[#7a8ba5]">
                    가입할 때 인증한 보조 이메일을 기본으로 불러옵니다. 알림받을 주소가 다르면 수정해주세요.
                  </span>
                </label>
              </div>

              <label className="block border-t border-[#edf1f6] pt-5">
                <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">진행 시 참고할 내용 <span className="font-normal text-[#8a99b2]">선택</span></span>
                <textarea
                  value={note}
                  onChange={(event) => setNote(event.target.value)}
                  placeholder="2단계 인증 사용 여부나 전달할 내용을 입력하세요."
                  className="min-h-[96px] w-full resize-y rounded-[10px] border border-[#dbe5f7] bg-white px-3.5 py-3 text-[14px] leading-6 text-[#1a2943] outline-none placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                />
              </label>

              <div className="mt-4 border-y border-[#edf1f6] py-4">
                <p className="text-[12px] leading-5 text-[#667792]">
                  가능하면 임시 비밀번호를 설정해 주세요. 계정정보는 암호화해 보관하며, 처리 완료·취소 즉시 또는 접수 후 최대 30일 안에 폐기합니다.
                </p>
                <div className="mt-3 flex items-start gap-2.5">
                  <input
                    id="domain-assistance-consent"
                    type="checkbox"
                    checked={consented}
                    onChange={(event) => setConsented(event.target.checked)}
                    className="mt-0.5 h-[16px] w-[16px] shrink-0 rounded-[4px] border-[#cfd7e4] text-[#2f6df6] focus:ring-[#d7e5ff]"
                  />
                  <label htmlFor="domain-assistance-consent" className="min-w-0 text-[12px] leading-5 text-[#526784]">
                    개인정보 수집·이용, 완료 안내 이메일 발송 및 계정정보 임시 보관에 동의합니다.
                  </label>
                  <button
                    type="button"
                    aria-label="개인정보 수집·이용 동의 내용 보기"
                    onClick={() => setTermsOpen(true)}
                    className="ml-auto shrink-0 cursor-pointer text-[12px] font-semibold text-[#2f6df6] hover:underline"
                  >
                    보기
                  </button>
                </div>
                <div className="mt-3 flex items-start gap-2.5">
                  <input
                    id="domain-assistance-payment-consent"
                    type="checkbox"
                    checked={paymentConsented}
                    onChange={(event) => setPaymentConsented(event.target.checked)}
                    className="mt-0.5 h-[16px] w-[16px] shrink-0 rounded-[4px] border-[#cfd7e4] text-[#2f6df6] focus:ring-[#d7e5ff]"
                  />
                  <label htmlFor="domain-assistance-payment-consent" className="min-w-0 text-[12px] leading-5 text-[#526784]">
                    DNS 연결 완료 시 프로모션 적용 후 최종 설정 대행비 {displayedFinalFee.toLocaleString("ko-KR")}원{displayedFinalFee > 0 ? "(VAT 별도)" : ""}이 처리되는 것에 동의합니다.
                  </label>
                </div>
              </div>

              <div className="mt-5 flex justify-end gap-2">
                <button
                  type="button"
                  onClick={() => setFormOpen(false)}
                  className="om-btn-secondary h-10 cursor-pointer rounded-[10px] px-4 text-[13px] shadow-none"
                >
                  닫기
                </button>
                <button
                  type="submit"
                  disabled={submitting}
                  className="om-btn-primary h-10 cursor-pointer rounded-[10px] px-4 text-[13px] shadow-none disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {submitting
                    ? paymentMethod.registered
                      ? "신청 접수 중..."
                      : "결제카드 등록 준비 중..."
                    : paymentMethod.registered
                      ? "설정 대행 신청"
                      : "결제카드 등록 후 신청"}
                </button>
              </div>
            </form>
          </div>
        </div>
      ) : null}

      {cancellationReasonOpen && request?.status === "cancelled" ? (
        <div
          className="fixed inset-0 z-[10030] flex items-end justify-center bg-[#111827]/32 p-0 backdrop-blur-[2px] sm:items-center sm:p-5"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target) {
              setCancellationReasonOpen(false);
            }
          }}
        >
          <div
            role="dialog"
            aria-modal="true"
            aria-labelledby="domain-assistance-cancellation-title"
            className="w-full rounded-t-[22px] bg-white shadow-[0_30px_80px_rgba(18,32,65,0.24)] sm:max-w-[520px] sm:rounded-[22px]"
          >
            <div className="flex items-start justify-between gap-4 border-b border-[#edf1f6] px-5 py-5 sm:px-6">
              <div className="min-w-0">
                <p className="text-[12px] font-semibold text-[#d64a5f]">신청 취소</p>
                <h2 id="domain-assistance-cancellation-title" className="mt-1 text-[18px] font-semibold tracking-[-0.04em] text-[#16233c]">
                  취소 사유
                </h2>
              </div>
              <button
                type="button"
                aria-label="취소 사유 닫기"
                onClick={() => setCancellationReasonOpen(false)}
                className="inline-flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full text-[#8190a8] transition-colors hover:bg-[#f3f6fb] hover:text-[#2f6df6]"
              >
                <CloseIcon />
              </button>
            </div>
            <div className="px-5 py-5 sm:px-6">
              <p className="whitespace-pre-wrap text-[13px] leading-6 text-[#526784]">
                {displayStatusMessage(request.statusMessage)}
              </p>
            </div>
            <div className="flex justify-end border-t border-[#edf1f6] px-5 py-4 sm:px-6">
              <button
                type="button"
                onClick={() => setCancellationReasonOpen(false)}
                className="om-btn-primary h-9 cursor-pointer rounded-[9px] px-4 text-[12px] shadow-none"
              >
                확인
              </button>
            </div>
          </div>
        </div>
      ) : null}

      {termsOpen ? (
        <div
          className="fixed inset-0 z-[10040] flex items-end justify-center bg-[#111827]/38 p-0 backdrop-blur-[2px] sm:items-center sm:p-5"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target) {
              setTermsOpen(false);
            }
          }}
        >
          <div role="dialog" aria-modal="true" aria-labelledby="domain-assistance-terms-title" className="max-h-[86dvh] w-full overflow-y-auto rounded-t-[22px] bg-white shadow-[0_30px_80px_rgba(18,32,65,0.24)] sm:max-w-[560px] sm:rounded-[22px]">
            <div className="flex items-start justify-between gap-4 border-b border-[#edf1f6] px-5 py-5 sm:px-6">
              <h2 id="domain-assistance-terms-title" className="text-[18px] font-semibold tracking-[-0.04em] text-[#16233c]">
                설정 대행 개인정보·자동결제 동의
              </h2>
              <button type="button" aria-label="동의 내용 닫기" onClick={() => setTermsOpen(false)} className="inline-flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full text-[#8190a8] hover:bg-[#f3f6fb] hover:text-[#2f6df6]">
                <CloseIcon />
              </button>
            </div>
            <div className="space-y-5 px-5 py-5 text-[13px] leading-6 text-[#526784] sm:px-6">
              <div>
                <p className="font-semibold text-[#263957]">수집·이용 목적</p>
                <p className="mt-1">도메인 DNS 연결 설정 대행, 신청자 확인, 결제수단 확인, 보완 요청·진행 상황 및 완료 결과 안내</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">수집 항목</p>
                <p className="mt-1">도메인명, 도메인 구매처·관리처, 관리 계정 아이디와 비밀번호, 완료 알림 이메일, 신청자가 입력한 참고 내용</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">안내 방법</p>
                <p className="mt-1">접수, 결제 결과, 보완 요청, 진행 상황 및 완료 결과를 신청자가 입력한 알림 이메일로 안내할 수 있습니다. 해당 주소는 광고성 정보 발송에 사용하지 않습니다.</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">설정비와 결제 시점</p>
                <p className="mt-1">설정 대행비는 도메인 1개 연결 작업당 {DOMAIN_SETUP_ASSISTANCE_NET_FEE.toLocaleString("ko-KR")}원이며 VAT는 별도입니다. 유효한 프로모션 코드가 적용되면 할인 후 공급가에 VAT가 반영됩니다. 신청 단계에서는 결제되지 않으며, 담당자가 DNS 연결 완료를 확인한 시점에 도메인 대표 관리자 계정에 등록된 결제수단으로 자동 결제됩니다.</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">결제 실패·취소</p>
                <p className="mt-1">자동결제가 실패하면 설정 대행은 완료 처리되지 않으며 재결제가 필요할 수 있습니다. 작업 시작 전에는 신청을 취소할 수 있고, 연결 완료 및 결제 이후 취소·환불은 실제 작업 이력과 관계 법령 및 서비스 약관에 따라 처리합니다.</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">보유·이용 기간</p>
                <p className="mt-1">관리 계정 아이디와 비밀번호는 설정 완료 또는 신청 취소 즉시 폐기하며, 처리가 끝나지 않은 경우에도 접수일로부터 최대 30일까지만 암호화 보관합니다. 알림 이메일과 신청자가 입력한 참고 내용은 업무 완료 또는 취소 후 90일 동안 보관한 뒤 폐기합니다. 관계 법령상 별도 보존 의무가 있는 정보는 해당 기간 동안 분리 보관할 수 있습니다.</p>
              </div>
              <div>
                <p className="font-semibold text-[#263957]">동의 거부 권리</p>
                <p className="mt-1">동의를 거부할 수 있으며, 이 경우 설정 대행 신청은 이용할 수 없습니다. 직접 DNS를 설정하거나 채널톡 안내는 계속 이용할 수 있습니다.</p>
              </div>
              <p className="border-t border-[#edf1f6] pt-4 text-[12px] text-[#70819d]">
                보안을 위해 기존 비밀번호 대신 임시 비밀번호 사용을 권장하며, 설정 완료 안내를 받은 뒤 즉시 변경해주세요.
              </p>
            </div>
            <div className="border-t border-[#edf1f6] px-5 py-4 text-right sm:px-6">
              <button type="button" onClick={() => setTermsOpen(false)} className="om-btn-primary h-10 cursor-pointer rounded-[10px] px-4 text-[13px] shadow-none">
                확인
              </button>
            </div>
          </div>
        </div>
      ) : null}

      {toast ? (
        <BottomToast
          key={`${toast.tone}-${toast.message}`}
          className="z-[10060]"
          notice={toast}
          onClose={() => setToast(null)}
        />
      ) : null}
      </>
    </StaticUiLocalizer>
  );
}
