"use client";

import { useRouter } from "next/navigation";
import {
  useTransition,
  type FormEvent as ReactFormEvent,
} from "react";
import {
  buildMailBillingSetupHref,
  MAIL_BILLING_HISTORY_QUICK_RANGES,
  resolveMailBillingHistoryState,
  type MailBillingHistoryState,
} from "@/lib/mail-billing-history";
import type {
  MailBillingHistoryEntry,
  MailBillingHistoryPage,
} from "@/lib/toss-pay";

type MailBillingHistoryPanelProps = {
  historyPage: MailBillingHistoryPage | null;
  historyState: MailBillingHistoryState;
};

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

function formatDateTimeLabel(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 paymentMethodLabel(entry: MailBillingHistoryEntry) {
  if (entry.payMethod === "CARD") {
    return [entry.cardCompanyName, entry.cardNum4Print ? `•••• ${entry.cardNum4Print}` : "카드"]
      .filter(Boolean)
      .join(" ");
  }

  if (entry.payMethod === "TOSS_MONEY") {
    return [entry.accountBankName, entry.accountNumberMasked || "토스머니"]
      .filter(Boolean)
      .join(" ");
  }

  return entry.payMethod?.trim() || "기록 없음";
}

function chargeKindLabel(value: MailBillingHistoryEntry["chargeKind"]) {
  return value === "cycle" ? "정기 결제" : "즉시 결제";
}

function chargeStatusMeta(status: MailBillingHistoryEntry["status"]) {
  switch (status) {
    case "success":
      return {
        className: "border-[#cfe6d6] bg-[#f3fbf5] text-[#1f7a3a]",
        label: "성공",
      };
    case "failed":
      return {
        className: "border-[#f1c7cb] bg-[#fff5f6] text-[#c03a4d]",
        label: "실패",
      };
    case "requested":
      return {
        className: "border-[#d8e3f5] bg-[#f6f9ff] text-[#4d6998]",
        label: "요청됨",
      };
    case "skipped":
      return {
        className: "border-[#e3e8f1] bg-[#f8fafd] text-[#70809c]",
        label: "건너뜀",
      };
  }
}

function refundStatusMeta(refundState: MailBillingHistoryEntry["refundState"]) {
  switch (refundState) {
    case "processing":
      return {
        className: "border-[#d8e3f5] bg-[#f6f9ff] text-[#4d6998]",
        label: "환불 진행",
      };
    case "partial":
      return {
        className: "border-[#fde2bf] bg-[#fff8f0] text-[#bb6a00]",
        label: "부분 환불",
      };
    case "refunded":
      return {
        className: "border-[#fde2bf] bg-[#fff8f0] text-[#bb6a00]",
        label: "전액 환불",
      };
    default:
      return null;
  }
}

function createPaginationItems(currentPage: number, totalPages: number) {
  if (totalPages <= 1) {
    return [1];
  }

  const windowSize = 5;
  let start = Math.max(1, currentPage - 2);
  const end = Math.min(totalPages, start + windowSize - 1);

  if (end - start + 1 < windowSize) {
    start = Math.max(1, end - windowSize + 1);
  }

  const items: number[] = [];

  for (let page = start; page <= end; page += 1) {
    items.push(page);
  }

  return items;
}

export function MailBillingHistoryPanel({
  historyPage,
  historyState,
}: MailBillingHistoryPanelProps) {
  const router = useRouter();
  const [pending, startTransition] = useTransition();
  const customFilterFormKey = `${historyState.from ?? ""}:${historyState.to ?? ""}`;

  function navigateHistory(next: {
    from?: string | null;
    page?: number;
    rangePreset?: MailBillingHistoryState["rangePreset"];
    to?: string | null;
  }) {
    const href = buildMailBillingSetupHref({
      tab: "history",
      from: next.from ?? historyState.from,
      page: next.page ?? historyState.page,
      rangePreset: next.rangePreset ?? historyState.rangePreset,
      to: next.to ?? historyState.to,
    });

    startTransition(() => {
      router.push(href, { scroll: false });
    });
  }

  function handleCustomFilterSubmit(event: ReactFormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    const fromValue = String(formData.get("from") ?? "").trim() || null;
    const toValue = String(formData.get("to") ?? "").trim() || null;

    const resolved = resolveMailBillingHistoryState({
      from: fromValue,
      page: 1,
      rangePreset: fromValue || toValue ? "custom" : "all",
      to: toValue,
    });

    navigateHistory(resolved);
  }

  const paginationItems = historyPage
    ? createPaginationItems(historyPage.page, historyPage.totalPages)
    : [1];
  const rangeSummary = historyPage
    ? historyPage.from && historyPage.to
      ? `${historyPage.from} ~ ${historyPage.to}`
      : historyPage.from
        ? `${historyPage.from} 이후`
        : historyPage.to
          ? `${historyPage.to} 이전`
          : "전체 기간"
    : "데이터를 불러오는 중";
  const rangeButtonClass = (active: boolean) =>
    `inline-flex h-9 items-center rounded-full border px-3 text-[13px] font-semibold transition-colors ${
      active
        ? "border-[#bfd4ff] bg-[#eef4ff] text-[#2f6df6]"
        : "border-[#e2e8f3] bg-white text-[#6d7d97] hover:border-[#d4ddeb] hover:text-[#2d3d5c]"
    }`;
  const paginationButtonClass = (active: boolean, disabled = false) =>
    `inline-flex h-9 min-w-9 items-center justify-center rounded-[11px] border px-3 text-[13px] font-semibold transition-colors ${
      disabled
        ? "cursor-not-allowed border-[#edf1f6] text-[#b7c1d2]"
        : active
          ? "border-[#bfd4ff] bg-[#eef4ff] text-[#2f6df6]"
          : "border-[#e2e8f3] bg-white text-[#607089] hover:border-[#d4ddeb] hover:text-[#2d3d5c]"
    }`;

  return (
    <div className="om-setup-panel relative px-3 py-4 sm:px-4 lg:px-5">
      {pending ? (
        <div className="absolute inset-0 z-10 flex items-center justify-center bg-[rgba(255,255,255,0.72)] backdrop-blur-[2px]">
          <div className="flex items-center gap-3 rounded-full border border-[#e4ebf6] bg-white px-4 py-2 text-[13px] font-semibold text-[#2f6df6] shadow-[0_12px_28px_rgba(15,23,42,0.08)]">
            <span className="h-4 w-4 animate-spin rounded-full border-2 border-[#cfe0ff] border-t-[#2f6df6]" />
            결제내역 불러오는 중
          </div>
        </div>
      ) : null}

      <div className="flex flex-col gap-5">
        <div className="flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
          <div>
            <p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-[#8aa0c6]">
              Payment History
            </p>
            <h2 className="mt-2 text-[28px] font-semibold tracking-[-0.05em] text-[#10203d]">
              실제 결제내역
            </h2>
            <p className="mt-2 text-[14px] leading-7 text-[#617492]">
              실제 청구 로그를 기준으로 최근 내역을 빠르게 조회합니다. 기본 10건씩
              페이지네이션되며 기간 필터를 바로 적용할 수 있습니다.
            </p>
          </div>
          <div className="rounded-[18px] border border-[#edf2fb] bg-[#fbfcff] px-4 py-3 text-[13px] text-[#6c7c95]">
            <p className="font-semibold text-[#20304a]">
              {historyPage ? `총 ${historyPage.totalCount.toLocaleString("ko-KR")}건` : "조회 준비 중"}
            </p>
            <p className="mt-1">{rangeSummary}</p>
          </div>
        </div>

        <div className="rounded-[22px] border border-[#edf2fb] bg-[#fbfcff] p-4">
          <div className="flex flex-col gap-4">
            <div className="flex flex-wrap gap-2">
              {MAIL_BILLING_HISTORY_QUICK_RANGES.map((range) => (
                <button
                  key={range.id}
                  type="button"
                  disabled={pending}
                  onClick={() =>
                    navigateHistory({
                      page: 1,
                      rangePreset: range.id,
                    })
                  }
                  className={rangeButtonClass(historyState.rangePreset === range.id)}
                >
                  {range.label}
                </button>
              ))}
            </div>

            <form
              key={customFilterFormKey}
              onSubmit={handleCustomFilterSubmit}
              className="grid gap-3 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]"
            >
              <label className="grid gap-1.5">
                <span className="text-[12px] font-semibold text-[#74849f]">시작일</span>
                <input
                  name="from"
                  type="date"
                  defaultValue={historyState.from ?? ""}
                  disabled={pending}
                  className="h-11 rounded-[14px] border border-[#e2e8f3] bg-white px-3 text-[14px] text-[#22314e] outline-none transition-colors focus:border-[#bfd4ff]"
                />
              </label>
              <label className="grid gap-1.5">
                <span className="text-[12px] font-semibold text-[#74849f]">종료일</span>
                <input
                  name="to"
                  type="date"
                  defaultValue={historyState.to ?? ""}
                  disabled={pending}
                  className="h-11 rounded-[14px] border border-[#e2e8f3] bg-white px-3 text-[14px] text-[#22314e] outline-none transition-colors focus:border-[#bfd4ff]"
                />
              </label>
              <div className="flex items-end gap-2">
                <button
                  type="submit"
                  disabled={pending}
                  className="inline-flex h-11 items-center justify-center rounded-[14px] bg-[#2f6df6] px-4 text-[14px] font-semibold text-white transition-colors hover:bg-[#245de3] disabled:cursor-not-allowed disabled:bg-[#b6c8f5]"
                >
                  기간 적용
                </button>
              </div>
            </form>
          </div>
        </div>

        {historyPage === null ? (
          <div className="rounded-[22px] border border-[#edf2fb] bg-[#fbfcff] px-6 py-10 text-center">
            <p className="text-[16px] font-semibold text-[#20304a]">
              결제내역을 불러오지 못했습니다.
            </p>
            <p className="mt-2 text-[13px] leading-6 text-[#74849f]">
              잠시 후 다시 시도해 주세요.
            </p>
          </div>
        ) : historyPage.entries.length === 0 ? (
          <div className="rounded-[22px] border border-[#edf2fb] bg-[#fbfcff] px-6 py-10 text-center">
            <p className="text-[16px] font-semibold text-[#20304a]">
              선택한 기간에는 결제내역이 없습니다.
            </p>
            <p className="mt-2 text-[13px] leading-6 text-[#74849f]">
              빠른 기간 버튼을 누르거나 날짜 범위를 다시 지정해 보세요.
            </p>
          </div>
        ) : (
          <>
            <div className="space-y-3 lg:hidden">
              {historyPage.entries.map((entry) => {
                const chargeStatus = chargeStatusMeta(entry.status);
                const refundStatus = refundStatusMeta(entry.refundState);

                return (
                  <article
                    key={entry.id}
                    className="rounded-[20px] border border-[#edf2fb] bg-[#fbfcff] p-4"
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0">
                        <p className="text-[15px] font-semibold text-[#20304a]">
                          {formatDateTimeLabel(entry.approvedAt ?? entry.requestedAt)}
                        </p>
                        <p className="mt-1 truncate text-[12px] text-[#7a8aa5]">
                          {entry.orderNo}
                        </p>
                      </div>
                      <p className="shrink-0 text-[16px] font-semibold tracking-[-0.04em] text-[#10203d]">
                        {formatCurrency(entry.amount)}
                      </p>
                    </div>

                    <div className="mt-3 flex flex-wrap gap-2">
                      <span
                        className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[12px] font-semibold ${chargeStatus.className}`}
                      >
                        {chargeStatus.label}
                      </span>
                      <span className="inline-flex items-center rounded-full border border-[#dfe6f2] bg-white px-2.5 py-1 text-[12px] font-semibold text-[#5f708c]">
                        {chargeKindLabel(entry.chargeKind)}
                      </span>
                      {refundStatus ? (
                        <span
                          className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[12px] font-semibold ${refundStatus.className}`}
                        >
                          {refundStatus.label}
                        </span>
                      ) : null}
                    </div>

                    <div className="mt-4 grid gap-3 text-[13px] text-[#62748f]">
                      <div>
                        <p className="font-semibold text-[#20304a]">결제수단</p>
                        <p className="mt-1">{paymentMethodLabel(entry)}</p>
                      </div>
                      <div>
                        <p className="font-semibold text-[#20304a]">상품</p>
                        <p className="mt-1">{entry.productDesc}</p>
                      </div>
                      {entry.refundState !== "none" ? (
                        <p className="font-medium text-[#bb6a00]">
                          환불 누적 {formatCurrency(entry.refundedAmount)}
                        </p>
                      ) : null}
                      {entry.errorMessage ? (
                        <p className="font-medium text-[#c03a4d]">{entry.errorMessage}</p>
                      ) : null}
                    </div>
                  </article>
                );
              })}
            </div>

            <div className="hidden overflow-hidden rounded-[22px] border border-[#edf2fb] lg:block">
              <table className="min-w-full border-collapse bg-white">
                <thead>
                  <tr className="bg-[#fbfcff] text-left text-[12px] font-semibold uppercase tracking-[0.08em] text-[#7d8ca8]">
                    <th className="px-5 py-4">결제일</th>
                    <th className="px-5 py-4">구분</th>
                    <th className="px-5 py-4">상태</th>
                    <th className="px-5 py-4">결제수단</th>
                    <th className="px-5 py-4 text-right">금액</th>
                  </tr>
                </thead>
                <tbody>
                  {historyPage.entries.map((entry) => {
                    const chargeStatus = chargeStatusMeta(entry.status);
                    const refundStatus = refundStatusMeta(entry.refundState);

                    return (
                      <tr
                        key={entry.id}
                        className="align-top border-t border-[#edf2fb] text-[14px] text-[#20304a]"
                      >
                        <td className="px-5 py-4">
                          <p className="font-semibold">
                            {formatDateTimeLabel(entry.approvedAt ?? entry.requestedAt)}
                          </p>
                          <p className="mt-1 text-[12px] text-[#7a8aa5]">{entry.orderNo}</p>
                        </td>
                        <td className="px-5 py-4">
                          <p className="font-semibold">{chargeKindLabel(entry.chargeKind)}</p>
                          <p className="mt-1 text-[12px] leading-5 text-[#70819d]">
                            {entry.productDesc}
                          </p>
                        </td>
                        <td className="px-5 py-4">
                          <div className="flex flex-wrap gap-2">
                            <span
                              className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[12px] font-semibold ${chargeStatus.className}`}
                            >
                              {chargeStatus.label}
                            </span>
                            {refundStatus ? (
                              <span
                                className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[12px] font-semibold ${refundStatus.className}`}
                              >
                                {refundStatus.label}
                              </span>
                            ) : null}
                          </div>
                          {entry.errorMessage ? (
                            <p className="mt-2 text-[12px] leading-5 text-[#c03a4d]">
                              {entry.errorMessage}
                            </p>
                          ) : entry.refundState !== "none" ? (
                            <p className="mt-2 text-[12px] leading-5 text-[#bb6a00]">
                              환불 누적 {formatCurrency(entry.refundedAmount)}
                            </p>
                          ) : null}
                        </td>
                        <td className="px-5 py-4">
                          <p className="font-semibold">{paymentMethodLabel(entry)}</p>
                          {entry.transactionId ? (
                            <p className="mt-1 text-[12px] text-[#7a8aa5]">
                              거래번호 {entry.transactionId}
                            </p>
                          ) : null}
                        </td>
                        <td className="px-5 py-4 text-right">
                          <p className="font-semibold tracking-[-0.03em] text-[#10203d]">
                            {formatCurrency(entry.amount)}
                          </p>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>

            <div className="flex flex-col gap-3 border-t border-[#edf2fb] pt-4 sm:flex-row sm:items-center sm:justify-between">
              <p className="text-[13px] text-[#70819d]">
                {historyPage.totalCount.toLocaleString("ko-KR")}건 중{" "}
                {Math.min((historyPage.page - 1) * historyPage.pageSize + 1, historyPage.totalCount)}
                -
                {Math.min(historyPage.page * historyPage.pageSize, historyPage.totalCount)}번째
                내역
              </p>
              <div className="flex flex-wrap items-center gap-1.5">
                <button
                  type="button"
                  disabled={pending || historyPage.page <= 1}
                  onClick={() => navigateHistory({ page: historyPage.page - 1 })}
                  className={paginationButtonClass(false, historyPage.page <= 1 || pending)}
                >
                  이전
                </button>
                {paginationItems.map((pageNumber) => (
                  <button
                    key={pageNumber}
                    type="button"
                    disabled={pending}
                    onClick={() => navigateHistory({ page: pageNumber })}
                    className={paginationButtonClass(pageNumber === historyPage.page, pending)}
                  >
                    {pageNumber}
                  </button>
                ))}
                <button
                  type="button"
                  disabled={pending || historyPage.page >= historyPage.totalPages}
                  onClick={() => navigateHistory({ page: historyPage.page + 1 })}
                  className={paginationButtonClass(
                    false,
                    historyPage.page >= historyPage.totalPages || pending,
                  )}
                >
                  다음
                </button>
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
