// frontend/components/mail/Triage.tsx — 아리 비서 다이제스트(아리 정리 보기)
// 새 메일 중 '챙길 거리'를 발신자 카드로 정리: 요약 + 할 일/일정/답장 액션을 바로 적용.
"use client";
import { Icon } from "@/components/Icon";
import type { AiAnalysis, AiReply, EmailRow, ExtractKind, Person } from "@/lib/types";

const PALETTE = ["var(--blue)", "var(--violet)", "var(--coral)", "var(--green)", "var(--amber)"];
const PRIO_RANK: Record<string, number> = { 높음: 0, 보통: 1, 낮음: 2 };

// 기준 시각(ISO) → 사용자 로컬 표기('6월 18일 오후 2:30').
function fmtSince(iso?: string): string {
  if (!iso) return "";
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return "";
  return d.toLocaleString("ko-KR", {
    month: "long",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
  });
}

// 발신자 이름 → 안정적 색(메일마다 같은 발신자는 같은 색).
function senderColor(name: string): string {
  let h = 0;
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0;
  return PALETTE[h % PALETTE.length];
}

// 메일 한 통에 달린 액션 수(할 일 + 일정 + 답장 1).
function actionCount(ai: AiAnalysis): number {
  return ai.tasks.length + ai.events.length + (ai.replies.length ? 1 : 0);
}

// 카드 상태 배지 — 우선순위·액션 종류에서 비서 톤으로 산출.
function statusOf(ai: AiAnalysis): { text: string; tone: string } {
  if (ai.priority === "높음") return { text: "중요 · 액션 필요", tone: "coral" };
  if (ai.events.length) return { text: "일정 · 준비 필요", tone: "violet" };
  if (ai.tasks.length) return { text: "할 일 · 확인 필요", tone: "blue" };
  if (ai.replies.length) return { text: "답장 추천", tone: "green" };
  return { text: "검토 필요", tone: "muted" };
}

function ActionRow({
  icon,
  kind,
  title,
  meta,
  done,
  onAdd,
}: {
  icon: "check" | "cal";
  kind: "task" | "event";
  title: string;
  meta: string;
  done: boolean;
  onAdd: () => void;
}) {
  return (
    <div className={"sc-item " + kind}>
      <div className={"si-ico " + kind}>
        <Icon name={icon} />
      </div>
      <div className="si-body">
        <b>{title}</b>
        {meta && <span className="si-meta">{meta}</span>}
      </div>
      <button
        className={"si-add" + (done ? " done" : "")}
        onClick={onAdd}
        disabled={done}
        aria-label={done ? "추가됨" : kind === "task" ? "할 일로 추가" : "일정에 추가"}
      >
        <Icon name={done ? "check" : "plus"} />
      </button>
    </div>
  );
}

function SecretaryCard({
  m,
  name,
  color,
  added,
  onOpen,
  onAdd,
  onAddAll,
  onReply,
}: {
  m: EmailRow;
  name: string;
  color: string;
  added: Record<string, boolean>;
  onOpen: (id: string) => void;
  onAdd: (mailId: string, key: string, kind: ExtractKind, index: number) => void;
  onAddAll: (m: EmailRow) => void;
  onReply: (m: EmailRow, idx: number, r: AiReply) => void;
}) {
  const ai = m.ai;
  if (!ai) return null;
  const status = statusOf(ai);
  const n = actionCount(ai);
  const reply = ai.replies[0];

  return (
    <article className="sc-card">
      <header className="sc-head">
        <div className="sc-ava" style={{ background: color }}>
          {name.slice(0, 1).toUpperCase()}
        </div>
        <div className="sc-who">
          <b>{name}</b>
          <span className={"sc-status " + status.tone}>{status.text}</span>
        </div>
        <button className="sc-open" onClick={() => onOpen(m.id)} aria-label="메일 열기">
          <Icon name="arrow" />
        </button>
      </header>

      <h3 className="sc-title" onClick={() => onOpen(m.id)}>
        {ai.summary || m.subject}
      </h3>
      {ai.summary && m.subject !== ai.summary && <p className="sc-sub">{m.subject}</p>}

      {n > 0 && (
        <div className="sc-actions">
          {ai.tasks.map((t, i) => (
            <ActionRow
              key={"t" + i}
              icon="check"
              kind="task"
              title={t.text}
              meta={[t.due, t.project].filter(Boolean).join(" · ")}
              done={!!added["t:" + m.id + ":" + i]}
              onAdd={() => onAdd(m.id, "t:" + m.id + ":" + i, "task", i)}
            />
          ))}
          {ai.events.map((e, i) => (
            <ActionRow
              key={"e" + i}
              icon="cal"
              kind="event"
              title={e.title}
              meta={[e.date && `${e.date}${e.day ? ` (${e.day})` : ""}`, e.time, e.place]
                .filter(Boolean)
                .join(" · ")}
              done={!!added["e:" + m.id + ":" + i]}
              onAdd={() => onAdd(m.id, "e:" + m.id + ":" + i, "event", i)}
            />
          ))}
          {reply && (
            <button className="sc-item reply" onClick={() => onReply(m, 0, reply)}>
              <div className="si-ico reply">
                <Icon name="reply" />
              </div>
              <div className="si-body">
                <b>답장 초안 · {reply.tone}</b>
                <span className="si-meta">“{reply.preview}”</span>
              </div>
              <Icon name="arrow" />
            </button>
          )}
        </div>
      )}

      {n > 1 && (
        <button className="sc-applyall" onClick={() => onAddAll(m)}>
          <Icon name="zap" />
          {n}개 한 번에 적용
        </button>
      )}
    </article>
  );
}

export function Triage({
  emails,
  people,
  accColor,
  added,
  analyzing,
  since,
  onAnalyze,
  onResetBaseline,
  onOpen,
  onAdd,
  onAddAll,
  onReply,
}: {
  emails: EmailRow[];
  people: Record<string, Person>;
  accColor: (id: string) => string;
  added: Record<string, boolean>;
  analyzing: boolean;
  since?: string;
  onAnalyze: () => void;
  onResetBaseline: () => void;
  onOpen: (id: string) => void;
  onAdd: (mailId: string, key: string, kind: ExtractKind, index: number) => void;
  onAddAll: (m: EmailRow) => void;
  onReply: (m: EmailRow, idx: number, r: AiReply) => void;
}) {
  const nameOf = (m: EmailRow) => people[m.from]?.name ?? m.from_name ?? m.from;
  const colorOf = (m: EmailRow) =>
    people[m.from]?.color ?? senderColor(nameOf(m)) ?? accColor(m.account);

  // 새 메일 = 기준 시각 이후 도착(서버가 smart 보기로 이미 필터). 읽음 여부와 무관 —
  // 사용자가 폰/다른 앱에서 먼저 읽어도 아리가 챙길 거리를 정리한다.
  const fresh = emails.filter((m) => m.ai);
  // 챙길 거리: 할 일/일정/답장이 있거나 중요(높음)인 새 메일.
  const cards = fresh
    .filter((m) => m.ai && (actionCount(m.ai) > 0 || m.ai.priority === "높음"))
    .sort((a, b) => {
      const pa = PRIO_RANK[a.ai!.priority] ?? 1;
      const pb = PRIO_RANK[b.ai!.priority] ?? 1;
      if (pa !== pb) return pa - pb;
      return actionCount(b.ai!) - actionCount(a.ai!);
    });

  const tot = cards.reduce(
    (acc, m) => {
      acc.tasks += m.ai!.tasks.length;
      acc.events += m.ai!.events.length;
      acc.replies += m.ai!.replies.length ? 1 : 0;
      return acc;
    },
    { tasks: 0, events: 0, replies: 0 },
  );
  // 아직 아리가 정리하지 않은(분석 전) 새 메일 수.
  const pending = emails.filter((m) => !m.ai).length;

  return (
    <div className="secretary">
      <div className="sec-scroll" role="region" aria-label="아리 비서 정리" tabIndex={0}>
        <header className="sec-hero">
          <div className="sec-spark">
            <Icon name="spark" />
          </div>
          <div className="sec-hero-main">
            <div className="sec-eyebrow">아리 비서 · 새 메일</div>
            <h2>
              {cards.length > 0
                ? `새 메일 ${fresh.length}통 중 ${cards.length}건을 챙겨뒀어요`
                : pending > 0
                  ? `새 메일 ${pending}통, 정리해 드릴까요?`
                  : "지금은 챙길 새 메일이 없어요"}
            </h2>
            <p>
              아리가 <b>기준 시각 이후 도착한 새 메일</b>만 읽고 할 일·일정·답장으로 정리해요.
              카드마다 바로 적용하거나 한 번에 처리하면, 결재가 필요한 발송은 결재함으로 올려둘게요.
            </p>
            <div className="sec-hero-row">
              {cards.length > 0 && (
                <div className="sec-stats">
                  <span className="sec-stat task">
                    <Icon name="check" />
                    <b>{tot.tasks}</b> 할 일
                  </span>
                  <span className="sec-stat event">
                    <Icon name="cal" />
                    <b>{tot.events}</b> 일정
                  </span>
                  <span className="sec-stat reply">
                    <Icon name="reply" />
                    <b>{tot.replies}</b> 답장
                  </span>
                </div>
              )}
              <button className="sec-analyze" onClick={onAnalyze} disabled={analyzing}>
                <Icon name={analyzing ? "refresh" : "spark"} />
                {analyzing
                  ? "아리가 읽는 중…"
                  : pending > 0
                    ? `새 메일 ${pending}통 정리 맡기기`
                    : "새 메일 확인하기"}
              </button>
            </div>
            {since && (
              <div className="sec-baseline">
                <span>
                  <b>{fmtSince(since)}</b> 이후 도착한 메일만 정리해요
                </span>
                <button onClick={onResetBaseline} disabled={analyzing}>
                  지금부터 다시
                </button>
              </div>
            )}
          </div>
        </header>

        {cards.length === 0 ? (
          <div className="sec-empty">
            <div className="se-ico">
              <Icon name={pending > 0 ? "spark" : "check"} />
            </div>
            {pending > 0 ? (
              <>
                <h3>아직 정리하지 않은 새 메일이 {pending}통 있어요</h3>
                <p>위 ‘정리 맡기기’를 누르면 아리가 읽고 할 일·일정·답장으로 정리해 드려요.</p>
              </>
            ) : (
              <>
                <h3>새로 도착한 메일이 없어요</h3>
                <p>기준 시각 이후 새 메일이 오면 아리가 여기에 할 일·일정·답장으로 정리해 둘게요.</p>
              </>
            )}
          </div>
        ) : (
          <div className="sec-cards">
            {cards.map((m) => (
              <SecretaryCard
                key={m.id}
                m={m}
                name={nameOf(m)}
                color={colorOf(m)}
                added={added}
                onOpen={onOpen}
                onAdd={onAdd}
                onAddAll={onAddAll}
                onReply={onReply}
              />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
