"use client";

import { useEffect, useState } from "react";

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

type ActionDetailResponse = {
  detail?: KavenixStatisticsActionDetail;
  message?: string;
  ok?: boolean;
};

type RetryNotice = {
  itemId: string;
  message: string;
  tone: "error" | "success";
};

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

  return new Intl.DateTimeFormat("ko-KR", {
    dateStyle: "medium",
    timeStyle: "short",
    timeZone: "Asia/Seoul",
  }).format(new Date(value));
}

export function KavenixStatisticsActionDetailDialog({
  action,
  onClose,
  onResolved,
}: {
  action: KavenixStatisticsActionItem;
  onClose: () => void;
  onResolved: (actionId: KavenixStatisticsActionItem["id"]) => void;
}) {
  const [detail, setDetail] = useState<KavenixStatisticsActionDetail | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [retryNotice, setRetryNotice] = useState<RetryNotice | null>(null);
  const [retryingItemId, setRetryingItemId] = useState<string | null>(null);
  const canRetry = action.id === "sync-errors" || action.id === "content-sync-errors";

  async function retryMailbox(itemId: string) {
    if (retryingItemId) {
      return;
    }

    setRetryingItemId(itemId);
    setRetryNotice(null);

    try {
      const response = await fetch("/api/kavenix/statistics/action-details", {
        body: JSON.stringify({ actionId: action.id, mailboxId: itemId }),
        cache: "no-store",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        method: "POST",
      });
      const payload = (await response.json().catch(() => null)) as ActionDetailResponse | null;

      if (payload?.detail) {
        setDetail(payload.detail);
      }

      if (!response.ok || !payload?.ok) {
        throw new Error(payload?.message || "메일함 재동기화를 완료하지 못했습니다.");
      }

      setRetryNotice({ itemId, message: "재동기화를 완료했습니다.", tone: "success" });
      onResolved(action.id);
    } catch (error) {
      setRetryNotice({
        itemId,
        message: error instanceof Error ? error.message : "메일함 재동기화를 완료하지 못했습니다.",
        tone: "error",
      });
    } finally {
      setRetryingItemId(null);
    }
  }

  useEffect(() => {
    const controller = new AbortController();
    const params = new URLSearchParams({ action: action.id });

    fetch(`/api/kavenix/statistics/action-details?${params.toString()}`, {
      cache: "no-store",
      credentials: "same-origin",
      signal: controller.signal,
    })
      .then(async (response) => {
        const payload = (await response.json().catch(() => null)) as ActionDetailResponse | 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();
  }, [action.id]);

  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-action-detail-title"
        className="flex max-h-[calc(100dvh-3rem)] w-full max-w-[760px] 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]">운영 점검 상세</p>
            <div className="mt-1.5 flex flex-wrap items-end gap-x-3 gap-y-1">
              <h2
                id="statistics-action-detail-title"
                className="text-[21px] font-semibold tracking-[-0.04em] text-[#16233c] sm:text-[24px]"
              >
                {action.title}
              </h2>
              <span className="pb-0.5 text-[14px] font-semibold text-[#c14d61]">{action.count}건</span>
            </div>
            <p className="mt-2 text-[12px] leading-5 text-[#7a8aa2]">{action.description}</p>
          </div>
          <CloseIconButton ariaLabel="운영 항목 상세 닫기" onClick={onClose} />
        </div>

        <div className="min-h-[240px] overflow-y-auto px-5 py-2 sm:px-6">
          {!detail && !errorMessage ? (
            <div className="flex min-h-[240px] 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-[240px] items-center justify-center text-center text-[13px] leading-6 text-[#b34e62]">
              {errorMessage}
            </div>
          ) : null}

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

          {detail?.items.map((item) => {
            const occurredAt = formatDateTime(item.occurredAt);

            return (
              <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>
                  <div className="flex shrink-0 flex-col items-end gap-2">
                    {occurredAt ? (
                      <time className="pt-0.5 text-[11px] font-medium text-[#8a98ab]">
                        {occurredAt}
                      </time>
                    ) : null}
                    {canRetry ? (
                      <button
                        type="button"
                        disabled={retryingItemId !== null}
                        onClick={() => void retryMailbox(item.id)}
                        className="inline-flex h-8 cursor-pointer items-center justify-center gap-1.5 rounded-[9px] bg-[#2f6df6] px-3 text-[11px] font-semibold text-white transition-colors hover:bg-[#245de3] disabled:cursor-wait disabled:bg-[#9db9f7]"
                      >
                        {retryingItemId === item.id ? (
                          <span className="h-3 w-3 animate-spin rounded-full border-2 border-white/50 border-t-white" />
                        ) : null}
                        {retryingItemId === item.id ? "재동기화 중" : "재동기화"}
                      </button>
                    ) : null}
                  </div>
                </div>
                {item.details.length > 0 ? (
                  <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>
                    ))}
                  </div>
                ) : null}
                {retryNotice?.itemId === item.id ? (
                  <p
                    className={`mt-2 text-[11px] font-medium ${
                      retryNotice.tone === "success" ? "text-[#27845d]" : "text-[#b34e62]"
                    }`}
                  >
                    {retryNotice.message}
                  </p>
                ) : null}
              </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>
  );
}
