// frontend/components/inbox/InboxView.tsx — 인박스 클라이언트 루트
"use client";
import { useRef, useState } from "react";
import { Icon } from "@/components/Icon";
import { captureInbox, confirmInbox, reclassifyInbox } from "@/lib/inbox/api";
import { nextType } from "@/lib/inbox/presentation";
import type { InboxItem, RouteType, Sphere, UiInboxItem } from "@/lib/types";
import ClassifyPrinciples from "./ClassifyPrinciples";
import SmartInbox from "./SmartInbox";
import TodayRouted from "./TodayRouted";

function relTime(iso: string): string {
  if (!iso) return "방금";
  const diff = Date.now() - new Date(iso).getTime();
  if (Number.isNaN(diff)) return "방금";
  const m = Math.floor(diff / 60000);
  if (m < 1) return "방금";
  if (m < 60) return `${m}분 전`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}시간 전`;
  return `${Math.floor(h / 24)}일 전`;
}

function toUi(it: InboxItem): UiInboxItem {
  return { ...it, status: it.status, time: relTime(it.created_at) };
}

export default function InboxView({
  initialItems,
  initialLoadError,
}: {
  initialItems: InboxItem[];
  initialLoadError: boolean;
}) {
  const [items, setItems] = useState<UiInboxItem[]>(() => initialItems.map(toUi));
  const [filter, setFilter] = useState<"all" | Sphere>("all");
  const tmpSeq = useRef(0);

  const clearFresh = (xs: UiInboxItem[]) => xs.map((x) => (x.fresh ? { ...x, fresh: false } : x));

  /* ---- 캡처 제출 ---- */
  const submit = async (raw: string, kind: "text" | "voice" | "image") => {
    const text = raw.trim();
    if (!text) return;
    const tmpId = "tmp-" + ++tmpSeq.current;
    setItems((xs) => [
      {
        id: tmpId,
        kind,
        raw: text,
        status: "thinking",
        time: "방금",
        created_at: new Date(0).toISOString(),
        materialized_task_id: null,
        classification: null,
        fresh: true,
      } as UiInboxItem,
      ...clearFresh(xs),
    ]);
    try {
      const { item, classification } = await captureInbox({ kind, raw: text });
      setItems((xs) =>
        xs.map((x) =>
          x.id === tmpId
            ? {
                ...item,
                classification,
                status: "classified",
                time: "방금",
                fresh: true,
                fallbackUsed: classification.model === "heuristic",
              }
            : x,
        ),
      );
    } catch {
      setItems((xs) => xs.map((x) => (x.id === tmpId ? { ...x, status: "error" } : x)));
    }
  };

  /* ---- 다르게 분류 (타입 순환) ---- */
  const reType = async (id: string) => {
    const cur = items.find((x) => x.id === id);
    if (!cur?.classification) return;
    const original = cur.classification.type;
    const wanted = nextType(original);
    // 낙관적 미리보기
    setItems((xs) =>
      xs.map((x) =>
        x.id === id && x.classification
          ? { ...x, classification: { ...x.classification, type: wanted } }
          : x,
      ),
    );
    try {
      const { item, classification } = await reclassifyInbox(id, wanted as RouteType);
      setItems((xs) =>
        xs.map((x) =>
          x.id === id
            ? {
                ...item,
                classification,
                status: "classified",
                time: x.time,
                fresh: x.fresh,
                fallbackUsed: classification.model === "heuristic",
              }
            : x,
        ),
      );
    } catch {
      // 롤백: 원래 타입 복구
      setItems((xs) =>
        xs.map((x) =>
          x.id === id && x.classification
            ? { ...x, classification: { ...x.classification, type: original } }
            : x,
        ),
      );
    }
  };

  /* ---- 좋아요(confirm) → 실체화 ---- */
  const confirm = async (id: string) => {
    setItems((xs) => xs.map((x) => (x.id === id ? { ...x, status: "confirmed" } : x)));
    try {
      const res = await confirmInbox(id);
      setItems((xs) =>
        xs.map((x) =>
          x.id === id
            ? { ...res.item, classification: x.classification, status: "confirmed", time: x.time }
            : x,
        ),
      );
    } catch {
      setItems((xs) => xs.map((x) => (x.id === id ? { ...x, status: "classified" } : x)));
    }
  };

  const todayRouted = items.filter(
    (x) => x.classification && x.status !== "thinking" && x.status !== "error",
  ).length;
  const shown = items.filter(
    (x) => filter === "all" || (x.classification && x.classification.sphere === filter),
  );

  return (
    <>
      <div className="pagehead">
        <div>
          <div className="ph-eyebrow">
            <span>오늘 {todayRouted}건 정리</span>
            <span className="sep" />
            <span>분류를 고민한 시간 0초</span>
          </div>
          <h1 className="ph-title">
            스마트 인박스 <em>일단 적으세요</em>
          </h1>
        </div>
      </div>

      <div className="work">
        <div className="board">
          {initialLoadError && (
            <div className="inbox-loaderr card sp2" style={{ gridColumn: "span 4" }}>
              <Icon name="x" /> 인박스를 불러오지 못했어요. 새로고침하거나 백엔드 연결을 확인하세요.
            </div>
          )}
          <SmartInbox
            items={shown}
            todayRouted={todayRouted}
            filter={filter}
            onFilter={setFilter}
            onSubmit={submit}
            onConfirm={confirm}
            onReType={reType}
          />
          <ClassifyPrinciples />
          <TodayRouted items={items} todayRouted={todayRouted} />
        </div>
      </div>
    </>
  );
}
