"use client";

import Link from "next/link";
import { useEffect, useState } from "react";

import { CloseIconButton } from "@/components/close-icon-button";
import type {
  KavenixStatisticsDetail,
  KavenixStatisticsMetricKey,
} from "@/lib/kavenix-statistics-types";

type DetailResponse = {
  detail?: KavenixStatisticsDetail;
  message?: string;
  ok?: boolean;
};

function formatDate(value: string) {
  const [year, month, day] = value.split("-").map(Number);
  return new Intl.DateTimeFormat("ko-KR", {
    dateStyle: "long",
  }).format(new Date(Date.UTC(year, month - 1, day)));
}

function formatDateTime(value: string) {
  return new Intl.DateTimeFormat("ko-KR", {
    hour: "2-digit",
    hour12: true,
    minute: "2-digit",
    timeZone: "Asia/Seoul",
  }).format(new Date(value));
}

export function KavenixStatisticsDetailDialog({
  date,
  label,
  metricKey,
  onClose,
  value,
}: {
  date: string;
  label: string;
  metricKey: KavenixStatisticsMetricKey;
  onClose: () => void;
  value: string;
}) {
  const [detail, setDetail] = useState<KavenixStatisticsDetail | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);

  useEffect(() => {
    const controller = new AbortController();
    const params = new URLSearchParams({ date, metric: metricKey });

    fetch(`/api/kavenix/statistics/details?${params.toString()}`, {
      cache: "no-store",
      credentials: "same-origin",
      signal: controller.signal,
    })
      .then(async (response) => {
        const payload = (await response.json().catch(() => null)) as DetailResponse | null;

        if (!response.ok || !payload?.ok || !payload.detail) {
          throw new Error(payload?.message || "상세 통계를 불러오지 못했습니다.");
        }

        setDetail(payload.detail);
      })
      .catch((error) => {
        if (!controller.signal.aborted) {
          setErrorMessage(error instanceof Error ? error.message : "상세 통계를 불러오지 못했습니다.");
        }
      });

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

  useEffect(() => {
    const previousOverflow = document.body.style.overflow;

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

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

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

  return (
    <div
      className="fixed inset-0 z-[190] flex items-center justify-center bg-[rgba(12,18,31,0.44)] px-3 py-6 sm:px-5 sm:py-8"
      onClick={onClose}
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby="statistics-detail-title"
        className="flex max-h-[calc(100dvh-3rem)] w-full max-w-[720px] flex-col overflow-hidden rounded-[20px] border border-[#dfe8f7] bg-white shadow-[0_28px_80px_rgba(15,23,42,0.22)] sm:max-h-[calc(100dvh-4rem)] sm:rounded-[24px]"
        onClick={(event) => event.stopPropagation()}
      >
        <div className="flex items-start justify-between gap-4 border-b border-[#edf2f8] px-5 py-5 sm:px-6">
          <div className="min-w-0">
            <p className="text-[12px] font-semibold text-[#2f6df6]">{formatDate(date)}</p>
            <div className="mt-1.5 flex flex-wrap items-end gap-x-3 gap-y-1">
              <h2 id="statistics-detail-title" className="text-[21px] font-semibold tracking-[-0.04em] text-[#16233c] sm:text-[24px]">
                {label} 상세
              </h2>
              <span className="pb-0.5 text-[14px] font-semibold text-[#61728e]">{value}</span>
            </div>
            <p className="mt-2 text-[12px] leading-5 text-[#7a8aa2]">해당 날짜의 실제 집계 항목을 최신순으로 표시합니다.</p>
          </div>
          <CloseIconButton ariaLabel="통계 상세 닫기" onClick={onClose} />
        </div>

        <div className="min-h-[220px] overflow-y-auto px-5 py-2 sm:px-6">
          {!detail && !errorMessage ? (
            <div className="flex min-h-[220px] items-center justify-center gap-2 text-[13px] text-[#74849c]">
              <span className="h-4 w-4 animate-spin rounded-full border-2 border-[#d7e3f7] border-t-[#2f6df6]" />
              상세 데이터를 불러오는 중입니다.
            </div>
          ) : null}

          {errorMessage ? (
            <div className="flex min-h-[220px] items-center justify-center text-center text-[13px] leading-6 text-[#b34e62]">
              {errorMessage}
            </div>
          ) : null}

          {detail?.items.length === 0 ? (
            <div className="flex min-h-[220px] items-center justify-center text-[13px] text-[#7b8ba3]">
              표시할 상세 항목이 없습니다.
            </div>
          ) : null}

          {detail?.items.map((item) => (
            <article key={item.id} className="border-b border-[#edf2f8] py-4 last:border-b-0">
              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <p className="break-words text-[14px] font-semibold leading-6 text-[#223351]">{item.title}</p>
                  {item.subtitle ? (
                    <p className="mt-0.5 break-all text-[12px] leading-5 text-[#71819a]">{item.subtitle}</p>
                  ) : null}
                </div>
                <time className="shrink-0 pt-0.5 text-[11px] font-medium text-[#8a98ab]">
                  {formatDateTime(item.occurredAt)}
                </time>
              </div>
              <div className="mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-[#60718d]">
                {item.details.map((detailItem, index) => (
                  <span key={`${item.id}-${detailItem}-${index}`} className="inline-flex items-center gap-2">
                    {index > 0 ? <span className="h-0.5 w-0.5 rounded-full bg-[#aab5c5]" /> : null}
                    <span className="break-all">{detailItem}</span>
                  </span>
                ))}
                {item.href ? (
                  <Link href={item.href} className="ml-auto shrink-0 font-semibold text-[#2f6df6] hover:text-[#245ed6]">
                    관리 화면 열기
                  </Link>
                ) : null}
              </div>
            </article>
          ))}
        </div>

        {detail?.truncated ? (
          <p className="border-t border-[#edf2f8] px-5 py-3 text-[11px] text-[#7b8ba3] sm:px-6">
            항목이 많아 최신 200개까지만 표시합니다.
          </p>
        ) : null}
      </div>
    </div>
  );
}
