"use client";

import { useEffect, useEffectEvent, useState } from "react";
import type {
  MailboxFolderBackupManifest,
  MailboxStorageFolder,
  MailboxStorageOverview
} from "@/lib/official-mail";

const FOLDER_LABELS: Record<string, string> = {
  drafts: "임시보관함",
  inbox: "받은메일함",
  sent: "보낸메일함",
  spam: "스팸메일함",
  trash: "휴지통"
};

function formatBytes(bytes: number | null) {
  if (bytes === null) return "집계 중";
  if (bytes < 1024) return `${bytes} B`;
  const units = ["KB", "MB", "GB", "TB"];
  let value = bytes / 1024;
  let unitIndex = 0;
  while (value >= 1024 && unitIndex < units.length - 1) {
    value /= 1024;
    unitIndex += 1;
  }
  return `${value >= 10 ? value.toFixed(1) : value.toFixed(2)} ${units[unitIndex]}`;
}

function folderLabel(folder: MailboxStorageFolder) {
  return FOLDER_LABELS[folder.systemName] ?? folder.name;
}

function folderGroupLabel(folder: MailboxStorageFolder) {
  return folder.kind === "custom" ? "내 메일함" : "기본메일함";
}

function DownloadIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4">
      <path d="M12 3v12" />
      <path d="m7.5 10.5 4.5 4.5 4.5-4.5" />
      <path d="M5 20h14" />
    </svg>
  );
}

export function MailStorageSettingsPanel() {
  const [storage, setStorage] = useState<MailboxStorageOverview | null>(null);
  const [loading, setLoading] = useState(true);
  const [actionPending, setActionPending] = useState<string | null>(null);
  const [clearTarget, setClearTarget] = useState<MailboxStorageFolder | null>(null);
  const [backupTarget, setBackupTarget] = useState<MailboxStorageFolder | null>(null);
  const [backupManifest, setBackupManifest] = useState<MailboxFolderBackupManifest | null>(null);
  const [backupLoading, setBackupLoading] = useState(false);
  const [notice, setNotice] = useState<{ message: string; tone: "error" | "success" } | null>(null);

  const loadStorage = async () => {
    setLoading(true);
    try {
      const response = await fetch("/api/mailbox/storage", { cache: "no-store" });
      const payload = (await response.json().catch(() => null)) as {
        message?: string;
        ok?: boolean;
        storage?: MailboxStorageOverview;
      } | null;
      if (!response.ok || !payload?.ok || !payload.storage) {
        throw new Error(payload?.message ?? "메일함 용량을 불러오지 못했습니다.");
      }
      setStorage(payload.storage);
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "메일함 용량을 불러오지 못했습니다.", tone: "error" });
    } finally {
      setLoading(false);
    }
  };

  const loadStorageEffect = useEffectEvent(loadStorage);

  useEffect(() => {
    const timer = window.setTimeout(() => void loadStorageEffect(), 0);
    return () => window.clearTimeout(timer);
  }, []);

  const runFolderAction = async (folder: MailboxStorageFolder, action: "clear" | "mark-read") => {
    const pendingKey = `${action}:${folder.id}`;
    if (actionPending) return;
    setActionPending(pendingKey);
    setNotice(null);
    try {
      const response = await fetch("/api/mailbox/folder-actions", {
        body: JSON.stringify({ action, folder: folder.systemName, label: folderLabel(folder) }),
        headers: { "Content-Type": "application/json" },
        method: "POST"
      });
      const payload = (await response.json().catch(() => null)) as { notice?: { message?: string }; ok?: boolean } | null;
      if (!response.ok || !payload?.ok) throw new Error(payload?.notice?.message ?? "메일함 작업을 완료하지 못했습니다.");
      setClearTarget(null);
      setNotice({ message: payload.notice?.message ?? "메일함 작업을 완료했습니다.", tone: "success" });
      await loadStorage();
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "메일함 작업을 완료하지 못했습니다.", tone: "error" });
    } finally {
      setActionPending(null);
    }
  };

  const openBackup = async (folder: MailboxStorageFolder) => {
    setBackupTarget(folder);
    setBackupManifest(null);
    setBackupLoading(true);
    setNotice(null);
    try {
      const response = await fetch(`/api/mailbox/storage/backup?folder=${encodeURIComponent(folder.systemName)}`, { cache: "no-store" });
      const payload = (await response.json().catch(() => null)) as {
        manifest?: MailboxFolderBackupManifest;
        message?: string;
        ok?: boolean;
      } | null;
      if (!response.ok || !payload?.ok || !payload.manifest) {
        throw new Error(payload?.message ?? "메일함 백업을 준비하지 못했습니다.");
      }
      setBackupManifest(payload.manifest);
    } catch (error) {
      setBackupTarget(null);
      setNotice({ message: error instanceof Error ? error.message : "메일함 백업을 준비하지 못했습니다.", tone: "error" });
    } finally {
      setBackupLoading(false);
    }
  };

  const usagePercent = Math.max(0, Math.min(100, storage?.usagePercent ?? 0));

  return (
    <div className="om-setup-content">
      <div className="om-setup-header">
        <div className="om-setup-header-copy">
          <h1 className="om-page-title text-[#16233c]">메일함 용량 관리</h1>
          <p className="om-setup-header-description">메일함별 용량과 메일 수를 확인하고 백업하거나 정리합니다.</p>
        </div>
      </div>

      {notice ? <div className={`rounded-[12px] px-4 py-3 text-[13px] ${notice.tone === "success" ? "bg-[#eef9f3] text-[#23724b]" : "bg-[#fff4f6] text-[#ad4257]"}`}>{notice.message}</div> : null}

      <section className="om-setup-panel bg-white p-4 sm:p-5">
        <div className="flex flex-col gap-5 sm:flex-row sm:items-end sm:justify-between">
          <div>
            <p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-[#8aa0c6]">전체 사용량</p>
            <p className="mt-2 text-[28px] font-semibold tracking-[-0.04em] text-[#172640]">{formatBytes(storage?.usedBytes ?? null)}</p>
            <p className="mt-1 text-[13px] text-[#71819b]">{storage?.isUnlimited ? "용량 제한 없음" : `${formatBytes(storage?.limitBytes ?? null)} 중 사용`}</p>
          </div>
          <div className="text-left sm:text-right">
            <p className="text-[12px] text-[#8290a7]">메일 서버 기준</p>
            <p className="mt-1 text-[15px] font-semibold text-[#2f6df6]">{storage?.isUnlimited ? "무제한" : storage?.usagePercent === null || storage?.usagePercent === undefined ? "집계 중" : `${usagePercent}%`}</p>
          </div>
        </div>
        <div className="mt-5 h-3 overflow-hidden rounded-full bg-[#edf2f8]"><div className="h-full rounded-full bg-[linear-gradient(90deg,#2f6df6,#70a0ff)] transition-[width] duration-500" style={{ width: `${storage?.isUnlimited ? 0 : Math.max(usagePercent, usagePercent > 0 ? 1 : 0)}%` }} /></div>
      </section>

      <section className="om-setup-panel overflow-hidden bg-white">
        <div className="border-b border-[#edf2fb] px-4 py-4">
          <h2 className="text-[15px] font-semibold text-[#20304d]">메일함 관리</h2>
          <p className="mt-1 text-[12px] text-[#7b8ba3]">백업 파일은 원본 메일(.eml)을 담은 ZIP 형식으로 생성됩니다.</p>
        </div>
        {loading && !storage ? <div className="px-4 py-20 text-center text-[13px] text-[#8290a7]">메일함 용량을 집계하고 있습니다.</div> : (
          <>
            <div className="hidden grid-cols-[100px_minmax(160px,1fr)_150px_110px_220px] border-b border-[#e8eef8] bg-[#f8faff] px-4 py-2.5 text-[12px] font-semibold text-[#61728e] md:grid">
              <span>구분</span><span>메일함</span><span>안 읽음 / 전체 메일</span><span className="text-right">용량</span><span className="text-right">관리</span>
            </div>
            <div className="divide-y divide-[#edf2fb]">
              {storage?.folders.map((folder) => {
                const backupPending = backupLoading && backupTarget?.id === folder.id;
                const clearPending = actionPending === `clear:${folder.id}`;
                const readPending = actionPending === `mark-read:${folder.id}`;
                return <div key={folder.id} className="grid gap-3 px-4 py-3 transition-colors hover:bg-[#f9fbff] md:grid-cols-[100px_minmax(160px,1fr)_150px_110px_220px] md:items-center md:gap-0">
                  <span className="text-[11px] font-medium text-[#8794a8] md:text-[12px]">{folderGroupLabel(folder)}</span>
                  <span className="text-[14px] font-semibold text-[#263754]">{folderLabel(folder)}</span>
                  <span className="text-[12px] text-[#667792]"><strong className="font-semibold text-[#2f6df6]">{folder.unreadCount.toLocaleString("ko-KR")}</strong> / {folder.messageCount.toLocaleString("ko-KR")}</span>
                  <span className="text-[12px] text-[#667792] md:text-right">{formatBytes(folder.estimatedBytes)}</span>
                  <div className="flex flex-wrap items-center gap-x-3 gap-y-2 md:justify-end">
                    <button type="button" disabled={folder.messageCount === 0 || backupLoading} onClick={() => void openBackup(folder)} className="cursor-pointer text-[12px] font-medium text-[#2f6df6] disabled:cursor-default disabled:text-[#b3bdcc]">{backupPending ? "준비 중" : "백업"}</button>
                    <button type="button" disabled={folder.messageCount === 0 || Boolean(actionPending)} onClick={() => setClearTarget(folder)} className="cursor-pointer text-[12px] font-medium text-[#536987] disabled:cursor-default disabled:text-[#b3bdcc]">{clearPending ? "처리 중" : "비우기"}</button>
                    <button type="button" disabled={folder.unreadCount === 0 || Boolean(actionPending)} onClick={() => void runFolderAction(folder, "mark-read")} className="cursor-pointer text-[12px] font-medium text-[#536987] disabled:cursor-default disabled:text-[#b3bdcc]">{readPending ? "처리 중" : "모두 읽음"}</button>
                  </div>
                </div>;
              })}
            </div>
          </>
        )}
      </section>
      <p className="px-4 py-2 text-[11px] leading-5 text-[#8794a8]">전체 사용량은 메일 서버의 실제 값이며, 폴더별 용량은 색인된 원본과 본문을 기준으로 한 추정치입니다. 파일서랍 용량은 메일함 용량에 포함되지 않습니다.</p>

      {clearTarget ? <div className="fixed inset-0 z-[190] flex items-center justify-center bg-[rgba(12,18,31,0.42)] px-4 backdrop-blur-[3px]" onClick={() => !actionPending && setClearTarget(null)}><div className="w-full max-w-[440px] rounded-[20px] bg-white p-6 text-center shadow-[0_30px_80px_rgba(15,28,58,0.22)]" onClick={(event) => event.stopPropagation()}><div className="mx-auto flex h-10 w-10 items-center justify-center rounded-full bg-[#fff0f2] text-[18px] font-bold text-[#d34e62]">!</div><h2 className="mt-4 text-[18px] font-semibold text-[#16233c]">{folderLabel(clearTarget)}을 비울까요?</h2><p className="mt-2 text-[13px] leading-6 text-[#71819b]">메일 {clearTarget.messageCount.toLocaleString("ko-KR")}개가 영구 삭제되며 복구할 수 없습니다. 필요한 메일은 먼저 백업해주세요.</p><div className="mt-6 flex justify-center gap-2"><button type="button" disabled={Boolean(actionPending)} onClick={() => setClearTarget(null)} className="om-btn-secondary h-10 cursor-pointer rounded-[11px] px-4 text-[13px]">취소</button><button type="button" disabled={Boolean(actionPending)} onClick={() => void runFolderAction(clearTarget, "clear")} className="h-10 cursor-pointer rounded-[11px] bg-[#e55264] px-5 text-[13px] font-semibold text-white disabled:opacity-60">{actionPending ? "처리 중..." : "영구 삭제"}</button></div></div></div> : null}

      {backupTarget ? <div className="fixed inset-0 z-[195] flex items-center justify-center bg-[rgba(12,18,31,0.42)] px-4 py-6 backdrop-blur-[3px]" onClick={() => !backupLoading && setBackupTarget(null)}><div className="max-h-full w-full max-w-[560px] overflow-y-auto rounded-[20px] bg-white shadow-[0_30px_80px_rgba(15,28,58,0.22)]" onClick={(event) => event.stopPropagation()}><div className="border-b border-[#edf2fb] px-5 py-4"><h2 className="text-[18px] font-semibold text-[#16233c]">메일함 백업 선택</h2><p className="mt-1 text-[12px] text-[#74839b]">{folderLabel(backupTarget)} 메일을 원본 형식으로 내려받습니다.</p></div><div className="px-5 py-4"><ul className="space-y-1 text-[12px] leading-5 text-[#6f7f97]"><li>· 메일함 크기가 2GB 이상이면 2GB 단위로 파일이 생성됩니다.</li><li>· 각 ZIP 파일에는 다른 메일 서비스에서도 열 수 있는 원본 .eml 파일이 들어갑니다.</li><li>· 백업 중 이동하거나 삭제한 메일은 포함되지 않을 수 있습니다.</li><li className="font-semibold text-[#2f6df6]">· 영구 삭제한 메일은 복구할 수 없으니 백업 파일을 먼저 확인해주세요.</li></ul>{backupLoading ? <div className="py-12 text-center text-[13px] text-[#8290a7]">백업 파일 목록을 준비하고 있습니다.</div> : backupManifest?.parts.length ? <div className="mt-4 overflow-hidden rounded-[12px] border border-[#e1e8f3]"><div className="flex items-center justify-between border-b border-[#edf2fb] bg-[#f8faff] px-3 py-2 text-[12px] text-[#667792]"><span>백업 파일(압축 전 용량)</span><span>전체 {formatBytes(backupManifest.totalBytes)}</span></div>{backupManifest.parts.map((part) => <div key={part.index} className="flex items-center gap-3 border-b border-[#edf2fb] px-3 py-3 last:border-b-0"><span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-[6px] bg-[#8b735e] text-[9px] font-bold text-white">ZIP</span><span className="min-w-0 flex-1"><span className="block truncate text-[13px] font-medium text-[#2d3c57]">{part.fileName}</span><span className="mt-0.5 block text-[11px] text-[#8794a8]">메일 {part.messageCount.toLocaleString("ko-KR")}개 · {formatBytes(part.sizeBytes)}</span></span><a href={`/api/mailbox/storage/backup?download=1&folder=${encodeURIComponent(backupManifest.folderSystemName)}&part=${part.index}`} className="inline-flex shrink-0 cursor-pointer items-center gap-1 text-[12px] font-medium text-[#536987] transition-colors hover:text-[#2f6df6]"><DownloadIcon />다운로드</a></div>)}</div> : <div className="py-12 text-center text-[13px] text-[#8290a7]">백업할 메일이 없습니다.</div>}</div><div className="flex justify-center border-t border-[#edf2fb] px-5 py-4"><button type="button" onClick={() => setBackupTarget(null)} className="om-btn-primary h-10 cursor-pointer rounded-[11px] px-6 text-[13px]">닫기</button></div></div></div> : null}
    </div>
  );
}
