import Link from "next/link";
import { notFound } from "next/navigation";
import { KavenixCancellationReviewActions } from "@/components/kavenix-cancellation-review-actions";
import { KavenixChargeDetailsDialog } from "@/components/kavenix-charge-details-dialog";
import { KavenixChargeRefundButton } from "@/components/kavenix-charge-refund-button";
import { KavenixDomainDnsPopover } from "@/components/kavenix-domain-dns-popover";
import { KavenixMemberCreateDialog } from "@/components/kavenix-member-create-dialog";
import { getMailEntryUrlForCurrentRequest, requireSessionUser } from "@/lib/auth";
import {
  getKavenixAdminDataset,
  isKavenixAdminEmail,
  normalizeKavenixChargeFilter,
  type KavenixAdminChargeFilter,
  type KavenixAdminChargeRefundState,
  type KavenixAdminChargeRow,
  type KavenixAdminDomainRow,
  type KavenixAdminMailboxRow,
  type KavenixAdminSummary,
  type KavenixAdminUserRow,
} from "@/lib/kavenix-admin";
import {
  getKavenixMarketingAnalytics,
  getKavenixMarketingVisitorCount,
  normalizeKavenixMarketingDrilldown,
  normalizeKavenixMarketingRangeDays,
  type KavenixMarketingAnalytics,
  type KavenixMarketingDrilldown,
  type KavenixMarketingDrilldownDimension,
  type KavenixMarketingRangeDays,
} from "@/lib/marketing-analytics";
import { KavenixDomainCleanupButton } from "@/components/kavenix-domain-cleanup-button";
import { KavenixGoogleSearchConsoleDashboard } from "@/components/kavenix-google-search-console-dashboard";
import { KavenixBlogEditor } from "@/components/kavenix-blog-editor";
import { getKavenixGoogleSearchConsoleAnalytics } from "@/lib/google-search-console";
import {
  getKavenixMarketingBlogPostCount,
  getKavenixMarketingBlogPosts,
} from "@/lib/marketing-blog";

export const metadata = {
  title: "Kavenix Admin | 오피셜메일",
  description: "오피셜메일 최고관리자 대시보드",
};

type AdminView = "analytics" | "search" | "blog" | "users" | "domains" | "mailboxes" | "charges";

const ADMIN_X_PADDING = "px-3 sm:px-4 lg:px-8";
const ADMIN_CELL_START = "pl-3 sm:pl-4 lg:pl-8";
const ADMIN_CELL_END = "pr-3 sm:pr-4 lg:pr-8";

type AdminNavItem = {
  count?: number;
  description: string;
  label: string;
  view: AdminView;
};

function MenuIcon({ className }: { 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="M4.5 7h15" />
      <path d="M4.5 12h15" />
      <path d="M4.5 17h15" />
    </svg>
  );
}

function ArrowLeftIcon({ className }: { 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="M15 5 8 12l7 7" />
    </svg>
  );
}

function AdminViewIcon({ className, view }: { className?: string; view: AdminView }) {
  if (view === "analytics") {
    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="M4.5 19.5V5.5" />
        <path d="M4.5 19.5h15" />
        <path d="m7.4 15.5 3-3.2 2.8 1.8 4-5.2" />
        <path d="M15.8 8.9h1.4v1.4" />
      </svg>
    );
  }

  if (view === "search") {
    return (
      <svg
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
        className={className}
        aria-hidden="true"
      >
        <circle cx="10.5" cy="10.5" r="5.8" />
        <path d="m15 15 4.5 4.5" />
        <path d="M8.2 10.5h4.6" />
      </svg>
    );
  }

  if (view === "blog") {
    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="M6.5 4.5h8.2l2.8 2.8v12.2H6.5z" />
        <path d="M14.5 4.5v3h3" />
        <path d="M9 11h6" />
        <path d="M9 14.5h6" />
      </svg>
    );
  }

  if (view === "domains") {
    return (
      <svg
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
        className={className}
        aria-hidden="true"
      >
        <circle cx="12" cy="12" r="8.2" />
        <path d="M4.3 9.4h15.4" />
        <path d="M4.3 14.6h15.4" />
        <path d="M12 3.8c2 2.2 3.1 5 3.1 8.2s-1.1 6-3.1 8.2" />
        <path d="M12 3.8c-2 2.2-3.1 5-3.1 8.2s1.1 6 3.1 8.2" />
      </svg>
    );
  }

  if (view === "charges") {
    return (
      <svg
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
        className={className}
        aria-hidden="true"
      >
        <rect x="4" y="6" width="16" height="12" rx="2.6" />
        <path d="M4 10h16" />
        <path d="M8 14h3" />
      </svg>
    );
  }

  if (view === "mailboxes") {
    return (
      <svg
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
        className={className}
        aria-hidden="true"
      >
        <rect x="3.5" y="5.5" width="17" height="13" rx="2.5" />
        <path d="m4.8 7 7.2 5.6L19.2 7" />
      </svg>
    );
  }

  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="M9 11a3 3 0 1 0-3-3 3 3 0 0 0 3 3Z" />
      <path d="M15.8 10.5a2.5 2.5 0 1 0-2.5-2.5 2.5 2.5 0 0 0 2.5 2.5Z" />
      <path d="M4.5 18a4.8 4.8 0 0 1 8.8-2.7" />
      <path d="M14.1 18a4 4 0 0 1 5.4-2.6" />
    </svg>
  );
}

function AdminNavigation({
  chargeFilter,
  currentView,
  domain,
  items,
  q,
  rangeDays,
}: {
  chargeFilter: KavenixAdminChargeFilter;
  currentView: AdminView;
  domain: string;
  items: AdminNavItem[];
  q: string;
  rangeDays: KavenixMarketingRangeDays;
}) {
  return (
    <nav className="space-y-1" aria-label="최고관리자 메뉴">
      {items.map((item) => {
        const active = currentView === item.view;

        return (
          <Link
            key={item.view}
            href={buildAdminHref({
              view: item.view,
              q,
              domain,
              chargeFilter,
              rangeDays: item.view === "analytics" ? rangeDays : undefined,
            })}
            className={`group flex min-h-10 w-full items-center gap-[6px] rounded-[10px] px-2 py-2 text-left text-[14px] font-medium transition-colors duration-150 ${
              active
                ? "bg-[#edf4ff] font-semibold text-[#2f6df6]"
                : "text-[#33445f] hover:bg-[#f4f6fa] hover:text-[#2f6df6]"
            }`}
          >
            <span
              className={`inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-[8px] transition-colors ${
                active ? "text-[#2f6df6]" : "text-[#8390a8] group-hover:text-[#2f6df6]"
              }`}
            >
              <AdminViewIcon view={item.view} className="h-[17px] w-[17px]" />
            </span>
            <span className="min-w-0 flex-1 truncate">{item.label}</span>
            {typeof item.count === "number" ? (
              <span className={`shrink-0 text-[12px] font-semibold ${active ? "text-[#2f6df6]" : "text-[#70829f]"}`}>
                {item.count.toLocaleString("ko-KR")}
              </span>
            ) : null}
          </Link>
        );
      })}
    </nav>
  );
}

function AdminSidebar({
  chargeFilter,
  currentView,
  domain,
  items,
  q,
  rangeDays,
  userEmail,
}: {
  chargeFilter: KavenixAdminChargeFilter;
  currentView: AdminView;
  domain: string;
  items: AdminNavItem[];
  q: string;
  rangeDays: KavenixMarketingRangeDays;
  userEmail: string;
}) {
  return (
    <aside className="hidden min-h-screen w-[270px] shrink-0 border-r border-[#edf1f6] bg-white lg:flex lg:flex-col">
      <div className="border-b border-[#edf1f6] px-4 pb-4 pt-5">
        <p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-[#7d8ca8]">Kavenix Admin</p>
        <p className="mt-2 truncate text-[18px] font-semibold tracking-[-0.04em] text-[#16233c]">
          최고관리자
        </p>
        <p className="mt-1 truncate text-[13px] text-[#6d7f9d]">{userEmail}</p>
      </div>
      <div className="px-3 py-3">
        <AdminNavigation
          chargeFilter={chargeFilter}
          currentView={currentView}
          domain={domain}
          items={items}
          q={q}
          rangeDays={rangeDays}
        />
      </div>
      <div className="mt-auto border-t border-[#edf1f6] px-4 py-4 text-[12px] leading-5 text-[#7c8da8]">
        운영 데이터는 실시간 조회 기준으로 표시됩니다.
      </div>
    </aside>
  );
}

function AdminMobileMenu({
  chargeFilter,
  currentView,
  domain,
  items,
  q,
  rangeDays,
}: {
  chargeFilter: KavenixAdminChargeFilter;
  currentView: AdminView;
  domain: string;
  items: AdminNavItem[];
  q: string;
  rangeDays: KavenixMarketingRangeDays;
}) {
  const currentItem = items.find((item) => item.view === currentView) ?? items[0];

  return (
    <details className="group lg:hidden">
      <summary className="flex min-h-10 cursor-pointer list-none items-center justify-between gap-3 rounded-[10px] bg-[#f6f8fc] px-3 py-2 text-[#16233c] marker:hidden transition-colors hover:bg-[#f1f5fb] [&::-webkit-details-marker]:hidden">
        <span className="inline-flex min-w-0 items-center gap-2">
          <MenuIcon className="h-[18px] w-[18px] shrink-0 text-[#2f6df6]" />
          <span className="min-w-0">
            <span className="block truncate text-[14px] font-semibold">{currentItem.label}</span>
          </span>
        </span>
        <span className="h-2 w-2 rotate-45 border-b border-r border-[#7d8ca8] transition-transform group-open:rotate-[225deg]" />
      </summary>
      <div className="mt-2 border-y border-[#edf1f6] bg-white py-2">
        <AdminNavigation
          chargeFilter={chargeFilter}
          currentView={currentView}
          domain={domain}
          items={items}
          q={q}
          rangeDays={rangeDays}
        />
      </div>
    </details>
  );
}

function formatDateTime(value: string | null) {
  if (!value) {
    return "-";
  }

  return new Intl.DateTimeFormat("ko-KR", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(value));
}

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

function formatCancellationResult(value: string | null) {
  if (!value) {
    return "-";
  }

  try {
    const parsed = JSON.parse(value) as {
      cleanupError?: string | null;
      deletedAssetCount?: number;
      deletedManagedMemberCount?: number;
      deletedMessageCount?: number;
      refundedAmount?: number;
    };
    const parts: string[] = [];

    if (typeof parsed.deletedMessageCount === "number") {
      parts.push(`메시지 ${parsed.deletedMessageCount.toLocaleString("ko-KR")}건 정리`);
    }

    if (typeof parsed.deletedAssetCount === "number") {
      parts.push(`파일 ${parsed.deletedAssetCount.toLocaleString("ko-KR")}건 정리`);
    }

    if (typeof parsed.deletedManagedMemberCount === "number") {
      parts.push(`멤버 ${parsed.deletedManagedMemberCount.toLocaleString("ko-KR")}명 정리`);
    }

    if (typeof parsed.refundedAmount === "number" && parsed.refundedAmount > 0) {
      parts.push(`환불 ${formatCurrency(parsed.refundedAmount)}`);
    }

    if (parsed.cleanupError) {
      parts.push(`정리 오류: ${parsed.cleanupError}`);
    }

    return parts.length > 0 ? parts.join(" / ") : "처리 완료";
  } catch {
    return value;
  }
}

function formatCancellationReviewNote(value: string | null) {
  if (!value) {
    return null;
  }

  if (value === "policy-auto-withdrawal") {
    return "정책 기준 충족으로 자동 청약철회 처리";
  }

  return value;
}

function buildAdminHref(input: {
  chargeFilter?: KavenixAdminChargeFilter;
  domain?: string;
  marketingDrilldown?: KavenixMarketingDrilldown | null;
  q?: string;
  rangeDays?: KavenixMarketingRangeDays;
  view: AdminView;
}) {
  const searchParams = new URLSearchParams();
  searchParams.set("view", input.view);

  if (input.q?.trim()) {
    searchParams.set("q", input.q.trim());
  }

  if (input.domain?.trim()) {
    searchParams.set("domain", input.domain.trim());
  }

  if (input.chargeFilter && input.chargeFilter !== "all") {
    searchParams.set("chargeFilter", input.chargeFilter);
  }

  if (input.rangeDays) {
    searchParams.set("range", String(input.rangeDays));
  }

  if (input.marketingDrilldown) {
    searchParams.set("drill", input.marketingDrilldown.dimension);
    searchParams.set("drillValue", input.marketingDrilldown.value);
  }

  const query = searchParams.toString();
  return query ? `/kavenix?${query}` : "/kavenix";
}

function badgeClass(tone: "blue" | "green" | "amber" | "rose" | "slate") {
  if (tone === "green") {
    return "om-badge-success";
  }

  if (tone === "amber") {
    return "om-badge-warning";
  }

  if (tone === "rose") {
    return "om-badge-danger";
  }

  if (tone === "blue") {
    return "om-badge-info";
  }

  return "om-badge-muted";
}

type ChargeStageVariant =
  | "payment-success"
  | "payment-failed"
  | "payment-requested"
  | "payment-skipped"
  | "refund-processing"
  | "refund-full"
  | "refund-partial"
  | "withdrawal-pending"
  | "withdrawal-approved"
  | "withdrawal-rejected"
  | "muted";

function chargeStageBadgeClass(variant: ChargeStageVariant) {
  if (variant === "payment-success") {
    return "border-[#bfdbfe] bg-[#eff6ff] text-[#1d4ed8]";
  }

  if (variant === "refund-full") {
    return "border-[#ddd6fe] bg-[#f5f3ff] text-[#6d28d9]";
  }

  if (variant === "refund-partial") {
    return "border-[#bae6fd] bg-[#f0f9ff] text-[#0369a1]";
  }

  if (variant === "refund-processing" || variant === "withdrawal-pending") {
    return "border-[#fed7aa] bg-[#fff7ed] text-[#c2410c]";
  }

  if (variant === "withdrawal-approved") {
    return "border-[#c7d2fe] bg-[#eef2ff] text-[#4338ca]";
  }

  if (variant === "payment-failed" || variant === "withdrawal-rejected") {
    return "border-[#fecdd3] bg-[#fff1f2] text-[#be123c]";
  }

  if (variant === "payment-requested") {
    return "border-[#d8e4ff] bg-[#f5f8ff] text-[#315fce]";
  }

  if (variant === "payment-skipped") {
    return "border-[#fde68a] bg-[#fffbeb] text-[#a16207]";
  }

  return "border-[#e4eaf4] bg-white text-[#5f718e]";
}

function chargeStageDotClass(variant: ChargeStageVariant) {
  if (variant === "payment-success" || variant === "payment-requested") {
    return "bg-[#2f6df6]";
  }

  if (variant === "refund-full") {
    return "bg-[#7c3aed]";
  }

  if (variant === "refund-partial") {
    return "bg-[#0284c7]";
  }

  if (variant === "refund-processing" || variant === "withdrawal-pending" || variant === "payment-skipped") {
    return "bg-[#f97316]";
  }

  if (variant === "withdrawal-approved") {
    return "bg-[#4f46e5]";
  }

  if (variant === "payment-failed" || variant === "withdrawal-rejected") {
    return "bg-[#e11d48]";
  }

  return "bg-[#94a3b8]";
}

function domainStatusMeta(status: KavenixAdminUserRow["latestDomainStatus"] | KavenixAdminDomainRow["domainStatus"]) {
  if (status === "verified") {
    return { label: "검증 완료", tone: "green" as const };
  }

  if (status === "failed") {
    return { label: "점검 필요", tone: "rose" as const };
  }

  if (status === "pending") {
    return { label: "대기 중", tone: "amber" as const };
  }

  return { label: "-", tone: "slate" as const };
}

function mailboxStatusMeta(
  status:
    | KavenixAdminUserRow["latestMailboxStatus"]
    | KavenixAdminDomainRow["mailboxStatus"]
    | KavenixAdminMailboxRow["status"],
) {
  if (status === "active") {
    return { label: "활성", tone: "green" as const };
  }

  if (status === "pending_dns") {
    return { label: "DNS 대기", tone: "amber" as const };
  }

  if (status === "disabled") {
    return { label: "사용 중지", tone: "rose" as const };
  }

  return { label: "-", tone: "slate" as const };
}

function billingStatusMeta(status: KavenixAdminUserRow["subscriptionStatus"] | KavenixAdminDomainRow["subscriptionStatus"]) {
  if (status === "active") {
    return { label: "자동결제 활성", tone: "green" as const };
  }

  if (status === "paused") {
    return { label: "일시중지", tone: "amber" as const };
  }

  if (status === "cancelled") {
    return { label: "해지", tone: "rose" as const };
  }

  if (status === "pending") {
    return { label: "등록 대기", tone: "blue" as const };
  }

  return { label: "미등록", tone: "slate" as const };
}

function chargeStatusMeta(
  status:
    | KavenixAdminUserRow["lastChargeStatus"]
    | KavenixAdminDomainRow["lastChargeStatus"]
    | KavenixAdminChargeRow["chargeStatus"],
) {
  if (status === "success") {
    return { label: "성공", tone: "green" as const };
  }

  if (status === "failed") {
    return { label: "실패", tone: "rose" as const };
  }

  if (status === "requested") {
    return { label: "요청됨", tone: "blue" as const };
  }

  if (status === "skipped") {
    return { label: "건너뜀", tone: "amber" as const };
  }

  return { label: "-", tone: "slate" as const };
}

function refundStateMeta(state: KavenixAdminChargeRefundState) {
  if (state === "processing") {
    return { label: "환불 처리 중", tone: "amber" as const };
  }

  if (state === "refunded") {
    return { label: "전액 환불 완료", tone: "green" as const };
  }

  if (state === "partial") {
    return { label: "부분 환불", tone: "blue" as const };
  }

  return { label: "환불 전", tone: "slate" as const };
}

function latestRefundMeta(status: KavenixAdminChargeRow["latestRefundStatus"]) {
  if (status === "success") {
    return { label: "최근 환불 성공", tone: "green" as const };
  }

  if (status === "failed") {
    return { label: "최근 환불 실패", tone: "rose" as const };
  }

  if (status === "pending") {
    return { label: "환불 대기", tone: "amber" as const };
  }

  return { label: "-", tone: "slate" as const };
}

function cancellationReviewMeta(row: KavenixAdminChargeRow) {
  if (!row.cancellationRequestId || !row.cancellationReviewStatus) {
    return null;
  }

  if (row.cancellationRequestStatus === "processing") {
    return { label: "청약철회 진행", tone: "amber" as const };
  }

  if (row.cancellationReviewStatus === "pending_review") {
    return { label: "청약철회 신청", tone: "amber" as const };
  }

  if (row.cancellationReviewStatus === "approved_partial") {
    return row.cancellationRequestStatus === "completed"
      ? { label: "부분 환불 완료", tone: "green" as const }
      : { label: "부분 환불 승인", tone: "blue" as const };
  }

  if (row.cancellationReviewStatus === "approved_full") {
    return row.cancellationRequestStatus === "completed"
      ? { label: "청약철회 완료", tone: "green" as const }
      : { label: "청약철회 승인", tone: "blue" as const };
  }

  if (row.cancellationReviewStatus === "rejected") {
    return { label: "청약철회 반려", tone: "rose" as const };
  }

  if (row.cancellationReviewStatus === "cancelled_by_user") {
    return { label: "청약철회 요청 취소", tone: "slate" as const };
  }

  return { label: "청약철회 연결", tone: "slate" as const };
}

function chargeStageMeta(row: KavenixAdminChargeRow) {
  const cancellationMeta = cancellationReviewMeta(row);

  if (cancellationMeta) {
    if (row.cancellationReviewStatus === "rejected") {
      return { ...cancellationMeta, variant: "withdrawal-rejected" as const };
    }

    if (row.cancellationReviewStatus === "cancelled_by_user") {
      return { ...cancellationMeta, variant: "muted" as const };
    }

    if (row.cancellationRequestStatus === "completed") {
      return {
        ...cancellationMeta,
        variant: row.cancellationReviewStatus === "approved_partial" ? ("refund-partial" as const) : ("refund-full" as const),
      };
    }

    if (row.cancellationReviewStatus === "approved_partial" || row.cancellationReviewStatus === "approved_full") {
      return { ...cancellationMeta, variant: "withdrawal-approved" as const };
    }

    return { ...cancellationMeta, variant: "withdrawal-pending" as const };
  }

  if (row.latestRefundStatus === "pending" || row.refundState === "processing") {
    return { label: "환불 진행", tone: "amber" as const, variant: "refund-processing" as const };
  }

  if (row.refundState === "refunded") {
    return { label: "전액 환불 완료", tone: "green" as const, variant: "refund-full" as const };
  }

  if (row.refundState === "partial") {
    return { label: "부분 환불", tone: "blue" as const, variant: "refund-partial" as const };
  }

  if (row.chargeStatus === "success") {
    return { label: "결제완료", tone: "green" as const, variant: "payment-success" as const };
  }

  if (row.chargeStatus === "failed") {
    return { label: "결제 실패", tone: "rose" as const, variant: "payment-failed" as const };
  }

  if (row.chargeStatus === "requested") {
    return { label: "결제 요청", tone: "blue" as const, variant: "payment-requested" as const };
  }

  if (row.chargeStatus === "skipped") {
    return { label: "청구 건너뜀", tone: "amber" as const, variant: "payment-skipped" as const };
  }

  return { label: "-", tone: "slate" as const, variant: "muted" as const };
}

function SummaryRail({ className = "", summary }: { className?: string; summary: KavenixAdminSummary }) {
  const items = [
    ["전체 사용자", `${summary.totalUsers.toLocaleString("ko-KR")}명`],
    ["연결 도메인", `${summary.totalDomains.toLocaleString("ko-KR")}개`],
    ["활성 멤버", `${summary.activeMembers.toLocaleString("ko-KR")}명`],
    ["월 예상 매출", formatCurrency(summary.expectedMonthlyRevenue)],
    ["활성 정기결제", `${summary.activeSubscriptions.toLocaleString("ko-KR")}건`],
    ["최근 30일 성공 청구", `${summary.successfulCharges30d.toLocaleString("ko-KR")}건`],
  ] as const;

  return (
    <div className={`${className} border-b border-[#edf1f6] bg-white`}>
      <div className={`flex overflow-x-auto ${ADMIN_X_PADDING}`}>
        {items.map(([label, value], index) => (
          <div
            key={label}
            className={`min-w-[154px] shrink-0 py-3 pr-6 ${
              index !== 0 ? "border-l border-[#edf2fb] pl-6" : ""
            }`}
          >
            <p className="text-[12px] font-medium text-[#7c879b]">
              {label}
            </p>
            <p className="mt-1 text-[16px] font-semibold tracking-[-0.03em] text-[#16233c]">
              {value}
            </p>
          </div>
        ))}
      </div>
    </div>
  );
}

function formatConversionRate(value: number, base: number) {
  if (base <= 0) {
    return "-";
  }

  return `${((value / base) * 100).toFixed(1)}%`;
}

function MarketingRangeSelector({
  drilldown,
  rangeDays,
}: {
  drilldown: KavenixMarketingDrilldown | null;
  rangeDays: KavenixMarketingRangeDays;
}) {
  return (
    <div className="flex items-center gap-1.5" aria-label="유입 분석 기간">
      {([7, 30, 90] as const).map((days) => {
        const active = days === rangeDays;

        return (
          <Link
            key={days}
            href={buildAdminHref({ marketingDrilldown: drilldown, rangeDays: days, view: "analytics" })}
            className={`inline-flex h-9 items-center rounded-[10px] px-3 text-[13px] font-semibold transition-colors ${
              active
                ? "bg-[#edf4ff] text-[#2f6df6]"
                : "text-[#6d7e9a] hover:bg-[#f5f8fc] hover:text-[#2f6df6]"
            }`}
          >
            최근 {days}일
          </Link>
        );
      })}
    </div>
  );
}

function MarketingFunnelRail({ analytics }: { analytics: KavenixMarketingAnalytics }) {
  const { metrics } = analytics;
  const steps = [
    {
      description: "공개 페이지 방문",
      label: "유입 방문자",
      value: metrics.landingVisitors,
    },
    {
      description: `유입 대비 ${formatConversionRate(metrics.signups, metrics.landingVisitors)}`,
      label: "가입 완료",
      value: metrics.signups,
    },
    {
      description: `가입 대비 ${formatConversionRate(metrics.domainVerified, metrics.signups)}`,
      label: "도메인 연결",
      value: metrics.domainVerified,
    },
    {
      description: `연결 대비 ${formatConversionRate(metrics.growthPlanStarted, metrics.domainVerified)}`,
      label: "성장플랜 전환",
      value: metrics.growthPlanStarted,
    },
  ] as const;

  return (
    <section className="border-b border-[#edf1f6] bg-white">
      <div className={`flex overflow-x-auto ${ADMIN_X_PADDING}`}>
        {steps.map((step, index) => (
          <div
            key={step.label}
            className={`min-w-[170px] shrink-0 py-4 pr-6 ${
              index > 0 ? "border-l border-[#edf2fb] pl-6" : ""
            }`}
          >
            <p className="text-[12px] font-medium text-[#7c879b]">{step.label}</p>
            <p className="mt-1.5 text-[24px] font-semibold tracking-[-0.05em] text-[#16233c]">
              {step.value.toLocaleString("ko-KR")}
            </p>
            <p className="mt-1 text-[12px] text-[#70819d]">{step.description}</p>
          </div>
        ))}
      </div>
    </section>
  );
}

function MarketingTrend({ analytics }: { analytics: KavenixMarketingAnalytics }) {
  if (analytics.dailyVisitors.length === 0) {
    return (
      <div className="flex h-[176px] items-center justify-center border-t border-[#edf1f6] text-[13px] text-[#7c8da8]">
        아직 집계된 유입이 없습니다.
      </div>
    );
  }

  const maxVisitors = Math.max(
    1,
    ...analytics.dailyVisitors.map((row) => row.visitors),
  );

  return (
    <div className="border-t border-[#edf1f6] px-3 pb-3 pt-5 sm:px-4 lg:px-8">
      <div className="flex h-[128px] min-w-[420px] items-end gap-1.5">
        {analytics.dailyVisitors.map((row) => {
          const height = Math.max(5, Math.round((row.visitors / maxVisitors) * 100));

          return (
            <div key={row.day} className="flex min-w-0 flex-1 flex-col items-center justify-end gap-2">
              <div
                className="w-full rounded-t-[4px] bg-[#8bb2ff] transition-colors hover:bg-[#2f6df6]"
                style={{ height: `${height}%` }}
                title={`${row.day} ${row.visitors.toLocaleString("ko-KR")}명`}
              />
              <span className="whitespace-nowrap text-[10px] text-[#8795ad]">{row.day}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function MarketingTrafficList({
  dimension,
  heading,
  rangeDays,
  rows,
}: {
  dimension: KavenixMarketingDrilldownDimension;
  heading: string;
  rangeDays: KavenixMarketingRangeDays;
  rows: Array<{ label?: string; path?: string; visitors: number }>;
}) {
  return (
    <section className="min-w-0">
      <div className="border-b border-[#edf1f6] px-3 py-3 sm:px-4 lg:px-8">
        <h2 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">{heading}</h2>
      </div>
      {rows.length > 0 ? (
        <div>
          {rows.map((row, index) => {
            const label = row.path ?? row.label ?? "-";

            const drilldown = {
              dimension,
              value: label,
            } satisfies KavenixMarketingDrilldown;

            return (
              <Link
                key={`${label}-${index}`}
                href={buildAdminHref({ marketingDrilldown: drilldown, rangeDays, view: "analytics" })}
                className="flex items-center justify-between gap-4 border-b border-[#edf1f6] px-3 py-3 text-[13px] last:border-b-0 sm:px-4 lg:px-8"
              >
                <span className="min-w-0 truncate font-medium text-[#30425f] transition-colors hover:text-[#2f6df6]" title={label}>
                  {label}
                </span>
                <span className="shrink-0 font-semibold text-[#2f6df6]">
                  {row.visitors.toLocaleString("ko-KR")}명
                </span>
              </Link>
            );
          })}
        </div>
      ) : (
        <div className="px-3 py-8 text-[13px] text-[#7c8da8] sm:px-4 lg:px-8">
          집계된 데이터가 없습니다.
        </div>
      )}
    </section>
  );
}

function MarketingDrilldownPanel({
  drilldown,
  rangeDays,
}: {
  drilldown: NonNullable<KavenixMarketingAnalytics["drilldown"]>;
  rangeDays: KavenixMarketingRangeDays;
}) {
  const metrics = [
    ["유입 방문자", drilldown.metrics.landingVisitors],
    ["가입 완료", drilldown.metrics.signups],
    ["도메인 연결", drilldown.metrics.domainVerified],
    ["성장플랜 전환", drilldown.metrics.growthPlanStarted],
    ["관측 네트워크", drilldown.metrics.networks],
  ] as const;
  const breakdownHeading = drilldown.dimension === "page" ? "이 페이지의 유입 경로" : "이 경로의 랜딩 페이지";

  return (
    <section className="border-b border-[#edf1f6] bg-white">
      <div className={`border-b border-[#edf1f6] py-4 ${ADMIN_X_PADDING}`}>
        <div className="min-w-0">
          <Link
            href={buildAdminHref({ rangeDays, view: "analytics" })}
            className="-ml-1 inline-flex h-7 items-center gap-1 rounded-[8px] px-1 text-[12px] font-semibold text-[#607493] transition-colors hover:text-[#2f6df6]"
          >
            <ArrowLeftIcon className="h-[15px] w-[15px]" />
            <span>돌아가기</span>
          </Link>
          <p className="mt-2 text-[12px] font-semibold text-[#2f6df6]">유입 상세</p>
          <h2 className="mt-1 truncate text-[16px] font-semibold tracking-[-0.04em] text-[#16233c]" title={drilldown.label}>
            {drilldown.label}
          </h2>
          <p className="mt-1.5 text-[12px] leading-5 text-[#70819d]">
            같은 방문자 ID의 가입, 도메인 연결, 성장플랜 전환을 기간 안에서 함께 계산합니다.
          </p>
        </div>
      </div>

      <div className={`flex overflow-x-auto border-b border-[#edf1f6] ${ADMIN_X_PADDING}`}>
        {metrics.map(([label, value], index) => (
          <div key={label} className={`min-w-[154px] shrink-0 py-3.5 pr-6 ${index > 0 ? "border-l border-[#edf2fb] pl-6" : ""}`}>
            <p className="text-[12px] font-medium text-[#7c879b]">{label}</p>
            <p className="mt-1 text-[21px] font-semibold tracking-[-0.05em] text-[#16233c]">{value.toLocaleString("ko-KR")}</p>
            <p className="mt-1 text-[11px] text-[#7183a1]">
              {label === "유입 방문자" ? "선택 유입 기준" : `유입 대비 ${formatConversionRate(value, drilldown.metrics.landingVisitors)}`}
            </p>
          </div>
        ))}
      </div>

      <div className="grid lg:grid-cols-[minmax(0,1fr)_320px]">
        <div className="min-w-0 border-b border-[#edf1f6] lg:border-b-0">
          <div className="border-b border-[#edf1f6] px-3 py-3 sm:px-4 lg:px-8">
            <h3 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">일별 전환 흐름</h3>
          </div>
          {drilldown.daily.length > 0 ? (
            <div className="overflow-x-auto">
              <table className="w-full min-w-[620px] border-collapse text-left">
                <thead className="border-b border-[#edf1f6] text-[12px] font-semibold text-[#7c879b]">
                  <tr>
                    <th className="px-3 py-2.5 sm:px-4 lg:px-8">날짜</th>
                    <th className="px-3 py-2.5 text-right">방문</th>
                    <th className="px-3 py-2.5 text-right">가입</th>
                    <th className="px-3 py-2.5 text-right">도메인</th>
                    <th className="px-3 py-2.5 text-right sm:px-4 lg:px-8">성장플랜</th>
                  </tr>
                </thead>
                <tbody>
                  {drilldown.daily.map((row) => (
                    <tr key={row.day} className="border-b border-[#edf1f6] text-[13px] text-[#33445f] last:border-b-0">
                      <td className="px-3 py-3 font-medium sm:px-4 lg:px-8">{row.day}</td>
                      <td className="px-3 py-3 text-right">{row.visitors.toLocaleString("ko-KR")}</td>
                      <td className="px-3 py-3 text-right">{row.signups.toLocaleString("ko-KR")}</td>
                      <td className="px-3 py-3 text-right">{row.domainVerified.toLocaleString("ko-KR")}</td>
                      <td className="px-3 py-3 text-right font-semibold text-[#2f6df6] sm:px-4 lg:px-8">{row.growthPlanStarted.toLocaleString("ko-KR")}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ) : (
            <p className="px-3 py-8 text-[13px] text-[#7284a4] sm:px-4 lg:px-8">선택한 유입의 세부 데이터가 없습니다.</p>
          )}
        </div>

        <div className="min-w-0 lg:border-l lg:border-[#edf1f6]">
          <div className="border-b border-[#edf1f6] px-3 py-3 sm:px-4 lg:px-6">
            <h3 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">{breakdownHeading}</h3>
          </div>
          {drilldown.breakdown.length > 0 ? (
            drilldown.breakdown.map((row, index) => (
              <div key={`${row.label}-${index}`} className="flex items-center justify-between gap-3 border-b border-[#edf1f6] px-3 py-3 text-[13px] last:border-b-0 sm:px-4 lg:px-6">
                <span className="min-w-0 truncate font-medium text-[#30425f]" title={row.label}>{row.label}</span>
                <span className="shrink-0 font-semibold text-[#2f6df6]">{row.visitors.toLocaleString("ko-KR")}명</span>
              </div>
            ))
          ) : (
            <p className="px-3 py-8 text-[13px] text-[#7284a4] sm:px-4 lg:px-6">분석 가능한 세부 유입이 없습니다.</p>
          )}
        </div>
      </div>

      <div className="grid border-t border-[#edf1f6] sm:grid-cols-2">
        <section className="min-w-0">
          <div className="border-b border-[#edf1f6] px-3 py-3 sm:px-4 lg:px-8">
            <h3 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">기기별 유입</h3>
          </div>
          {drilldown.devices.length > 0 ? drilldown.devices.map((row, index) => (
            <div key={`${row.label}-${index}`} className="flex items-center justify-between gap-3 border-b border-[#edf1f6] px-3 py-3 text-[13px] last:border-b-0 sm:px-4 lg:px-8">
              <span className="min-w-0 truncate font-medium text-[#30425f]">{row.label}</span>
              <span className="shrink-0 font-semibold text-[#2f6df6]">{row.visitors.toLocaleString("ko-KR")}명</span>
            </div>
          )) : <p className="px-3 py-6 text-[13px] text-[#7284a4] sm:px-4 lg:px-8">새로운 유입부터 기기 정보가 표시됩니다.</p>}
        </section>
        <section className="min-w-0 border-t border-[#edf1f6] sm:border-l sm:border-t-0">
          <div className="border-b border-[#edf1f6] px-3 py-3 sm:px-4 lg:px-8">
            <h3 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">리퍼러 경로</h3>
          </div>
          {drilldown.referrers.length > 0 ? drilldown.referrers.map((row, index) => (
            <div key={`${row.label}-${index}`} className="flex items-center justify-between gap-3 border-b border-[#edf1f6] px-3 py-3 text-[13px] last:border-b-0 sm:px-4 lg:px-8">
              <span className="min-w-0 truncate font-medium text-[#30425f]" title={row.label}>{row.label}</span>
              <span className="shrink-0 font-semibold text-[#2f6df6]">{row.visitors.toLocaleString("ko-KR")}명</span>
            </div>
          )) : <p className="px-3 py-6 text-[13px] text-[#7284a4] sm:px-4 lg:px-8">새로운 유입부터 리퍼러 경로가 표시됩니다.</p>}
        </section>
      </div>

      <section className="border-t border-[#edf1f6]">
        <div className={`flex flex-col gap-1 border-b border-[#edf1f6] py-3 ${ADMIN_X_PADDING} sm:flex-row sm:items-center sm:justify-between`}>
          <div>
            <h3 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">최근 익명 유입</h3>
            <p className="mt-1 text-[12px] text-[#7183a1]">
              원본 IP와 리퍼러 쿼리스트링은 저장하지 않고, 해시·대역 및 경로 정보만 분석에 사용합니다.
            </p>
          </div>
          <span className="text-[12px] font-medium text-[#7c8da8]">최근 {drilldown.recentVisits.length}건</span>
        </div>
        {drilldown.recentVisits.length > 0 ? (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[1060px] border-collapse text-left">
              <thead className="border-b border-[#edf1f6] text-[12px] font-semibold text-[#7c879b]">
                <tr>
                  <th className="px-3 py-2.5 sm:px-4 lg:px-8">시각</th>
                  <th className="px-3 py-2.5">랜딩</th>
                  <th className="px-3 py-2.5">리퍼러</th>
                  <th className="px-3 py-2.5">환경</th>
                  <th className="px-3 py-2.5">네트워크</th>
                  <th className="px-3 py-2.5">언어·시간대</th>
                  <th className="px-3 py-2.5 sm:px-4 lg:px-8">화면</th>
                </tr>
              </thead>
              <tbody>
                {drilldown.recentVisits.map((visit, index) => (
                  <tr key={`${visit.occurredAt ?? "unknown"}-${visit.landingPath}-${index}`} className="border-b border-[#edf1f6] text-[13px] text-[#33445f] last:border-b-0">
                    <td className="whitespace-nowrap px-3 py-3 text-[#7183a1] sm:px-4 lg:px-8">{formatDateTime(visit.occurredAt)}</td>
                    <td className="max-w-[190px] truncate px-3 py-3 font-medium" title={visit.landingPath}>{visit.landingPath}</td>
                    <td className="max-w-[220px] truncate px-3 py-3" title={visit.referrer ?? "직접 방문"}>{visit.referrer ?? "직접 방문"}</td>
                    <td className="whitespace-nowrap px-3 py-3">{[visit.device, visit.browser, visit.operatingSystem].filter(Boolean).join(" · ") || "알 수 없음"}</td>
                    <td className="whitespace-nowrap px-3 py-3">{[visit.network, visit.country].filter(Boolean).join(" · ") || "미수집"}</td>
                    <td className="whitespace-nowrap px-3 py-3">{[visit.language, visit.timezone].filter(Boolean).join(" · ") || "미수집"}</td>
                    <td className="whitespace-nowrap px-3 py-3 sm:px-4 lg:px-8">{visit.viewport ?? "미수집"}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : (
          <p className={`py-8 text-[13px] text-[#7284a4] ${ADMIN_X_PADDING}`}>
            새로운 유입부터 익명 환경 데이터가 표시됩니다.
          </p>
        )}
      </section>
    </section>
  );
}

function MarketingAnalyticsDashboard({ analytics }: { analytics: KavenixMarketingAnalytics }) {
  return (
    <>
      <MarketingFunnelRail analytics={analytics} />
      {analytics.drilldown ? <MarketingDrilldownPanel drilldown={analytics.drilldown} rangeDays={analytics.rangeDays} /> : null}
      <section className="border-b border-[#edf1f6] bg-white">
        <div className="flex flex-col gap-2 px-3 pb-3 pt-4 sm:px-4 lg:flex-row lg:items-center lg:justify-between lg:px-8">
          <div>
            <h2 className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">일별 유입</h2>
            <p className="mt-1 text-[12px] text-[#70819d]">
              방문자 ID 기준으로 중복을 제외한 일별 공개 페이지 유입입니다.
            </p>
          </div>
          {analytics.trackingStartedAt ? (
            <p className="text-[12px] text-[#8a98b0]">
              측정 시작 {formatDateTime(analytics.trackingStartedAt)}
            </p>
          ) : null}
        </div>
        <div className="overflow-x-auto">
          <MarketingTrend analytics={analytics} />
        </div>
      </section>
      <section className="grid bg-white lg:grid-cols-2">
        <MarketingTrafficList
          dimension="page"
          heading="상위 랜딩 페이지"
          rangeDays={analytics.rangeDays}
          rows={analytics.landingPages.map((row) => ({
            path: row.path,
            visitors: row.visitors,
          }))}
        />
        <div className="border-t border-[#edf1f6] lg:border-l lg:border-t-0">
          <MarketingTrafficList
            dimension="channel"
            heading="유입 경로"
            rangeDays={analytics.rangeDays}
            rows={analytics.channels.map((row) => ({
              label: row.label,
              visitors: row.visitors,
            }))}
          />
        </div>
      </section>
    </>
  );
}

function UsersTable({ query, rows }: { query: string; rows: KavenixAdminUserRow[] }) {
  if (rows.length === 0) {
    return (
      <div className="border-t border-[#edf2fb] px-0 py-8 text-[14px] leading-7 text-[#7284a4]">
        {query ? "검색 조건에 맞는 사용자가 없습니다." : "아직 등록된 사용자가 없습니다."}
      </div>
    );
  }

  return (
    <div className="overflow-x-auto">
      <table className="min-w-[1200px] w-full border-collapse">
        <thead>
          <tr className="border-b border-[#edf1f6] text-left text-[12px] font-semibold text-[#7c879b]">
            <th className={`${ADMIN_CELL_START} py-2.5`}>사용자</th>
            <th className="px-4 py-2.5">대표 도메인</th>
            <th className="px-4 py-2.5">대표 메일</th>
            <th className="px-4 py-2.5">운영 수량</th>
            <th className="px-4 py-2.5">결제 상태</th>
            <th className={`pl-4 py-2.5 ${ADMIN_CELL_END}`}>최근 청구</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => {
            const isRepresentativeOwner = row.isRepresentativeOwner;
            const domainMeta = domainStatusMeta(row.latestDomainStatus);
            const mailboxMeta = mailboxStatusMeta(row.latestMailboxStatus);
            const billingMeta = billingStatusMeta(row.subscriptionStatus);
            const chargeMeta = chargeStatusMeta(row.lastChargeStatus);

            return (
              <tr
                key={row.id}
                className="border-b border-[#edf1f6] align-top text-[13px] text-[#31415f] transition-colors hover:bg-[#fafcff] last:border-b-0"
              >
                <td className={`${ADMIN_CELL_START} py-3.5`}>
                  <p className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {row.companyName || row.displayName || row.email}
                  </p>
                  <p className="mt-1 text-[12px] text-[#70819d]">{row.displayName || "-"}</p>
                  <p className="mt-1 break-all text-[12px] text-[#4d6186]">{row.email}</p>
                </td>
                <td className="px-4 py-3.5">
                  {isRepresentativeOwner ? (
                    <div className="flex flex-col gap-1.5">
                      {row.latestDomain ? (
                        <a
                          href={`https://${row.latestDomain}`}
                          target="_blank"
                          rel="noreferrer"
                          className="w-fit text-[14px] font-semibold text-[#2f6df6] hover:text-[#245de3]"
                        >
                          {row.latestDomain}
                        </a>
                      ) : (
                        <span className="text-[14px] font-semibold text-[#8a98b0]">-</span>
                      )}
                      <span className={`om-badge om-badge-sm w-fit ${badgeClass(domainMeta.tone)}`}>
                        {domainMeta.label}
                      </span>
                      <p className="text-[12px] text-[#70819d]">최근 점검 {formatDateTime(row.latestDomainVerifiedAt)}</p>
                    </div>
                  ) : (
                    <span className="text-[13px] text-[#8a98b0]">-</span>
                  )}
                </td>
                <td className="px-4 py-3.5">
                  {isRepresentativeOwner ? (
                    <div className="flex flex-col gap-1.5">
                      <p className="break-all text-[13px] font-medium text-[#30425f]">
                        {row.latestMailboxEmail ?? "-"}
                      </p>
                      <span className={`om-badge om-badge-sm w-fit ${badgeClass(mailboxMeta.tone)}`}>
                        {mailboxMeta.label}
                      </span>
                    </div>
                  ) : (
                    <span className="text-[13px] text-[#8a98b0]">-</span>
                  )}
                </td>
                <td className="px-4 py-3.5">
                  {isRepresentativeOwner ? (
                    <div className="space-y-1.5">
                      <p className="text-[13px] font-medium text-[#30425f]">
                        도메인 {row.domainCount.toLocaleString("ko-KR")}개
                      </p>
                      <p className="text-[13px] font-medium text-[#30425f]">
                        팀 인원 {row.activeMemberCount.toLocaleString("ko-KR")}명
                      </p>
                      <p className="text-[12px] text-[#70819d]">월 예상 {formatCurrency(row.estimatedMonthlyRevenue)}</p>
                    </div>
                  ) : (
                    <span className="text-[13px] text-[#8a98b0]">-</span>
                  )}
                </td>
                <td className="px-4 py-3.5">
                  {isRepresentativeOwner ? (
                    <div className="flex flex-col gap-1.5">
                      <span className={`om-badge om-badge-sm w-fit ${badgeClass(billingMeta.tone)}`}>
                        {billingMeta.label}
                      </span>
                      <p className="text-[12px] text-[#70819d]">프로필 {row.billingProfileStatus ?? "-"}</p>
                      <p className="text-[12px] text-[#70819d]">다음 청구 {formatDateTime(row.nextChargeAt)}</p>
                    </div>
                  ) : (
                    <span className="text-[13px] text-[#8a98b0]">-</span>
                  )}
                </td>
                <td className={`pl-4 py-3.5 ${ADMIN_CELL_END}`}>
                  {isRepresentativeOwner ? (
                    <div className="flex flex-col gap-1.5">
                      <span className={`om-badge om-badge-sm w-fit ${badgeClass(chargeMeta.tone)}`}>
                        {chargeMeta.label}
                      </span>
                      <p className="text-[12px] text-[#70819d]">최근 시각 {formatDateTime(row.lastChargeAt)}</p>
                    </div>
                  ) : (
                    <span className="text-[13px] text-[#8a98b0]">-</span>
                  )}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function DomainsTable({ query, rows }: { query: string; rows: KavenixAdminDomainRow[] }) {
  if (rows.length === 0) {
    return (
      <div className="border-t border-[#edf2fb] px-0 py-8 text-[14px] leading-7 text-[#7284a4]">
        {query ? "검색 조건에 맞는 도메인이 없습니다." : "아직 연결된 도메인이 없습니다."}
      </div>
    );
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full min-w-[1080px] table-fixed border-collapse">
        <colgroup>
          <col className="w-[17%]" />
          <col className="w-[20%]" />
          <col className="w-[18%]" />
          <col className="w-[11%]" />
          <col className="w-[14%]" />
          <col className="w-[11%]" />
          <col className="w-[9%]" />
        </colgroup>
        <thead>
          <tr className="border-b border-[#edf1f6] text-left text-[12px] font-semibold text-[#7c879b]">
            <th className={`${ADMIN_CELL_START} py-2.5`}>도메인</th>
            <th className="px-4 py-2.5">소유자</th>
            <th className="px-4 py-2.5">대표 메일</th>
            <th className="px-4 py-2.5">팀 인원</th>
            <th className="px-4 py-2.5">결제 상태</th>
            <th className="px-4 py-2.5">최근 청구</th>
            <th className={`pl-4 py-2.5 text-right ${ADMIN_CELL_END}`}>관리</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => {
            const domainMeta = domainStatusMeta(row.domainStatus);
            const mailboxMeta = mailboxStatusMeta(row.mailboxStatus);
            const billingMeta = billingStatusMeta(row.subscriptionStatus);
            const chargeMeta = chargeStatusMeta(row.lastChargeStatus);

            return (
              <tr
                key={row.id}
                className="border-b border-[#edf1f6] align-top text-[13px] text-[#31415f] transition-colors hover:bg-[#fafcff] last:border-b-0"
              >
                <td className={`${ADMIN_CELL_START} py-3.5`}>
                  <div className="flex min-w-0 items-start gap-1.5">
                    <p className="break-all text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">{row.displayDomain}</p>
                    <KavenixDomainDnsPopover
                      domain={row.displayDomain}
                      domainId={row.id}
                      dkimEnabled={row.dkimEnabled}
                      domainStatus={row.domainStatus}
                      lastCheckedAt={row.lastDnsCheckedAt ?? row.verifiedAt}
                      records={row.dnsRecords}
                    />
                  </div>
                  <div className="mt-1.5 flex flex-wrap gap-1.5">
                    <span className={`om-badge om-badge-sm ${badgeClass(domainMeta.tone)}`}>
                      {domainMeta.label}
                    </span>
                    <span className={`om-badge om-badge-sm ${badgeClass(mailboxMeta.tone)}`}>
                      {mailboxMeta.label}
                    </span>
                    {row.mailcowCleanupAt ? (
                      <span className="om-badge om-badge-sm border-[#f2d7d8] bg-[#fff6f6] text-[#c6535a]">
                        정리됨
                      </span>
                    ) : null}
                  </div>
                  <p className="mt-1.5 text-[12px] text-[#70819d]">최근 점검 {formatDateTime(row.lastDnsCheckedAt ?? row.verifiedAt)}</p>
                </td>
                <td className="px-4 py-3.5">
                  <div className="space-y-1.5">
                    <p className="break-all text-[14px] font-semibold text-[#16233c]">
                      {row.companyName || row.displayName || row.ownerEmail}
                    </p>
                    <p className="text-[12px] text-[#70819d]">{row.displayName || "-"}</p>
                    <Link
                      href={buildAdminHref({ view: "users", domain: row.displayDomain })}
                      className="break-all text-[12px] text-[#2f6df6] hover:text-[#245de3]"
                    >
                      {row.ownerEmail}
                    </Link>
                  </div>
                </td>
                <td className="px-4 py-3.5">
                  <p className="break-all text-[13px] font-medium text-[#30425f]">{row.mailboxEmail ?? "-"}</p>
                </td>
                <td className="px-4 py-3.5">
                  <p className="text-[14px] font-semibold text-[#16233c]">{row.activeMemberCount.toLocaleString("ko-KR")}명</p>
                  <p className="mt-1.5 text-[12px] text-[#70819d]">월 예상 {formatCurrency(row.expectedMonthlyRevenue)}</p>
                </td>
                <td className="px-4 py-3.5">
                  <div className="flex flex-col gap-1.5">
                    <span className={`om-badge om-badge-sm w-fit ${badgeClass(billingMeta.tone)}`}>
                      {billingMeta.label}
                    </span>
                    <p className="text-[12px] text-[#70819d]">프로필 {row.billingProfileStatus ?? "-"}</p>
                    <p className="text-[12px] text-[#70819d]">다음 청구 {formatDateTime(row.nextChargeAt)}</p>
                  </div>
                </td>
                <td className="px-4 py-3.5">
                  <div className="flex flex-col gap-1.5">
                    <span className={`om-badge om-badge-sm w-fit ${badgeClass(chargeMeta.tone)}`}>
                      {chargeMeta.label}
                    </span>
                    <p className="text-[12px] text-[#70819d]">최근 시각 {formatDateTime(row.lastChargeAt)}</p>
                  </div>
                </td>
                <td className={`pl-4 py-3.5 text-right ${ADMIN_CELL_END}`}>
                  <KavenixDomainCleanupButton
                    cleanedAt={row.mailcowCleanupAt}
                    domain={row.displayDomain}
                    domainId={row.id}
                  />
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function MailboxesTable({
  query,
  rows,
  selectedDomain,
}: {
  query: string;
  rows: KavenixAdminMailboxRow[];
  selectedDomain: string;
}) {
  if (rows.length === 0) {
    return (
      <div className="border-t border-[#edf2fb] px-0 py-8 text-[14px] leading-7 text-[#7284a4]">
        {selectedDomain
          ? `${selectedDomain}에 등록된 메일함이 없습니다.`
          : query
            ? "검색 조건에 맞는 메일함이 없습니다."
            : "아직 등록된 메일함이 없습니다."}
      </div>
    );
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full min-w-[980px] table-fixed border-collapse">
        <colgroup>
          <col className="w-[27%]" />
          <col className="w-[18%]" />
          <col className="w-[11%]" />
          <col className="w-[15%]" />
          <col className="w-[14%]" />
          <col className="w-[15%]" />
        </colgroup>
        <thead>
          <tr className="border-b border-[#edf1f6] text-left text-[12px] font-semibold text-[#7c879b]">
            <th className={`${ADMIN_CELL_START} py-2.5`}>메일함</th>
            <th className="px-4 py-2.5">도메인</th>
            <th className="px-4 py-2.5">구분</th>
            <th className="px-4 py-2.5">메일 현황</th>
            <th className="px-4 py-2.5">최근 동기화</th>
            <th className={`pl-4 py-2.5 ${ADMIN_CELL_END}`}>상태</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => {
            const mailboxMeta = mailboxStatusMeta(row.status);
            const domainMeta = domainStatusMeta(row.domainStatus);
            const roleLabel = row.isRepresentative ? "대표 계정" : "멤버";
            const roleClass = row.isRepresentative
              ? "border-[#d8e4ff] bg-[#f5f8ff] text-[#2f6df6]"
              : "border-[#e3e9f2] bg-[#f8fafc] text-[#5d6f8b]";

            return (
              <tr
                key={row.id}
                className="border-b border-[#edf1f6] align-top text-[13px] text-[#31415f] transition-colors hover:bg-[#fafcff] last:border-b-0"
              >
                <td className={`${ADMIN_CELL_START} py-3.5`}>
                  <p className="break-all text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">{row.email}</p>
                  <p className="mt-1 text-[12px] text-[#70819d]">{row.displayName || "-"}</p>
                  {row.accountEmail !== row.email ? (
                    <p className="mt-1 break-all text-[12px] text-[#8a9ab5]">로그인 {row.accountEmail}</p>
                  ) : null}
                </td>
                <td className="px-4 py-3.5">
                  <Link
                    href={buildAdminHref({ view: "mailboxes", domain: row.domain })}
                    className="break-all text-[13px] font-semibold text-[#2f6df6] hover:text-[#245de3]"
                  >
                    {row.domain}
                  </Link>
                  <p className="mt-1.5 break-all text-[12px] text-[#70819d]">소유자 {row.ownerEmail}</p>
                </td>
                <td className="px-4 py-3.5">
                  <span className={`om-badge om-badge-sm ${roleClass}`}>{roleLabel}</span>
                </td>
                <td className="px-4 py-3.5">
                  <p className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {row.inboxTotal.toLocaleString("ko-KR")}통
                  </p>
                  <p className={`mt-1.5 text-[12px] ${row.inboxUnread > 0 ? "font-semibold text-[#2f6df6]" : "text-[#70819d]"}`}>
                    안읽음 {row.inboxUnread.toLocaleString("ko-KR")}통
                  </p>
                </td>
                <td className="px-4 py-3.5">
                  <p className="text-[12px] leading-5 text-[#5d7195]">{formatDateTime(row.lastSyncAt)}</p>
                  {row.lastSyncError ? (
                    <p className="mt-1 max-w-[180px] truncate text-[12px] text-[#c6535a]" title={row.lastSyncError}>
                      동기화 오류
                    </p>
                  ) : null}
                </td>
                <td className={`pl-4 py-3.5 ${ADMIN_CELL_END}`}>
                  <div className="flex flex-wrap gap-1.5">
                    <span className={`om-badge om-badge-sm ${badgeClass(mailboxMeta.tone)}`}>{mailboxMeta.label}</span>
                    <span className={`om-badge om-badge-sm ${badgeClass(domainMeta.tone)}`}>{domainMeta.label}</span>
                    {row.managedMemberStatus === "disabled" ? (
                      <span className="om-badge om-badge-sm border-[#f2d7d8] bg-[#fff6f6] text-[#c6535a]">멤버 중지</span>
                    ) : null}
                  </div>
                  <p className="mt-1.5 text-[12px] text-[#70819d]">등록 {formatDateTime(row.createdAt)}</p>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function ChargesTable({ query, rows }: { query: string; rows: KavenixAdminChargeRow[] }) {
  if (rows.length === 0) {
    return (
      <div className="border-t border-[#edf2fb] px-0 py-8 text-[14px] leading-7 text-[#7284a4]">
        {query ? "검색 조건에 맞는 결제 내역이 없습니다." : "아직 저장된 결제 내역이 없습니다."}
      </div>
    );
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full min-w-[1080px] table-fixed border-collapse">
        <colgroup>
          <col className="w-[18%]" />
          <col className="w-[24%]" />
          <col className="w-[13%]" />
          <col className="w-[12%]" />
          <col className="w-[12%]" />
          <col className="w-[12%]" />
          <col className="w-[9%]" />
        </colgroup>
        <thead>
          <tr className="border-b border-[#edf1f6] text-left text-[12px] font-semibold text-[#7c879b]">
            <th className={`${ADMIN_CELL_START} py-2.5`}>사용자</th>
            <th className="px-4 py-2.5">상품 / 주문</th>
            <th className="px-4 py-2.5">결제수단</th>
            <th className="px-4 py-2.5">승인 금액</th>
            <th className="px-4 py-2.5">상태</th>
            <th className="px-4 py-2.5">승인 시각</th>
            <th className={`pl-4 py-2.5 text-right ${ADMIN_CELL_END}`}>관리</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => {
            const refundMeta = refundStateMeta(row.refundState);
            const latestRefund = latestRefundMeta(row.latestRefundStatus);
            const cancellationMeta = cancellationReviewMeta(row);
            const stageMeta = chargeStageMeta(row);
            const reviewPending =
              row.cancellationRequestId !== null &&
              row.cancellationReviewStatus === "pending_review" &&
              row.cancellationRequestStatus === "pending";
            const buttonLabel =
              row.refundedAmount > 0 && row.remainingRefundableAmount > 0 ? "잔액 환불" : "전액 환불";
            const primaryName = row.companyName || row.displayName || row.ownerEmail;
            const paymentLabel =
              [row.cardCompanyName, row.cardNum4Print ? `(${row.cardNum4Print})` : null]
                .filter(Boolean)
                .join(" ") || row.payMethod || "-";

            let disabledReason = "";

            if (row.chargeStatus !== "success") {
              disabledReason = "성공 승인된 결제만 환불할 수 있습니다.";
            } else if (reviewPending) {
              disabledReason = "청약철회 검토 대기 중인 결제는 먼저 승인 또는 반려를 결정해 주세요.";
            } else if (!row.payTokenAvailable) {
              disabledReason = "환불 토큰이 없는 결제라서 취소를 진행할 수 없습니다.";
            } else if (row.pendingRefundCount > 0) {
              disabledReason = "이미 환불 처리 중인 요청이 있습니다.";
            } else if (row.remainingRefundableAmount <= 0) {
              disabledReason = "이미 전액 환불된 결제입니다.";
            }

            const stageBadgeClass = chargeStageBadgeClass(stageMeta.variant);
            const detailBadges = [{ label: stageMeta.label, className: stageBadgeClass }];

            const summaryRows = [
              { label: "주문번호", value: row.orderNo },
              { label: "상품", value: row.productDesc },
              { label: "도메인", value: row.displayDomain ?? "-" },
              { label: "대표 메일", value: row.latestMailboxEmail ?? "-" },
              { label: "소유자", value: row.ownerEmail },
              { label: "요청 시각", value: formatDateTime(row.requestedAt) },
            ];

            const paymentRows = [
              { label: "승인 금액", value: formatCurrency(row.amount) },
              { label: "면세 금액", value: formatCurrency(row.amountTaxFree) },
              { label: "결제수단", value: row.payMethod ?? "-" },
              { label: "카드 정보", value: paymentLabel },
              { label: "청구 방식", value: row.chargeKind === "cycle" ? "정기 청구" : "즉시 청구" },
              { label: "승인 시각", value: formatDateTime(row.approvedAt) },
            ];

            const refundRows = [
              { label: "환불 상태", value: refundMeta.label },
              { label: "최근 환불 상태", value: latestRefund.label },
              { label: "환불 완료 금액", value: formatCurrency(row.refundedAmount) },
              { label: "남은 환불 가능액", value: formatCurrency(row.remainingRefundableAmount) },
              { label: "최근 환불 요청", value: formatDateTime(row.latestRefundRequestedAt) },
              { label: "최근 환불 완료", value: formatDateTime(row.latestRefundedAt) },
              { label: "최근 요청자", value: row.latestRefundRequestedByEmail ?? "-" },
            ];

            const withdrawalRows = row.cancellationRequestId
              ? [
                  { label: "요청 상태", value: cancellationMeta?.label ?? "-" },
                  { label: "요청 시각", value: formatDateTime(row.cancellationRequestedAt) },
                  { label: "요청자", value: row.cancellationRequestedByEmail ?? "-" },
                  { label: "검토자", value: row.cancellationReviewedByEmail ?? "-" },
                  { label: "검토 시각", value: formatDateTime(row.cancellationReviewedAt) },
                  {
                    label: "승인 환불액",
                    value:
                      row.cancellationApprovedRefundAmount !== null
                        ? formatCurrency(row.cancellationApprovedRefundAmount)
                        : "-",
                  },
                  { label: "처리 결과", value: formatCancellationResult(row.cancellationResultText) },
                ]
              : [];

            const notes = [
              row.errorMessage ? { label: "결제 오류", text: row.errorMessage, tone: "danger" as const } : null,
              row.latestRefundReason ? { label: "환불 사유", text: row.latestRefundReason } : null,
              row.latestRefundErrorMessage
                ? { label: "환불 오류", text: row.latestRefundErrorMessage, tone: "danger" as const }
                : null,
              row.cancellationReviewNote
                ? {
                    label: "검토 메모",
                    text: formatCancellationReviewNote(row.cancellationReviewNote) ?? row.cancellationReviewNote,
                  }
                : null,
            ].filter((note): note is NonNullable<typeof note> => note !== null);

            return (
              <tr
                key={row.id}
                className="border-b border-[#edf1f6] align-top text-[13px] text-[#31415f] transition-colors hover:bg-[#fafcff] last:border-b-0"
              >
                <td className={`${ADMIN_CELL_START} py-3.5`}>
                  <p className="break-all text-[14px] font-semibold tracking-[-0.02em] text-[#16233c]">
                    {primaryName}
                  </p>
                  <p className="mt-1 break-all text-[12px] text-[#5d7195]">{row.ownerEmail}</p>
                  <p className="mt-1 text-[12px] text-[#8a9ab5]">{row.displayDomain ?? "-"}</p>
                </td>
                <td className="px-4 py-3.5">
                  <p className="break-all text-[13px] font-medium leading-5 text-[#30425f]">{row.productDesc}</p>
                  <p className="mt-1.5 break-all text-[12px] text-[#8a9ab5]">{row.orderNo}</p>
                </td>
                <td className="px-4 py-3.5">
                  <p className="break-words text-[13px] font-medium text-[#30425f]">{paymentLabel}</p>
                  <p className="mt-1.5 text-[12px] text-[#8a9ab5]">
                    {row.chargeKind === "cycle" ? "정기 청구" : "즉시 청구"}
                  </p>
                </td>
                <td className="px-4 py-3.5">
                  <p className="text-[14px] font-semibold tracking-[-0.03em] text-[#16233c]">
                    {formatCurrency(row.amount)}
                  </p>
                  {row.refundedAmount > 0 ? (
                    <p className="mt-1.5 text-[12px] text-[#8a9ab5]">
                      환불 {formatCurrency(row.refundedAmount)}
                    </p>
                  ) : null}
                </td>
                <td className="px-4 py-3.5">
                  <span
                    className={`om-badge om-badge-sm gap-1.5 ${stageBadgeClass}`}
                  >
                    <span className={`h-1.5 w-1.5 rounded-full ${chargeStageDotClass(stageMeta.variant)}`} />
                    {stageMeta.label}
                  </span>
                </td>
                <td className="px-4 py-3.5">
                  <p className="text-[12px] leading-5 text-[#5d7195]">
                    {formatDateTime(row.approvedAt ?? row.requestedAt)}
                  </p>
                </td>
                <td className={`pl-4 py-3.5 ${ADMIN_CELL_END}`}>
                  <div className="flex justify-end">
                    <KavenixChargeDetailsDialog
                      title={primaryName}
                      subtitle={`${row.ownerEmail} · ${row.displayDomain ?? "도메인 없음"}`}
                      badges={detailBadges}
                      summaryRows={summaryRows}
                      paymentRows={paymentRows}
                      refundRows={refundRows}
                      withdrawalRows={withdrawalRows}
                      notes={notes}
                      actionHint={
                        disabledReason ||
                        (reviewPending
                          ? "청약철회 요청 검토 후 즉시 상태가 갱신됩니다."
                          : row.latestRefundRequestedByEmail
                            ? `최근 환불 요청자: ${row.latestRefundRequestedByEmail}`
                            : null)
                      }
                      action={
                        reviewPending && row.cancellationRequestId ? (
                          <KavenixCancellationReviewActions
                            requestId={row.cancellationRequestId}
                            remainingRefundableAmount={row.remainingRefundableAmount}
                            className="grid gap-2 sm:grid-cols-3"
                          />
                        ) : (
                          <KavenixChargeRefundButton
                            chargeId={row.id}
                            disabled={!row.canRefund}
                            disabledReason={disabledReason}
                            label={buttonLabel}
                            className={`h-11 rounded-[10px] px-4 text-[13px] font-semibold ${
                              row.canRefund
                                ? "om-btn-primary"
                                : "cursor-not-allowed rounded-[10px] border border-[#d8e3f6] bg-[#f7f9fd] text-[#97a7c2]"
                            }`}
                          />
                        )
                      }
                    />
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

export default async function KavenixPage(props: PageProps<"/kavenix">) {
  const user = await requireSessionUser();

  if (!isKavenixAdminEmail(user.email)) {
    notFound();
  }

  const searchParams = await props.searchParams;
  const view =
    searchParams.view === "analytics" ||
    searchParams.view === "search" ||
    searchParams.view === "blog" ||
    searchParams.view === "domains" ||
    searchParams.view === "mailboxes" ||
    searchParams.view === "charges"
      ? searchParams.view
      : "users";
  const query = typeof searchParams.q === "string" ? searchParams.q : "";
  const selectedDomain = typeof searchParams.domain === "string" ? searchParams.domain : "";
  const chargeFilter = normalizeKavenixChargeFilter(
    typeof searchParams.chargeFilter === "string" ? searchParams.chargeFilter : "",
  );
  const rangeDays = normalizeKavenixMarketingRangeDays(
    typeof searchParams.range === "string" ? searchParams.range : null,
  );
  const marketingDrilldown = normalizeKavenixMarketingDrilldown({
    dimension: typeof searchParams.drill === "string" ? searchParams.drill : null,
    value: typeof searchParams.drillValue === "string" ? searchParams.drillValue : null,
  });
  const googleSearchConsoleStatus = typeof searchParams.gsc === "string" ? searchParams.gsc : null;
  const mailEntryUrl = await getMailEntryUrlForCurrentRequest(user);
  const [
    dataset,
    analytics,
    marketingVisitorCount,
    googleSearchConsoleAnalytics,
    marketingBlogPostCount,
    marketingBlogPosts,
  ] = await Promise.all([
    getKavenixAdminDataset({
      chargeFilter,
      domain: selectedDomain,
      query,
    }),
    view === "analytics"
      ? getKavenixMarketingAnalytics({ drilldown: marketingDrilldown, rangeDays })
      : Promise.resolve(null),
    view === "analytics"
      ? Promise.resolve(null)
      : getKavenixMarketingVisitorCount({ rangeDays }),
    view === "search"
      ? getKavenixGoogleSearchConsoleAnalytics()
      : Promise.resolve(null),
    getKavenixMarketingBlogPostCount(),
    view === "blog"
      ? getKavenixMarketingBlogPosts()
      : Promise.resolve(null),
  ]);

  const resultCount =
    view === "analytics"
      ? (analytics?.metrics.landingVisitors ?? 0)
      : view === "search"
        ? (googleSearchConsoleAnalytics?.metrics.clicks ?? 0)
      : view === "blog"
        ? marketingBlogPostCount
      : view === "users"
      ? dataset.users.length
      : view === "domains"
        ? dataset.domains.length
        : view === "mailboxes"
          ? dataset.mailboxes.length
          : dataset.charges.length;
  const analyticsVisitorCount = analytics?.metrics.landingVisitors ?? marketingVisitorCount ?? 0;

  const sectionTitle =
    view === "analytics"
      ? "유입 분석"
      : view === "search"
        ? "검색 성과"
      : view === "blog"
        ? "블로그 관리"
      : view === "users"
      ? "사용자 목록"
      : view === "domains"
        ? "도메인 목록"
        : view === "mailboxes"
          ? "메일 관리"
          : "결제 내역";
  const sectionDescription =
    view === "analytics"
      ? "공개 페이지 유입부터 가입, 도메인 연결, 성장플랜 전환까지의 퍼널을 기간별로 확인합니다."
      : view === "search"
        ? "Google Search Console을 연결해 검색 유입과 개선 기회를 매일 확인합니다."
      : view === "blog"
        ? "검색 의도에 맞는 가이드를 Markdown으로 작성하고, 미리보기·임시저장·발행 상태를 한곳에서 관리합니다."
      : view === "users"
      ? "대표 도메인, 대표 메일, 활성 멤버, 자동결제 상태를 사용자 기준으로 확인합니다."
      : view === "domains"
        ? "도메인별 소유자, 대표 메일, 활성 멤버, 자동결제 상태를 도메인 기준으로 확인합니다."
        : view === "mailboxes"
          ? "도메인을 선택해 대표 계정과 멤버 메일함의 동기화, 받은메일 수, 사용 상태를 확인합니다."
          : "결제 상태를 빠르게 확인하고, 자세한 기록과 관리자 조치는 상세 팝업에서 처리합니다.";
  const navItems: AdminNavItem[] = [
    {
      count: analyticsVisitorCount,
      description: "유입부터 성장플랜 전환 퍼널",
      label: "유입 분석",
      view: "analytics",
    },
    {
      description: "검색 클릭, 노출, 유입 페이지",
      label: "검색 성과",
      view: "search",
    },
    {
      count: marketingBlogPostCount,
      description: "Markdown 작성과 공개 발행 관리",
      label: "블로그 관리",
      view: "blog",
    },
    {
      count: dataset.users.length,
      description: "계정, 대표 도메인, 결제 상태",
      label: "사용자 목록",
      view: "users",
    },
    {
      count: dataset.domains.length,
      description: "도메인 연결과 메일함 상태",
      label: "도메인 목록",
      view: "domains",
    },
    {
      count: dataset.mailboxes.length,
      description: "도메인별 메일함 상태",
      label: "메일 관리",
      view: "mailboxes",
    },
    {
      count: dataset.charges.length,
      description: "결제, 환불, 청약철회",
      label: "결제 내역",
      view: "charges",
    },
  ];

  return (
    <div className="min-h-screen bg-white text-[#16233c]">
      <div className="flex min-h-screen">
        <AdminSidebar
          chargeFilter={chargeFilter}
          currentView={view}
          domain={selectedDomain}
          items={navItems}
          q={query}
          rangeDays={rangeDays}
          userEmail={user.email}
        />

        <main className="min-w-0 flex-1 bg-white">
          <section className={`border-b border-[#edf1f6] pb-3 pt-4 lg:pb-3 lg:pt-6 ${ADMIN_X_PADDING}`}>
            <div className="mb-3 lg:hidden">
              <AdminMobileMenu
                chargeFilter={chargeFilter}
                currentView={view}
                domain={selectedDomain}
                items={navItems}
                q={query}
                rangeDays={rangeDays}
              />
            </div>

            <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
              <div className="min-w-0">
                <div className="flex flex-wrap items-center gap-x-2 gap-y-2 text-[15px] leading-none sm:gap-x-3 sm:text-[16px]">
                  <h1 className="text-[16px] font-semibold tracking-[-0.03em] text-[#111a33] sm:text-[17px]">
                    {sectionTitle}
                  </h1>
                  <span className="font-semibold text-[#2f6df6]">{resultCount.toLocaleString("ko-KR")}</span>
                  <span className="text-[#7c879b]">{view === "analytics" ? "명" : view === "search" ? "클릭" : "건"}</span>
                </div>
                <p className="mt-2 text-[13px] leading-6 text-[#70819d]">{sectionDescription}</p>
              </div>

              <div className="flex shrink-0 flex-wrap items-center gap-2 text-[13px] text-[#5e7399] lg:justify-end">
                <span className="hidden max-w-[220px] truncate font-medium text-[#70819d] xl:inline">{user.email}</span>
                {view === "users" ? (
                  <KavenixMemberCreateDialog domains={dataset.memberDomainOptions} />
                ) : null}
                <a href={mailEntryUrl} className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] text-[#344767]">
                  메일함
                </a>
                <Link href="/" className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] text-[#344767]">
                  서비스 홈
                </Link>
              </div>
            </div>
          </section>

          {view !== "blog" ? <SummaryRail summary={dataset.summary} /> : null}

          {view === "analytics" ? (
            <section className={`border-b border-[#edf1f6] bg-white py-3 ${ADMIN_X_PADDING}`}>
              <MarketingRangeSelector drilldown={marketingDrilldown} rangeDays={rangeDays} />
            </section>
          ) : view === "search" || view === "blog" ? null : (
            <section className={`border-b border-[#edf1f6] bg-white py-3 ${ADMIN_X_PADDING}`}>
              <form
                className={`grid w-full gap-2.5 ${
                  view === "charges"
                    ? "sm:grid-cols-[minmax(0,1fr)_minmax(150px,210px)] xl:grid-cols-[minmax(0,1fr)_190px_210px_auto_auto]"
                    : "sm:grid-cols-[minmax(0,1fr)_minmax(150px,220px)] xl:grid-cols-[minmax(0,1fr)_220px_auto_auto]"
                }`}
              >
                <input type="hidden" name="view" value={view} />
                <input
                  type="text"
                  name="q"
                  defaultValue={query}
                  placeholder="이메일, 회사명, 도메인, 주문번호 검색"
                  className="h-10 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3 text-[13px] text-[#1a2943] outline-none transition-colors placeholder:text-[#97a7c2] focus:border-[#bcd1ff]"
                />
                <select
                  name="domain"
                  defaultValue={selectedDomain}
                  className="h-10 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3 text-[13px] text-[#1a2943] outline-none transition-colors focus:border-[#bcd1ff]"
                >
                  <option value="">전체 도메인</option>
                  {dataset.domainOptions.map((domain) => (
                    <option key={domain} value={domain}>
                      {domain}
                    </option>
                  ))}
                </select>
                {view === "charges" ? (
                  <select
                    name="chargeFilter"
                    defaultValue={dataset.chargeFilter}
                    className="h-10 w-full rounded-[10px] border border-[#dbe5f7] bg-white px-3 text-[13px] text-[#1a2943] outline-none transition-colors focus:border-[#bcd1ff] sm:col-span-2 xl:col-span-1"
                  >
                    <option value="all">전체 결제</option>
                    <option value="withdrawal">청약철회 요청 포함</option>
                    <option value="withdrawal_pending_review">청약철회 검토 대기</option>
                    <option value="withdrawal_approved">청약철회 승인 후 처리대기</option>
                    <option value="refunded">환불 진행/완료</option>
                  </select>
                ) : (
                  <input type="hidden" name="chargeFilter" value={dataset.chargeFilter} />
                )}
                <button type="submit" className="om-btn-primary h-10 rounded-[10px] px-4 text-[13px] shadow-none">
                  조회
                </button>
                <Link
                  href={buildAdminHref({ view })}
                  className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] text-[#344767] shadow-none"
                >
                  초기화
                </Link>
              </form>
            </section>
          )}

          <section className="bg-white">
            {view === "analytics" && analytics ? (
              <MarketingAnalyticsDashboard analytics={analytics} />
            ) : view === "search" && googleSearchConsoleAnalytics ? (
              <KavenixGoogleSearchConsoleDashboard
                analytics={googleSearchConsoleAnalytics}
                status={googleSearchConsoleStatus}
              />
            ) : view === "blog" ? (
              <KavenixBlogEditor posts={marketingBlogPosts ?? []} />
            ) : view === "users" ? (
              <UsersTable rows={dataset.users} query={query} />
            ) : view === "domains" ? (
              <DomainsTable rows={dataset.domains} query={query} />
            ) : view === "mailboxes" ? (
              <MailboxesTable rows={dataset.mailboxes} query={query} selectedDomain={selectedDomain} />
            ) : (
              <ChargesTable rows={dataset.charges} query={query} />
            )}
          </section>
        </main>
      </div>
    </div>
  );
}
