"use client";

import Link from "next/link";
import { useActionState, useEffect, useRef, useState, type ReactNode } from "react";
import { MailAiAssistPanel } from "@/components/mail-ai-assist-panel";
import { CloseIconButton } from "@/components/close-icon-button";
import {
  MailMembersPanel,
  type MemberMailboxViewState,
} from "@/components/mail-members-panel";
import { TossBillingModule } from "@/components/toss-billing-module";
import {
  completeMailSetupAction,
  regenerateMailSetupDkimAction,
  updateMailboxDisplayNameAction,
  updateMailSetupDkimUsageAction,
  updateRepresentativePasswordAction,
  verifyMailSetupAction,
} from "@/app/actions/session";
import { SubmitButton } from "@/components/submit-button";
import {
  countMailBillingSeatsFromManagedMembers,
  MAIL_GROWTH_PLAN_PRICE_PER_MEMBER,
  type MailPlanSummary,
} from "@/lib/mail-billing";
import type {
  MailBillingHistoryState,
  MailBillingTab,
} from "@/lib/mail-billing-history";
import type { MailBillingCancellationOverview } from "@/lib/billing-cancellation";
import type {
  MailAppOverview,
  MailSetupOverview,
} from "@/lib/official-mail";
import type {
  MailAiAssistOverview,
  ManagedMailboxMember,
} from "@/lib/mail-automation";
import type {
  MailBillingHistoryPage,
  MailBillingOverview,
} from "@/lib/toss-pay";
import { OFFICIAL_MAIL_GUIDE_URL } from "@/lib/mail-urls";

export type MailSetupSection =
  | "account"
  | "domain"
  | "assistant"
  | "members"
  | "billing";

type MailSetupWorkspaceProps = {
  section: MailSetupSection;
  overview: MailSetupOverview | null;
  aiAssistOverview: MailAiAssistOverview | null;
  billingOverview: MailBillingOverview | null;
  billingCancellationOverview: MailBillingCancellationOverview | null;
  billingHistoryPage: MailBillingHistoryPage | null;
  billingHistoryState: MailBillingHistoryState;
  billingTab: MailBillingTab;
  managedMembers: ManagedMailboxMember[];
  memberMailboxView: MemberMailboxViewState | null;
  mailData: MailAppOverview | null;
  planSummary: MailPlanSummary;
  canManageBilling: boolean;
  sessionCompanyName: string;
  sessionDisplayName: string;
  sessionDomain: string;
  sessionEmail: string;
  sessionMailbox: string;
};

type DnsRow = {
  key: string;
  type: string;
  host: string;
  value: string;
  ttl: string;
  priorityValue: string;
  statusLabel: string;
  statusTone: "neutral" | "success" | "error";
  copyValue: string;
};

type RepresentativePasswordActionState = {
  status: "idle" | "success" | "error";
  message: string;
};

type MailboxDisplayNameActionState = {
  status: "idle" | "success" | "error";
  message: string;
};

type DkimKeySize = 1024 | 2048;

const INITIAL_REPRESENTATIVE_PASSWORD_ACTION_STATE: RepresentativePasswordActionState = {
  status: "idle",
  message: "",
};

const INITIAL_MAILBOX_DISPLAY_NAME_ACTION_STATE: MailboxDisplayNameActionState = {
  status: "idle",
  message: "",
};

const SECTION_META: Record<
  MailSetupSection,
  { label: string; title: string; description: string }
> = {
  account: {
    label: "계정 설정",
    title: "계정 설정",
    description: "대표 계정 정보와 비밀번호를 관리합니다.",
  },
  domain: {
    label: "도메인 연결",
    title: "도메인 연결",
    description: "도메인 연결 상태와 DNS 값을 확인합니다.",
  },
  assistant: {
    label: "AI 어시스트",
    title: "AI 어시스트 브릿지",
    description: "메일 요약 알림과 외부 답장 릴레이를 설정합니다.",
  },
  members: {
    label: "멤버 관리",
    title: "멤버 관리",
    description: "팀 메일함을 추가하고 관리합니다.",
  },
  billing: {
    label: "결제 및 구독",
    title: "결제 및 구독",
    description:
      "결제수단은 미리 등록할 수 있고, 성장 플랜이 활성화되면 대표 메일과 추가 멤버를 포함한 팀 인원 기준으로 월 정기결제가 진행됩니다.",
  },
};

const SETTINGS_NAV_SECTIONS: MailSetupSection[] = [
  "account",
  "domain",
  "assistant",
  "members",
  "billing",
];

function buildSettingsProfileInitials(displayName: string, companyName: string, email: string) {
  const source = (displayName || companyName || email.split("@")[0] || "OM")
    .replace(/\s+/g, "")
    .trim();

  if (!source) {
    return "OM";
  }

  return source.slice(0, Math.min(2, source.length)).toUpperCase();
}

function normalizeDomainPreview(value: string) {
  return value
    .trim()
    .toLowerCase()
    .replace(/^https?:\/\//, "")
    .replace(/\/$/, "");
}

function normalizeLocalPartPreview(value: string) {
  return value.trim().replace(/\s+/g, "").toLowerCase();
}

function formatDateLabel(value: string | null) {
  if (!value) {
    return "아직 검증되지 않았습니다.";
  }

  const date = new Date(value);
  return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(
    date.getDate(),
  ).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(
    date.getMinutes(),
  ).padStart(2, "0")} 검증`;
}

function formatCurrency(value: number) {
  return `${value.toLocaleString("ko-KR")}원`;
}

function formatRecordHost(host: string, domain: string) {
  return host === domain ? "@" : host;
}

function getMxSpfRecordHost(domain: string, mxHostname: string) {
  const normalizedDomain = domain.trim().toLowerCase().replace(/\.$/, "");
  const normalizedMxHostname = mxHostname.trim().toLowerCase().replace(/\.$/, "");
  const suffix = `.${normalizedDomain}`;

  if (!normalizedDomain || !normalizedMxHostname.endsWith(suffix)) {
    return null;
  }

  return normalizedMxHostname.slice(0, -suffix.length) || "@";
}

function inferDkimKeySize(dkimPublicKey: string | undefined) {
  return dkimPublicKey && dkimPublicKey.length < 300 ? 1024 : 2048;
}

function DkimKeySizeSelector({
  value,
  onChange,
}: {
  value: DkimKeySize;
  onChange: (value: DkimKeySize) => void;
}) {
  const [isTooltipOpen, setIsTooltipOpen] = useState(false);
  const isRecommended = value === 2048;

  return (
    <div className="rounded-[14px] border border-[#dbe5f7] bg-[#f8fbff] px-3.5 py-3">
      <input name="dkimKeySize" type="hidden" value={value} />
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="flex items-center gap-1.5">
          <p className="text-[13px] font-semibold text-[#4f6284]">DKIM 키 길이</p>
          <div className="relative">
            <button
              type="button"
              aria-controls="dkim-key-size-help"
              aria-expanded={isTooltipOpen}
              aria-label="DKIM 키 길이 안내"
              onClick={() => setIsTooltipOpen((current) => !current)}
              className="flex h-5 w-5 items-center justify-center rounded-full border border-[#b9c9e3] bg-white text-[11px] font-bold text-[#607594] transition-colors hover:border-[#8eb2ef] hover:text-[#2f6df6]"
            >
              i
            </button>
            {isTooltipOpen ? (
              <div
                id="dkim-key-size-help"
                role="tooltip"
                className="absolute left-0 top-7 z-20 w-[min(300px,calc(100vw-3rem))] rounded-[12px] border border-[#d5e2f7] bg-white p-3 text-[12px] leading-5 text-[#526782] shadow-[0_12px_30px_rgba(38,73,130,0.16)]"
              >
                2048-bit는 권장되는 기본 설정입니다. 카페24처럼 긴 TXT 값을 등록할 수 없는 DNS를 사용할 때만 1024-bit 호환 모드를 선택하세요. 저장 후 키 길이를 바꾸려면 DKIM 키를 다시 발급해야 합니다.
              </div>
            ) : null}
          </div>
        </div>
        <span className="text-[12px] font-medium text-[#7183a1]">
          {isRecommended ? "권장 설정" : "DNS 호환 모드"}
        </span>
      </div>

      <div className="mt-3 inline-grid grid-cols-[auto_48px_auto] items-center gap-x-3">
        <span
          className={`whitespace-nowrap text-[12px] font-semibold transition-colors ${
            isRecommended ? "text-[#91a0b6]" : "text-[#245ac9]"
          }`}
        >
          1024-bit
        </span>
        <button
          type="button"
          role="switch"
          aria-checked={isRecommended}
          aria-label={`DKIM 키 길이: ${value}-bit`}
          onClick={() => onChange(isRecommended ? 1024 : 2048)}
          className={`relative h-7 min-w-[48px] max-w-[48px] rounded-full border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#8db8ff] focus-visible:ring-offset-2 ${
            isRecommended
              ? "border-[#2f6df6] bg-[#2f6df6]"
              : "border-[#9bb9ec] bg-[#dce9ff]"
          }`}
        >
          <span
            className={`absolute left-0.5 top-0.5 h-[22px] w-[22px] rounded-full bg-white shadow-[0_2px_5px_rgba(23,55,106,0.24)] transition-transform ${
              isRecommended ? "translate-x-[22px]" : "translate-x-0"
            }`}
          />
        </button>
        <span
          className={`whitespace-nowrap text-[12px] font-semibold transition-colors ${
            isRecommended ? "text-[#245ac9]" : "text-[#91a0b6]"
          }`}
        >
          2048-bit
        </span>
      </div>
      <p className="mt-2 text-[12px] leading-5 text-[#7183a1]">
        {isRecommended
          ? "대부분의 DNS 서비스에 권장되는 보안 키 길이입니다."
          : "TXT 값 길이가 255자 안팎으로 제한된 DNS 서비스용 설정입니다."}
      </p>
    </div>
  );
}

function createPreviewDnsRows(input: {
  dkimEnabled: boolean;
  domain: string;
  dkimSelector: string;
  dkimPublicKey: string;
  mxHostname: string;
  useSavedDns: boolean;
  savedRows: MailSetupOverview["dnsRecords"];
}) {
  const fallbackRows: DnsRow[] = [
    {
      key: "mx-root",
      type: "MX",
      host: "@",
      value: `${input.mxHostname}.`,
      ttl: "3600",
      priorityValue: "10",
      statusLabel: "저장 전",
      statusTone: "neutral",
      copyValue: `${input.mxHostname}.`,
    },
    {
      key: "spf-root",
      type: "TXT",
      host: "@",
      value: `v=spf1 include:${input.mxHostname} -all`,
      ttl: "3600",
      priorityValue: "-",
      statusLabel: "저장 전",
      statusTone: "neutral",
      copyValue: `v=spf1 include:${input.mxHostname} -all`,
    },
    {
      key: "dkim-root",
      type: "TXT",
      host: `${input.dkimSelector}._domainkey`,
      value: input.dkimPublicKey
        ? `v=DKIM1; k=rsa; p=${input.dkimPublicKey}`
        : `${input.domain} 저장 후 실제 DKIM 공개키가 이 칸에 표시됩니다.`,
      ttl: "3600",
      priorityValue: "-",
      statusLabel: input.dkimPublicKey ? "저장됨" : "저장 후 생성",
      statusTone: input.dkimPublicKey ? "success" : "neutral",
      copyValue: input.dkimPublicKey
        ? `v=DKIM1; k=rsa; p=${input.dkimPublicKey}`
        : "",
    },
    {
      key: "dmarc-root",
      type: "TXT",
      host: "_dmarc",
      value: "v=DMARC1; p=none; rua=mailto:dmarc@officialsite.kr",
      ttl: "3600",
      priorityValue: "-",
      statusLabel: "저장 전",
      statusTone: "neutral",
      copyValue: "v=DMARC1; p=none; rua=mailto:dmarc@officialsite.kr",
    },
  ];
  const mxSpfHost = getMxSpfRecordHost(input.domain, input.mxHostname);

  if (mxSpfHost) {
    fallbackRows.splice(2, 0, {
      key: "spf-mx-host",
      type: "TXT",
      host: mxSpfHost,
      value: "v=spf1 ip4:115.68.219.179 -all",
      ttl: "3600",
      priorityValue: "-",
      statusLabel: "저장 전",
      statusTone: "neutral",
      copyValue: "v=spf1 ip4:115.68.219.179 -all",
    });
  }

  if (!input.dkimEnabled) {
    const dkimIndex = fallbackRows.findIndex((row) => row.key === "dkim-root");

    if (dkimIndex >= 0) {
      fallbackRows.splice(dkimIndex, 1);
    }
  }

  if (!input.useSavedDns) {
    return fallbackRows;
  }

  const savedRowMap = new Map(
    input.savedRows.map(
      (record) => [`${record.type}-${record.host}`, record] as const,
    ),
  );

  return fallbackRows.map((row) => {
    const hostName = row.host === "@" ? input.domain : row.host;
    const savedRow = savedRowMap.get(`${row.type}-${hostName}`);

    if (!savedRow) {
      return row;
    }

    return {
      key: `${savedRow.type}-${savedRow.host}`,
      type: savedRow.type,
      host: formatRecordHost(savedRow.host, input.domain),
      value: savedRow.value,
      ttl: "3600",
      priorityValue: savedRow.priority ? String(savedRow.priority) : "-",
      statusLabel:
        savedRow.status === "verified"
          ? "정상"
          : savedRow.status === "failed"
            ? "불일치"
            : "확인 전",
      statusTone:
        savedRow.status === "verified"
          ? "success"
          : savedRow.status === "failed"
            ? "error"
            : "neutral",
      copyValue: savedRow.value,
    } satisfies DnsRow;
  });
}

function statusTextClass(tone: DnsRow["statusTone"]) {
  if (tone === "success") {
    return "text-[#2d8153]";
  }

  if (tone === "error") {
    return "text-[#b04c63]";
  }

  return "text-[#5f7190]";
}

function connectionBadge(input: {
  overview: MailSetupOverview | null;
  useSavedDns: boolean;
  hasDraftDomain: boolean;
}) {
  if (!input.overview) {
    return {
      label: input.hasDraftDomain ? "입력 중" : "설정 전",
      className: "om-badge-info",
    };
  }

  if (input.overview.mailConfigured) {
    return {
      label: "연결 완료",
      className: "om-badge-success",
    };
  }

  if (input.overview.status === "failed") {
    return {
      label: "검증 실패",
      className: "om-badge-danger",
    };
  }

  if (input.overview.status === "verified" && input.useSavedDns) {
    return {
      label: "메일 연결 대기",
      className: "om-badge-info",
    };
  }

  return {
    label: "DNS 대기",
    className: "om-badge-info",
  };
}

function resolveDomainStatusText(overview: MailSetupOverview | null) {
  if (!overview) {
    return "아직 도메인이 연결되지 않았습니다.";
  }

  if (overview.mailConfigured) {
    return "DNS 검증이 완료되어 대표 메일 송수신이 활성화되었습니다.";
  }

  if (overview.status === "failed") {
    return "DNS 값이 아직 일치하지 않습니다. 레코드를 다시 확인해주세요.";
  }

  return "DNS 검증 전 상태입니다. 레코드를 반영한 뒤 연결 상태를 확인해주세요.";
}

function GuideBadge({ step }: { step: string }) {
  return (
    <div className="flex h-7 w-7 items-center justify-center rounded-full border border-[#d5e2ff] bg-[#f7faff] text-[12px] font-semibold text-[#2f6df6]">
      {step}
    </div>
  );
}

function SettingsNavIcon({ section }: { section: MailSetupSection }) {
  const commonProps = {
    "aria-hidden": true,
    className: "h-[17px] w-[17px]",
    fill: "none",
    stroke: "currentColor",
    strokeLinecap: "round" as const,
    strokeLinejoin: "round" as const,
    strokeWidth: 1.9,
    viewBox: "0 0 24 24",
  };

  if (section === "account") {
    return (
      <svg {...commonProps}>
        <path d="M12 12.4a4.1 4.1 0 1 0 0-8.2 4.1 4.1 0 0 0 0 8.2Z" />
        <path d="M4.8 20.1a7.2 7.2 0 0 1 14.4 0" />
      </svg>
    );
  }

  if (section === "domain") {
    return (
      <svg {...commonProps}>
        <circle cx="12" cy="12" r="8.3" />
        <path d="M3.9 12h16.2" />
        <path d="M12 3.7c2.1 2.2 3.2 5 3.2 8.3s-1.1 6.1-3.2 8.3" />
        <path d="M12 3.7c-2.1 2.2-3.2 5-3.2 8.3s1.1 6.1 3.2 8.3" />
      </svg>
    );
  }

  if (section === "assistant") {
    return (
      <svg {...commonProps}>
        <path d="m12 3.6 1.8 4.7 4.6 1.7-4.6 1.8-1.8 4.6-1.8-4.6L5.6 10l4.6-1.7Z" />
        <path d="m18.2 15.3.7 1.8 1.8.7-1.8.7-.7 1.8-.7-1.8-1.8-.7 1.8-.7Z" />
      </svg>
    );
  }

  if (section === "members") {
    return (
      <svg {...commonProps}>
        <path d="M9.2 11.2a3.4 3.4 0 1 0 0-6.8 3.4 3.4 0 0 0 0 6.8Z" />
        <path d="M3.8 19.5a5.6 5.6 0 0 1 10.8-2" />
        <path d="M16.6 10.3a2.7 2.7 0 1 0 0-5.4" />
        <path d="M16.5 14.1a5 5 0 0 1 3.7 4.5" />
      </svg>
    );
  }

  return (
    <svg {...commonProps}>
      <rect x="4" y="6.2" width="16" height="11.6" rx="2.6" />
      <path d="M4 10h16" />
      <path d="M7.7 14.2h3.3" />
    </svg>
  );
}

function SettingsShell({
  canManageBilling,
  section,
  children,
}: {
  canManageBilling: boolean;
  section: MailSetupSection;
  children: ReactNode;
}) {
  const visibleSettingsSections = canManageBilling
    ? SETTINGS_NAV_SECTIONS
    : SETTINGS_NAV_SECTIONS.filter(
        (item) => item !== "domain" && item !== "members" && item !== "billing",
      );

  return (
    <div className="om-settings-layout">
      <aside className="om-settings-sidebar hidden xl:block">
        <nav className="om-settings-sidebar-nav">
          {visibleSettingsSections.map((item) => {
            const meta = SECTION_META[item];
            const active = item === section;

            return (
              <Link
                key={item}
                href={`/mail?panel=setup&section=${item}`}
                prefetch={false}
                className={`om-settings-sidebar-link ${
                  active
                    ? "om-settings-sidebar-link-active"
                    : "om-settings-sidebar-link-idle"
                }`}
              >
                <span className="om-settings-sidebar-link-icon">
                  <SettingsNavIcon section={item} />
                </span>
                <span className="truncate">{meta.label}</span>
              </Link>
            );
          })}
        </nav>
      </aside>

      <div className="om-settings-main">
        <div className="om-settings-main-inner om-settings-main-inner-compact">
          {children}
        </div>
      </div>
    </div>
  );
}

function AccountInfoItem({
  label,
  value,
  description,
  emphasis = false,
}: {
  label: string;
  value: ReactNode;
  description?: string;
  emphasis?: boolean;
}) {
  return (
    <div className="min-w-0 border-t border-[#edf1f6] py-3 lg:py-4">
      <p className="text-[12px] font-semibold uppercase tracking-[0.08em] text-[#7c8dab]">
        {label}
      </p>
      <div
        className={`mt-1.5 break-all ${
          emphasis
            ? "text-[17px] font-semibold tracking-[-0.03em] text-[#16233c] sm:text-[18px]"
            : "text-[14px] font-medium text-[#344767]"
        }`}
      >
        {value}
      </div>
      {description ? (
        <p className="mt-1.5 text-[12px] leading-5 text-[#7b8ca8]">{description}</p>
      ) : null}
    </div>
  );
}

function AccountSectionPanel({
  eyebrow,
  title,
  description,
  action,
  children,
}: {
  eyebrow: string;
  title: string;
  description: string;
  action?: ReactNode;
  children?: ReactNode;
}) {
  return (
    <section className="om-setup-panel bg-white px-3 py-4 sm:px-4 lg:px-5">
      <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
        <div className="min-w-0">
          <p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-[#8aa0c6]">
            {eyebrow}
          </p>
          <h2 className="mt-1.5 text-[18px] font-semibold tracking-[-0.04em] text-[#16233c] sm:text-[20px]">
            {title}
          </h2>
          <p className="mt-1.5 max-w-[720px] text-[13px] leading-5 text-[#6f7f99]">
            {description}
          </p>
        </div>
        {action ? <div className="shrink-0">{action}</div> : null}
      </div>
      {children ? <div className="mt-4">{children}</div> : null}
    </section>
  );
}

function AccountDisplayNameForm({ defaultValue }: { defaultValue: string }) {
  const [state, formAction, pending] = useActionState(
    updateMailboxDisplayNameAction,
    INITIAL_MAILBOX_DISPLAY_NAME_ACTION_STATE,
  );

  return (
    <form action={formAction} className="max-w-[620px]">
      <div className="flex flex-col gap-2 sm:flex-row sm:items-end">
        <label className="block min-w-0 flex-1">
          <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">표시 이름</span>
          <input
            required
            name="displayName"
            defaultValue={defaultValue}
            maxLength={191}
            autoComplete="name"
            className="h-10 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3 text-[14px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
          />
        </label>
        <SubmitButton
          label="저장"
          pendingLabel="저장 중..."
          className="om-btn-primary h-10 shrink-0 rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none"
        />
      </div>
      {state.status !== "idle" ? (
        <p
          aria-live="polite"
          className={`mt-2 text-[12px] leading-5 ${
            state.status === "success" ? "text-[#2d8153]" : "text-[#b54a5b]"
          }`}
        >
          {state.message}
        </p>
      ) : null}
    </form>
  );
}

function AccountPasswordDialogPanel({
  onClose,
  onSuccess,
  representativeMailbox,
  sessionEmail,
}: {
  onClose: () => void;
  onSuccess: (message: string) => void;
  representativeMailbox: string;
  sessionEmail: string;
}) {
  const [state, formAction, pending] = useActionState(
    updateRepresentativePasswordAction,
    INITIAL_REPRESENTATIVE_PASSWORD_ACTION_STATE,
  );

  useEffect(() => {
    if (state.status === "success") {
      onSuccess(state.message);
    }
  }, [onSuccess, state.message, state.status]);

  return (
    <div
      className="fixed inset-0 z-[170] flex items-center justify-center bg-[rgba(12,18,31,0.42)] px-4 py-8 backdrop-blur-[3px]"
      onClick={() => {
        if (!pending) {
          onClose();
        }
      }}
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby="account-password-dialog-title"
        className="w-full max-w-[560px] overflow-hidden rounded-[22px] border border-[#e2eaf7] bg-white shadow-[0_28px_70px_rgba(18,32,65,0.18)]"
        onClick={(event) => event.stopPropagation()}
      >
        <div className="border-b border-[#edf2fb] px-6 py-5">
          <div className="flex items-start justify-between gap-4">
            <div className="min-w-0">
              <p
                id="account-password-dialog-title"
                className="text-[20px] font-semibold tracking-[-0.04em] text-[#16233c]"
              >
                비밀번호 변경
              </p>
              <p className="mt-2 text-[14px] leading-6 text-[#6a7b98]">
                현재 비밀번호를 확인한 뒤 새 비밀번호를 적용합니다.
              </p>
            </div>
            <CloseIconButton
              ariaLabel="비밀번호 변경 닫기"
              className={pending ? "pointer-events-none opacity-60" : ""}
              onClick={() => {
                if (!pending) {
                  onClose();
                }
              }}
            />
          </div>
        </div>

        <form action={formAction} className="px-6 py-6">
          <div className="mt-5 space-y-4">
            <label className="block">
              <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                현재 비밀번호
              </span>
              <input
                required
                type="password"
                name="currentPassword"
                autoComplete="current-password"
                placeholder="현재 비밀번호를 입력하세요"
                className="h-13 w-full rounded-[16px] border border-[#dbe5f7] bg-white px-4 text-[15px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
              />
            </label>

            <div className="grid gap-4 xl:grid-cols-2">
              <label className="block">
                <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                  새 비밀번호
                </span>
                <input
                  required
                  type="password"
                  name="password"
                  autoComplete="new-password"
                  placeholder="새 비밀번호를 입력하세요"
                  className="h-13 w-full rounded-[16px] border border-[#dbe5f7] bg-white px-4 text-[15px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                />
              </label>

              <label className="block">
                <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                  비밀번호 확인
                </span>
                <input
                  required
                  type="password"
                  name="passwordConfirm"
                  autoComplete="new-password"
                  placeholder="같은 비밀번호를 다시 입력하세요"
                  className="h-13 w-full rounded-[16px] border border-[#dbe5f7] bg-white px-4 text-[15px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                />
              </label>
            </div>
          </div>

          {state.status === "error" ? (
            <div className="mt-4 rounded-[14px] border border-[#f0d8de] bg-[#fff7f9] px-4 py-3 text-[13px] leading-6 text-[#a34861]">
              {state.message}
            </div>
          ) : null}

          <div className="mt-6 flex items-center justify-end gap-2 border-t border-[#edf2fb] pt-5">
            <button
              type="button"
              disabled={pending}
              onClick={onClose}
              className="om-btn-secondary h-11 rounded-[14px] px-4 text-[13px] text-[#344767] disabled:cursor-not-allowed disabled:opacity-60"
            >
              취소
            </button>
            <SubmitButton
              label="비밀번호 변경"
              pendingLabel="변경 중..."
              className="om-btn-primary h-11 rounded-[14px] px-4 text-[13px]"
            />
          </div>
        </form>
      </div>
    </div>
  );
}

function AccountPasswordDialog({
  representativeMailbox,
  sessionEmail,
}: {
  representativeMailbox: string;
  sessionEmail: string;
}) {
  const [open, setOpen] = useState(false);
  const [dialogKey, setDialogKey] = useState(0);
  const [successMessage, setSuccessMessage] = useState("");

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

    const previousOverflow = document.body.style.overflow;

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

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

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

  useEffect(() => {
    if (!successMessage) {
      return undefined;
    }

    const timer = window.setTimeout(() => {
      setSuccessMessage("");
    }, 3200);

    return () => window.clearTimeout(timer);
  }, [successMessage]);

  return (
    <>
      <div className="flex flex-col items-start gap-3 lg:items-end lg:text-right">
        <button
          type="button"
          onClick={() => {
            setDialogKey((value) => value + 1);
            setOpen(true);
          }}
          className="om-btn-primary h-10 rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none"
        >
          비밀번호 변경
        </button>
        <p
          className={`text-[12px] leading-5 ${
            successMessage ? "text-[#2d8153]" : "text-[#7b8ca8]"
          }`}
        >
          {successMessage || "로그인, 웹메일, IMAP/SMTP 인증에 같은 비밀번호가 적용됩니다."}
        </p>
      </div>

      {open ? (
        <AccountPasswordDialogPanel
          key={dialogKey}
          representativeMailbox={representativeMailbox}
          sessionEmail={sessionEmail}
          onClose={() => setOpen(false)}
          onSuccess={(message) => {
            setSuccessMessage(message);
            setOpen(false);
          }}
        />
      ) : null}
    </>
  );
}

export function MailSetupWorkspace({
  section,
  overview,
  aiAssistOverview,
  billingOverview,
  billingCancellationOverview,
  billingHistoryPage,
  billingHistoryState,
  billingTab,
  managedMembers,
  memberMailboxView,
  mailData,
  planSummary,
  canManageBilling,
  sessionCompanyName,
  sessionDisplayName,
  sessionDomain,
  sessionEmail,
  sessionMailbox,
}: MailSetupWorkspaceProps) {
  const dnsRef = useRef<HTMLDivElement | null>(null);
  const [copiedRowKey, setCopiedRowKey] = useState("");
  const [dkimKeySize, setDkimKeySize] = useState<DkimKeySize>(() =>
    inferDkimKeySize(overview?.dkimPublicKey),
  );
  const [domain, setDomain] = useState(overview?.domain || sessionDomain || "");
  const [localPart, setLocalPart] = useState(
    overview?.localPart || sessionMailbox.split("@")[0] || "owner",
  );

  useEffect(() => {
    if (!copiedRowKey) {
      return undefined;
    }

    const timer = window.setTimeout(() => {
      setCopiedRowKey("");
    }, 1800);

    return () => window.clearTimeout(timer);
  }, [copiedRowKey]);

  const sectionMeta = SECTION_META[section];
  const normalizedDomain =
    normalizeDomainPreview(domain) ||
    overview?.domain ||
    sessionDomain ||
    "company.co.kr";
  const normalizedLocalPart =
    normalizeLocalPartPreview(localPart) ||
    overview?.localPart ||
    sessionMailbox.split("@")[0] ||
    "owner";
  const previewMailbox = `${normalizedLocalPart}@${normalizedDomain}`;
  const representativeMailbox =
    overview?.mailbox || sessionMailbox || previewMailbox;
  const useSavedDns = Boolean(overview && overview.domain === normalizedDomain);
  const hasDraftDomain = Boolean(normalizeDomainPreview(domain));
  const showDomainForm = !overview;
  const badge = connectionBadge({ overview, useSavedDns, hasDraftDomain });
  const billingSeatCount = countMailBillingSeatsFromManagedMembers(
    managedMembers.length,
  );
  const estimatedMonthlyCost = planSummary.isComplimentary
    ? 0
    : billingSeatCount * MAIL_GROWTH_PLAN_PRICE_PER_MEMBER;
  const accountBillingSummary =
    planSummary.isComplimentary
      ? `${formatCurrency(0)} · 운영 계정 혜택 적용`
      : planSummary.tier === "growth"
        ? `${formatCurrency(estimatedMonthlyCost)} · 팀 인원 ${billingSeatCount}명`
        : `${formatCurrency(0)} · 대표 메일 1개 무료`;
  const dnsRows = createPreviewDnsRows({
    dkimEnabled: overview?.dkimEnabled ?? true,
    domain: normalizedDomain,
    dkimSelector: overview?.dkimSelector || "om1",
    dkimPublicKey: useSavedDns ? overview?.dkimPublicKey || "" : "",
    mxHostname: overview?.mxHostname || "mx1.officialsite.kr",
    useSavedDns,
    savedRows: overview?.dnsRecords ?? [],
  });

  const copyRowValue = async (row: DnsRow) => {
    if (!row.copyValue) {
      return;
    }

    try {
      await navigator.clipboard.writeText(row.copyValue);
      setCopiedRowKey(row.key);
    } catch {
      setCopiedRowKey("");
    }
  };

  if (section === "account") {
    const accountTitle = sessionDisplayName || sessionCompanyName || "오피셜메일";
    const accountDisplayName =
      sessionDisplayName || sessionCompanyName || normalizedLocalPart;
    const accountInitials = buildSettingsProfileInitials(
      sessionDisplayName,
      sessionCompanyName,
      sessionEmail,
    );

    return (
      <SettingsShell
        canManageBilling={canManageBilling}
        section={section}
      >
        <div className="om-setup-header">
          <div className="om-setup-header-copy">
            <h1 className="om-page-title text-[#16233c]">
              {sectionMeta.title}
            </h1>
            <p className="om-setup-header-description">
              {sectionMeta.description}
            </p>
          </div>
        </div>

        <div className="om-setup-content">
          <section className="om-setup-panel bg-white px-3 py-4 sm:px-4 lg:px-5">
            <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
              <div className="flex min-w-0 items-center gap-3">
                <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-[15px] bg-[#edf4ff] text-[15px] font-semibold text-[#2f6df6]">
                  {accountInitials}
                </div>
                <div className="min-w-0">
                  <p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-[#8aa0c6]">
                    대표 계정
                  </p>
                  <h2 className="mt-1 truncate text-[20px] font-semibold tracking-[-0.05em] text-[#16233c] sm:text-[22px]">
                    {accountTitle}
                  </h2>
                  <p className="mt-1 break-all text-[13px] text-[#6f7f99]">
                    {sessionEmail}
                  </p>
                </div>
              </div>

              <div className="flex flex-wrap gap-2">
                <span className="om-badge om-badge-lg om-badge-info">
                  {planSummary.label}
                </span>
                <span className={`om-badge om-badge-lg ${badge.className}`}>
                  {badge.label}
                </span>
              </div>
            </div>

            <div className="mt-4 grid gap-x-8 sm:grid-cols-2 xl:grid-cols-4">
              <AccountInfoItem
                label="표시 이름"
                value={accountDisplayName}
                emphasis
              />
              <AccountInfoItem label="로그인 계정" value={sessionEmail} />
              <AccountInfoItem
                label="대표 메일"
                value={overview?.mailbox || sessionMailbox}
                description="송수신과 관리자 기능에 사용하는 기본 주소"
              />
              <AccountInfoItem
                label="연결 도메인"
                value={overview?.domain || normalizedDomain}
              />
            </div>
          </section>

          <AccountSectionPanel
            eyebrow="발신 정보"
            title="표시 이름"
            description="이후 보내는 새 메일의 보낸사람 이름에 적용됩니다. 기존에 보낸 메일은 변경되지 않습니다."
          >
            <AccountDisplayNameForm defaultValue={accountDisplayName} />
          </AccountSectionPanel>

          <AccountSectionPanel
            eyebrow="보안"
            title="비밀번호 변경"
            description="현재 비밀번호를 확인한 뒤 로그인, 웹메일, IMAP/SMTP 인증에 사용하는 비밀번호를 변경합니다."
            action={
              <AccountPasswordDialog
                representativeMailbox={representativeMailbox}
                sessionEmail={sessionEmail}
              />
            }
          >
            <div className="grid gap-x-8 sm:grid-cols-2">
              <AccountInfoItem
                label="적용 범위"
                value="로그인 · 웹메일 · IMAP/SMTP"
                emphasis
              />
              <AccountInfoItem
                label="도메인 연결"
                value="비밀번호 재입력 없음"
                description="DNS 연결 화면에서는 계정 비밀번호를 다시 입력하지 않습니다."
              />
            </div>
          </AccountSectionPanel>

          <AccountSectionPanel
            eyebrow="사용 상태"
            title="플랜과 연결"
            description="현재 구독 플랜, 도메인 연결 상태, 월 요금 기준을 분리해서 확인합니다."
          >
            <div className="grid gap-x-8 sm:grid-cols-2 xl:grid-cols-4">
              <AccountInfoItem label="현재 플랜" value={planSummary.label} emphasis />
              <AccountInfoItem label="연결 상태" value={badge.label} emphasis />
              <AccountInfoItem
                label="상태 안내"
                value={resolveDomainStatusText(overview)}
              />
              <AccountInfoItem
                label={planSummary.tier === "growth" ? "예상 월 요금" : "현재 월 요금"}
                value={accountBillingSummary}
              />
            </div>
          </AccountSectionPanel>
        </div>
      </SettingsShell>
    );
  }

  if (section === "assistant") {
    return (
      <SettingsShell
        canManageBilling={canManageBilling}
        section={section}
      >
        <MailAiAssistPanel
          embedded
          overview={aiAssistOverview}
          planSummary={planSummary}
          canManageBilling={canManageBilling}
        />
      </SettingsShell>
    );
  }

  if (section === "members") {
    return (
      <SettingsShell
        canManageBilling={canManageBilling}
        section={section}
      >
        <MailMembersPanel
          embedded
          canManageBilling={canManageBilling}
          domain={normalizedDomain}
          memberMailboxView={memberMailboxView}
          members={managedMembers}
          planSummary={planSummary}
          representativeDisplayName={sessionDisplayName}
          representativeMailbox={representativeMailbox}
        />
      </SettingsShell>
    );
  }

  if (section === "billing") {
    return (
      <SettingsShell
        canManageBilling={canManageBilling}
        section={section}
      >
        <div className="om-setup-header lg:flex-row lg:items-start lg:gap-5">
          <div className="om-setup-header-copy">
            <h1 className="om-page-title text-[#16233c]">
              {sectionMeta.title}
            </h1>
            <p className="om-setup-header-description">
              {sectionMeta.description}
            </p>
          </div>
        </div>

        <div className="om-setup-content">
          <TossBillingModule
            billingOverview={billingOverview}
            cancellationOverview={billingCancellationOverview}
            currentTab={billingTab}
            billingSeatCount={billingSeatCount}
            canManageBilling={canManageBilling}
            estimatedMonthlyCost={estimatedMonthlyCost}
            historyPage={billingHistoryPage}
            historyState={billingHistoryState}
            isComplimentaryGrowthPlan={planSummary.isComplimentary}
            managedMembers={managedMembers}
            representativeMailbox={representativeMailbox}
          />
        </div>
      </SettingsShell>
    );
  }

  return (
      <SettingsShell
        canManageBilling={canManageBilling}
        section={"domain"}
      >
      <div className="om-setup-header lg:flex-row lg:items-start lg:gap-5">
          <div className="om-setup-header-copy">
            <h1 className="om-page-title text-[#16233c]">도메인 연결</h1>
            <p className="om-setup-header-description">
              도메인 연결 상태와 DNS 값을 확인합니다.
            </p>
          </div>
          <Link
            href={`${OFFICIAL_MAIL_GUIDE_URL}#domain`}
            target="_blank"
            rel="noopener noreferrer"
            className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none"
          >
            도메인 연결 가이드
          </Link>
        </div>

        <div className="om-setup-content">
        {showDomainForm ? (
          <div className="om-setup-panel px-3 py-4 sm:px-4 lg:px-5">
            <div className="flex flex-col gap-1.5 border-b border-[#edf1f6] pb-3">
              <p className="text-[15px] font-semibold tracking-[-0.03em] text-[#16233c] sm:text-[16px]">
                도메인 등록
              </p>
              <p className="max-w-[620px] text-[13px] leading-5 text-[#7b8ca8]">
                도메인과 대표 메일 아이디를 저장하면 DNS 값이 생성됩니다.
              </p>
            </div>

            <form
              action={completeMailSetupAction}
              className="om-setup-subpanel mt-4 px-0 py-4"
            >
              <div className="grid gap-4 xl:grid-cols-[1.1fr_0.9fr]">
                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                    연결할 도메인
                  </span>
                  <input
                    required
                    type="text"
                    name="domain"
                    value={domain}
                    onChange={(event) => setDomain(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 transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                </label>

                <label className="block">
                  <span className="mb-2 block text-[13px] font-semibold text-[#4f6284]">
                    대표 메일 아이디
                  </span>
                  <input
                    required
                    type="text"
                    name="localPart"
                    pattern="^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$"
                    value={localPart}
                    onChange={(event) => setLocalPart(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 transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                  />
                </label>
              </div>

              <DkimKeySizeSelector
                value={dkimKeySize}
                onChange={setDkimKeySize}
              />

              <div className="om-setup-subpanel mt-4 px-0 py-4">
                <p className="text-[13px] font-semibold text-[#4f6284]">
                  대표 메일 비밀번호
                </p>
                <p className="mt-2 text-[13px] leading-6 text-[#7384a0]">
                  가입 시 생성한 대표 메일 비밀번호를 그대로 사용합니다.
                  비밀번호 변경은{" "}
                  <Link
                    href="/mail?panel=setup&section=account"
                    prefetch={false}
                    className="font-semibold text-[#2f6df6] underline underline-offset-4"
                  >
                    계정 설정
                  </Link>
                  에서 처리합니다.
                </p>
              </div>

              <div className="mt-5 flex flex-col gap-4 border-t border-[#edf2fb] px-0 pt-5 lg:flex-row lg:items-center lg:justify-between">
                <div>
                  <p className="text-[13px] font-semibold text-[#4f6284]">
                    생성될 대표 메일
                  </p>
                  <p className="mt-1 text-[18px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {previewMailbox}
                  </p>
                  <p className="mt-2 text-[13px] leading-6 text-[#7384a0]">
                    메일 아이디는 영문 소문자, 숫자, 점(.), 하이픈(-), 밑줄(_)만
                    사용할 수 있습니다.
                  </p>
                </div>
                <SubmitButton
                  label="도메인 저장"
                  pendingLabel="저장 중..."
                  className="om-btn-primary h-10 rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none"
                />
              </div>
            </form>
          </div>
        ) : null}

          <div ref={dnsRef} className="om-setup-panel px-3 py-4 sm:px-4 lg:px-5">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
              <div className="min-w-0">
                <p className="text-[15px] font-semibold tracking-[-0.03em] text-[#16233c] sm:text-[16px]">
                  DNS 레코드 검증
                </p>
                <p className="mt-1 max-w-[620px] text-[13px] leading-5 text-[#7b8ca8]">
                  DNS에 아래 값을 입력한 뒤 연결 상태를 확인하세요.
                </p>
                <div className="mt-3 flex flex-wrap items-center gap-2">
                  <span
                    className={`om-badge om-badge-lg ${badge.className}`}
                  >
                    {badge.label}
                  </span>
                  <span className="om-badge om-badge-lg om-badge-info">
                    {normalizedDomain}
                  </span>
                  <span className="om-badge om-badge-lg om-badge-muted">
                    {previewMailbox}
                  </span>
                </div>
              </div>

              <form action={verifyMailSetupAction}>
                <SubmitButton
                  label="연결 상태 확인"
                  pendingLabel="확인 중..."
                  disabled={!overview}
                  className="om-btn-primary h-10 min-w-[136px] rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none"
                />
              </form>
            </div>

            <div className="mt-4 border-t border-[#edf1f6] pt-3 text-[13px] leading-5 text-[#5f7190]">
              DNS 설정 변경 사항이 반영되는데 최대 1~24시간이 소요될 수
              있습니다.
            </div>

            {overview ? (
              <form
                action={updateMailSetupDkimUsageAction}
                className="mt-4 border-t border-[#edf1f6] pt-3"
              >
                <input
                  type="hidden"
                  name="dkimEnabled"
                  value={overview.dkimEnabled ? "0" : "1"}
                />
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div>
                    <p className="text-[13px] font-semibold text-[#30425f]">
                      DKIM 사용
                    </p>
                    <p className="mt-1 text-[12px] leading-5 text-[#7183a1]">
                      미사용 시 DKIM DNS 등록과 검증을 건너뜁니다. 외부 수신처에서
                      스팸 또는 반송될 가능성이 높아질 수 있습니다.
                    </p>
                  </div>
                  <div className="flex items-center gap-2.5">
                    <span
                      className={`text-[12px] font-semibold ${
                        overview.dkimEnabled ? "text-[#91a0b6]" : "text-[#526784]"
                      }`}
                    >
                      미사용
                    </span>
                    <button
                      type="submit"
                      role="switch"
                      aria-checked={overview.dkimEnabled}
                      aria-label={`DKIM ${overview.dkimEnabled ? "사용" : "미사용"}`}
                      className={`relative h-6 w-11 shrink-0 rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#8db8ff] focus-visible:ring-offset-2 ${
                        overview.dkimEnabled ? "bg-[#2f6df6]" : "bg-[#c8d4e8]"
                      }`}
                    >
                      <span
                        className={`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-white shadow-[0_1px_4px_rgba(24,52,96,0.28)] transition-transform ${
                          overview.dkimEnabled ? "translate-x-[20px]" : "translate-x-0"
                        }`}
                      />
                    </button>
                    <span
                      className={`text-[12px] font-semibold ${
                        overview.dkimEnabled ? "text-[#245ac9]" : "text-[#91a0b6]"
                      }`}
                    >
                      사용 (권장)
                    </span>
                  </div>
                </div>
              </form>
            ) : null}

            {overview?.dkimEnabled ? (
              <form
                action={regenerateMailSetupDkimAction}
                className="mt-4 flex flex-col gap-3 rounded-[16px] border border-[#dbe5f7] bg-white p-3.5 lg:flex-row lg:items-end lg:justify-between"
              >
                <div className="min-w-0 flex-1">
                  <DkimKeySizeSelector
                    value={dkimKeySize}
                    onChange={setDkimKeySize}
                  />
                </div>
                <div className="shrink-0">
                  <SubmitButton
                    label="DKIM 키 다시 발급"
                    pendingLabel="새 키 발급 중..."
                    className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px]"
                  />
                </div>
              </form>
            ) : null}

            <div className="mt-3 overflow-x-auto border-t border-[#ebf0fa]">
              <table className="w-full table-fixed border-collapse">
                <colgroup>
                  <col className="w-[94px]" />
                  <col className="w-[150px]" />
                  <col />
                  <col className="w-[98px]" />
                  <col className="w-[110px]" />
                  <col className="w-[104px]" />
                  <col className="w-[118px]" />
                </colgroup>
                <thead>
                  <tr className="border-b border-[#edf1f6] text-left text-[12px] font-semibold text-[#7a8ba8]">
                    <th className="px-3 py-3">유형</th>
                    <th className="px-3 py-3">이름 (호스트)</th>
                    <th className="px-3 py-3">값 (포인트)</th>
                    <th className="px-3 py-3">우선순위</th>
                    <th className="px-3 py-3">TTL</th>
                    <th className="px-3 py-3">상태</th>
                    <th className="px-3 py-3 text-right">복사</th>
                  </tr>
                </thead>
                <tbody>
                  {dnsRows.map((row) => (
                    <tr
                      key={row.key}
                      className="border-b border-[#edf1f6] align-top last:border-b-0"
                    >
                      <td className="px-3 py-3 text-[14px] font-semibold text-[#16233c]">
                        {row.type}
                      </td>
                      <td className="px-3 py-3 text-[13px] font-medium text-[#30425f]">
                        {row.host}
                      </td>
                      <td className="px-3 py-3">
                        <p className="break-all text-[13px] leading-6 text-[#30425f]">
                          {row.value}
                        </p>
                      </td>
                      <td className="px-3 py-3 text-[13px] text-[#5f7190]">
                        {row.priorityValue}
                      </td>
                      <td className="px-3 py-3 text-[13px] text-[#5f7190]">
                        {row.ttl}
                      </td>
                      <td
                        className={`px-3 py-3 text-[13px] font-medium ${statusTextClass(row.statusTone)}`}
                      >
                        {row.statusLabel}
                      </td>
                      <td className="px-3 py-3 text-right">
                        <button
                          type="button"
                          onClick={() => copyRowValue(row)}
                          disabled={!row.copyValue}
                          className="om-btn-secondary h-10 min-w-[92px] rounded-[14px] px-3 text-[12px] disabled:text-[#9aabc5]"
                        >
                          {copiedRowKey === row.key ? "복사됨" : "값 복사"}
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          <div className="grid gap-0 xl:grid-cols-2">
            <div className="om-setup-panel px-3 py-4 sm:px-4 lg:px-5 xl:border-r">
              <p className="text-[15px] font-semibold tracking-[-0.03em] text-[#16233c] sm:text-[16px]">
                현재 연결 정보
              </p>
              <div className="mt-3">
                <div className="om-setup-subpanel-box px-0 py-3">
                  <p className="text-[12px] font-semibold text-[#6f819f]">
                    연결 도메인
                  </p>
                  <p className="mt-1.5 text-[17px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {normalizedDomain}
                  </p>
                </div>
                <div className="om-setup-subpanel-box px-0 py-3">
                  <p className="text-[12px] font-semibold text-[#6f819f]">
                    대표 메일
                  </p>
                  <p className="mt-1.5 text-[15px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {previewMailbox}
                  </p>
                </div>
                <div className="om-setup-subpanel-box px-0 py-3">
                  <p className="text-[12px] font-semibold text-[#6f819f]">
                    마지막 상태
                  </p>
                  <p className="mt-1.5 text-[13px] leading-5 text-[#5f7498]">
                    {useSavedDns && overview
                      ? formatDateLabel(overview.verifiedAt)
                      : "도메인을 저장한 뒤 DNS 값을 반영하면 검증 시각이 표시됩니다."}
                  </p>
                </div>
              </div>
            </div>

            <div className="om-setup-panel px-3 py-4 sm:px-4 lg:px-5">
              <p className="text-[15px] font-semibold tracking-[-0.03em] text-[#16233c] sm:text-[16px]">
                연결 순서
              </p>
              <div className="mt-4 space-y-4">
                {[
                  [
                    "1",
                    "DNS 레코드 입력",
                    "MX, SPF, DKIM, DMARC 값을 도메인 DNS에 그대로 추가합니다.",
                  ],
                  [
                    "2",
                    "전파 대기",
                    "DNS 변경은 즉시 반영되지 않을 수 있으므로 잠시 기다립니다.",
                  ],
                  [
                    "3",
                    "상태 확인",
                    "연결 상태 확인 버튼으로 실제 공개 DNS와 메일 서버 등록 상태를 검증합니다.",
                  ],
                ].map(([step, title, description]) => (
                  <div key={step} className="flex items-start gap-3">
                    <GuideBadge step={step} />
                    <div>
                      <p className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">
                        {title}
                      </p>
                      <p className="mt-1 text-[13px] leading-5 text-[#6b7c99]">
                        {description}
                      </p>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
    </SettingsShell>
  );
}
