<script lang="ts">
  // 모닝브리핑 /news — 확정 시안 '편집 신문 1면'. 야간(KST 0~5h) 수집 뉴스를
  // topic×country 비교 분석. 전 기능 보존(국가 관점·기사ID·차이/공통·인용·지난흐름·읽음/별표·날짜).
  // 이모지 국기 → 국가 색칩(no-emoji 규칙). 데이터·API 는 기존 /briefing 그대로.
  import { onMount } from 'svelte';
  import { api, type ApiError } from '$lib/api';

  type CountryPerspective = { country: string; summary: string; article_ids: number[] };
  type KeyQuote = { country: string; source: string; quote: string };
  type BriefingTopic = {
    id: number; topic_rank: number; topic_label: string; headline: string;
    country_perspectives: CountryPerspective[]; divergences: string[]; convergences: string[];
    key_quotes: KeyQuote[]; historical_context: string | null; cluster_members: number[];
    article_count: number; country_count: number; importance_score: number; llm_fallback_used: boolean;
    is_read: boolean; read_at: string | null; highlighted: boolean; highlighted_at: string | null;
  };
  type BriefingDateSummary = {
    briefing_date: string; total_topics: number; total_articles: number;
    status: string; read_count: number; highlighted_count: number;
  };
  type Briefing = {
    briefing_date: string; window_start: string; window_end: string;
    total_articles: number; total_countries: number; total_topics: number;
    llm_calls: number; llm_failures: number;
    status: 'success' | 'partial' | 'failed' | 'empty';
    headline_oneliner: string | null; topics: BriefingTopic[];
  };

  // 국가 라벨(한국어, 이모지 없음) + 색칩 토큰
  const COUNTRY_LABEL: Record<string, string> = {
    KR: '한국', US: '미국', JP: '일본', CN: '중국', HK: '홍콩', TW: '대만',
    DE: '독일', FR: '프랑스', GB: '영국', UK: '영국', IN: '인도', RU: '러시아',
    IR: '이란', IL: '이스라엘', PH: '필리핀', AU: '호주', NL: '네덜란드',
  };
  const COUNTRY_CHIP: Record<string, string> = {
    KR: 'bg-warning', US: 'bg-domain-engineering', JP: 'bg-domain-reference',
    DE: 'bg-accent-hover', HK: 'bg-domain-philosophy', CN: 'bg-error',
    TW: 'bg-domain-general', GB: 'bg-domain-engineering', UK: 'bg-domain-engineering',
    FR: 'bg-domain-philosophy', IN: 'bg-domain-reference', RU: 'bg-error',
    IL: 'bg-accent', IR: 'bg-warning',
  };
  function countryLabel(code: string): string {
    return COUNTRY_LABEL[code?.toUpperCase?.()] ?? code;
  }
  function countryChip(code: string): string {
    return COUNTRY_CHIP[code?.toUpperCase?.()] ?? 'bg-dim';
  }

  let briefing = $state<Briefing | null>(null);
  let loading = $state(true);
  let errorMsg = $state<string | null>(null);
  let availableDates = $state<BriefingDateSummary[]>([]);
  let selectedDate = $state<string>('');

  async function loadBriefing(dateStr: string) {
    loading = true; errorMsg = null;
    try {
      const path = dateStr ? `/briefing?date=${dateStr}` : '/briefing/latest';
      briefing = await api<Briefing>(path);
    } catch (e) {
      const err = e as ApiError;
      briefing = null;
      errorMsg = err?.status === 404
        ? (dateStr ? `${dateStr} 자에는 briefing 이 없습니다.` : '아직 생성된 브리핑이 없습니다. 매일 새벽 05:10 KST 에 자동 생성됩니다.')
        : (err?.detail || '브리핑을 불러오지 못했습니다.');
    } finally {
      loading = false;
    }
  }
  async function loadDates() {
    try { availableDates = await api<BriefingDateSummary[]>('/briefing/dates'); }
    catch { availableDates = []; }
  }
  function onDateChange() { loadBriefing(selectedDate); }

  async function toggleRead(topic: BriefingTopic) {
    if (!briefing) return;
    const next = !topic.is_read;
    try {
      const r = await api<{ is_read: boolean; read_at: string | null }>(
        `/briefing/topics/${topic.id}/read`, { method: 'PATCH', body: JSON.stringify({ value: next }) });
      topic.is_read = r.is_read; topic.read_at = r.read_at;
    } catch (e) { console.error('toggleRead failed', e); }
  }
  async function toggleHighlight(topic: BriefingTopic) {
    if (!briefing) return;
    const next = !topic.highlighted;
    try {
      const r = await api<{ highlighted: boolean; highlighted_at: string | null }>(
        `/briefing/topics/${topic.id}/highlight`, { method: 'PATCH', body: JSON.stringify({ value: next }) });
      topic.highlighted = r.highlighted; topic.highlighted_at = r.highlighted_at;
    } catch (e) { console.error('toggleHighlight failed', e); }
  }

  onMount(async () => { await Promise.all([loadDates(), loadBriefing('')]); });

  const fallbackPct = $derived(
    briefing && briefing.llm_calls > 0 ? Math.round((briefing.llm_failures / briefing.llm_calls) * 100) : 0
  );
  const highlightedCount = $derived(briefing ? briefing.topics.filter((t) => t.highlighted).length : 0);
  const leadTopic = $derived(briefing && briefing.topics.length > 0 ? briefing.topics[0] : null);
  const restTopics = $derived(briefing ? briefing.topics.slice(1) : []);
  function folio(rank: number) { return String(rank).padStart(2, '0'); }
</script>

<div class="nws bg-bg min-h-full p-4 lg:p-6">
  <div class="max-w-[1240px] mx-auto">

    <!-- ═══ 마스트헤드 ═══ -->
    <header class="bg-surface border border-default rounded-lg relative overflow-hidden px-5 lg:px-7 pt-5 pb-4">
      <span class="absolute left-0 top-0 bottom-0 w-[5px] bg-accent"></span>
      <div class="flex justify-between items-end flex-wrap gap-3 border-b-2 border-text pb-2.5 mb-3">
        <div class="nws-serif font-extrabold tracking-tight text-text text-3xl lg:text-4xl leading-none">모닝브리핑</div>
        <div class="flex items-center gap-2.5 flex-wrap text-xs text-dim font-mono">
          {#if availableDates.length > 0}
            <select
              bind:value={selectedDate}
              onchange={onDateChange}
              class="bg-bg border border-default rounded-md px-2 py-1 text-xs text-text"
              aria-label="브리핑 날짜"
            >
              <option value="">최신</option>
              {#each availableDates as d}
                <option value={d.briefing_date}>{d.briefing_date} · {d.total_topics}토픽{#if d.highlighted_count > 0} · ★{d.highlighted_count}{/if}</option>
              {/each}
            </select>
          {:else if briefing}
            <span class="font-bold text-text">{briefing.briefing_date}</span>
          {/if}
          {#if briefing}
            <span>{briefing.total_topics}토픽{#if highlightedCount > 0} · 별표 <span class="text-warning font-bold">{highlightedCount}</span>{/if}</span>
            <span>새벽 수집</span>
          {/if}
        </div>
      </div>

      {#if briefing?.headline_oneliner}
        <div class="nws-serif text-text font-semibold text-lg lg:text-[22px] leading-snug tracking-tight mb-3.5">
          <span class="block font-mono text-xs font-bold text-accent-hover uppercase tracking-wider mb-1">오늘의 한 줄</span>
          {briefing.headline_oneliner}
        </div>
      {/if}

      {#if briefing}
        <div class="flex flex-wrap border-t border-default pt-3">
          <div class="flex flex-col gap-0.5 pr-6 border-r border-default">
            <span class="nws-serif text-2xl font-extrabold text-text leading-none">{briefing.total_articles}</span>
            <span class="text-[11px] text-dim uppercase tracking-wide">총 기사</span>
          </div>
          <div class="flex flex-col gap-0.5 px-6 border-r border-default">
            <span class="nws-serif text-2xl font-extrabold text-text leading-none">{briefing.total_countries}</span>
            <span class="text-[11px] text-dim uppercase tracking-wide">개국</span>
          </div>
          <div class="flex flex-col gap-0.5 px-6">
            <span class="nws-serif text-2xl font-extrabold text-text leading-none">{briefing.total_topics}</span>
            <span class="text-[11px] text-dim uppercase tracking-wide">토픽</span>
          </div>
        </div>
      {/if}

      {#if briefing && (briefing.status === 'partial' || briefing.status === 'failed')}
        <div class="flex items-center gap-2.5 mt-3.5 px-3.5 py-2 rounded-md text-[13px]
          {briefing.status === 'failed' ? 'bg-error/10 border border-error/30 text-error' : 'bg-warning/10 border border-warning/30 text-warning'}">
          <span class="w-2 h-2 rounded-full shrink-0 {briefing.status === 'failed' ? 'bg-error' : 'bg-warning'}"></span>
          {#if briefing.status === 'failed'}
            LLM 분석 실패율이 높습니다 ({briefing.llm_failures}/{briefing.llm_calls}, {fallbackPct}%). 일부 토픽이 원문 묶음으로 표시됩니다.
          {:else}
            일부 토픽 LLM 실패 ({briefing.llm_failures}/{briefing.llm_calls}). 다른 토픽은 정상 분석되었습니다.
          {/if}
        </div>
      {/if}
    </header>

    <!-- ═══ 본문 ═══ -->
    {#if loading}
      <div class="bg-surface border border-default rounded-lg p-5 mt-4 text-sm text-dim">불러오는 중…</div>
    {:else if errorMsg}
      <div class="bg-surface border border-default rounded-lg p-5 mt-4 text-sm text-text">{errorMsg}</div>
    {:else if briefing}
      {#if briefing.status === 'empty'}
        <div class="bg-surface border border-default rounded-lg p-5 mt-4">
          <p class="text-sm text-text">오늘 새벽({briefing.briefing_date}) 다국 비교 가능한 토픽이 없습니다.</p>
          <p class="mt-2 text-xs text-dim">(수집 뉴스 0건 또는 2개국 이상 다룬 주제 없음)</p>
        </div>
      {:else}
        <!-- 리드 토픽 (전체 너비, 관점 2열) -->
        {#if leadTopic}
          {@render topicCard(leadTopic, true)}
        {/if}
        <!-- 나머지 토픽 (2열 그리드) -->
        {#if restTopics.length > 0}
          <div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mt-4">
            {#each restTopics as topic (topic.id)}
              {@render topicCard(topic, false)}
            {/each}
          </div>
        {/if}
      {/if}
    {/if}
  </div>
</div>

{#snippet topicCard(topic, isLead)}
  <article class="bg-surface border rounded-lg overflow-hidden relative transition-opacity
    {isLead ? 'mt-4' : ''}
    {topic.highlighted ? 'border-accent ring-2 ring-accent/25' : 'border-default'}
    {topic.is_read ? 'opacity-50 hover:opacity-80' : ''}">
    {#if topic.is_read}
      <span class="absolute top-3 right-[88px] text-[10px] font-mono font-bold tracking-widest text-error border border-error rounded px-1.5 py-0.5 -rotate-6 opacity-70 pointer-events-none uppercase select-none">읽음</span>
    {/if}
    <!-- head -->
    <div class="flex items-start gap-3.5 px-5 pt-4 pb-3.5 border-b border-default">
      <div class="nws-serif font-extrabold leading-none text-text shrink-0 text-center pt-0.5 min-w-[42px]
        {topic.highlighted ? 'text-white bg-accent rounded-md px-1 py-1.5' : ''} {isLead ? 'text-3xl' : 'text-2xl'}">{folio(topic.topic_rank)}</div>
      <div class="flex-1 min-w-0">
        <div class="font-mono text-[11px] tracking-wide uppercase text-accent-hover font-bold mb-1">
          {topic.topic_label}{#if topic.llm_fallback_used}<span class="text-dim ml-1 normal-case">(원문 묶음)</span>{/if}
        </div>
        <div class="nws-serif font-bold leading-tight text-text tracking-tight {isLead ? 'text-[23px]' : 'text-[19px]'}">{topic.headline}</div>
        <div class="inline-flex items-center gap-1.5 mt-2 text-xs text-dim font-mono">
          <span>{topic.country_count}개국</span><span class="w-1 h-1 rounded-full bg-faint"></span><span>{topic.article_count}건</span>
        </div>
      </div>
      <div class="flex gap-1.5 shrink-0">
        <button type="button" onclick={() => toggleHighlight(topic)} aria-label="별표 토글" title={topic.highlighted ? '별표 해제' : '별표'}
          class="w-[34px] h-[30px] rounded-md border flex items-center justify-center transition-colors
            {topic.highlighted ? 'bg-accent border-accent text-white' : 'bg-bg border-default text-dim hover:text-text hover:bg-surface-hover'}">★</button>
        <button type="button" onclick={() => toggleRead(topic)} aria-label="읽음 토글" title={topic.is_read ? '읽지 않음으로' : '읽음 처리'}
          class="w-[34px] h-[30px] rounded-md border flex items-center justify-center text-xs transition-colors
            {topic.is_read ? 'bg-accent/15 border-accent text-accent-hover' : 'bg-bg border-default text-dim hover:text-text hover:bg-surface-hover'}">✓</button>
      </div>
    </div>

    <!-- body -->
    <div class="px-5 pt-4 pb-4.5">
      {#if topic.country_perspectives.length > 0}
        <div class="nws-rule font-mono text-[10px] tracking-wider uppercase text-faint flex items-center gap-2 mb-2">국가별 관점</div>
        <div class="grid gap-2.5 {isLead ? 'lg:grid-cols-2' : 'grid-cols-1'}">
          {#each topic.country_perspectives as cp}
            <div class="border-l-[3px] border-border-strong pl-3 py-0.5">
              <div class="flex items-center gap-2 flex-wrap mb-1">
                <span class="font-mono text-[10.5px] font-extrabold tracking-wide text-white rounded px-1.5 py-0.5 {countryChip(cp.country)}">{countryLabel(cp.country)}</span>
                {#if cp.article_ids.length > 0}
                  <span class="inline-flex gap-1.5 flex-wrap">
                    {#each cp.article_ids as id}
                      <a href={`/documents/${id}`} class="font-mono text-[11px] text-accent-hover bg-accent/12 rounded px-1.5 py-px border border-transparent hover:border-accent transition-colors">#{id}</a>
                    {/each}
                  </span>
                {/if}
              </div>
              <div class="text-[13.5px] text-text leading-relaxed">{cp.summary}</div>
            </div>
          {/each}
        </div>
      {/if}

      {#if topic.divergences.length > 0 || topic.convergences.length > 0}
        <div class="grid gap-2.5 mt-3.5 {isLead && topic.divergences.length > 0 && topic.convergences.length > 0 ? 'lg:grid-cols-2' : 'grid-cols-1'}">
          {#if topic.divergences.length > 0}
            <div class="rounded-lg px-3.5 py-3 text-[13px] leading-relaxed bg-error/[0.06] border border-error/20">
              <span class="block font-mono text-[10px] font-bold tracking-wide uppercase mb-1.5 text-error">차이</span>
              <span class="text-text">{topic.divergences.join(' · ')}</span>
            </div>
          {/if}
          {#if topic.convergences.length > 0}
            <div class="rounded-lg px-3.5 py-3 text-[13px] leading-relaxed bg-accent/12 border border-accent/25">
              <span class="block font-mono text-[10px] font-bold tracking-wide uppercase mb-1.5 text-accent-hover">공통</span>
              <span class="text-text">{topic.convergences.join(' · ')}</span>
            </div>
          {/if}
        </div>
      {/if}

      {#if topic.key_quotes.length > 0}
        <div class="mt-3.5 flex flex-col gap-2.5">
          {#each topic.key_quotes as q}
            <div class="nws-quote relative pl-6">
              <div class="nws-serif italic text-[15px] leading-snug text-text">{q.quote}</div>
              <div class="text-[11px] text-dim font-mono mt-1 flex items-center gap-1.5 flex-wrap">
                {#if q.country}<span class="text-[9.5px] font-extrabold tracking-wide text-white rounded px-1.5 py-0.5 {countryChip(q.country)}">{countryLabel(q.country)}</span>{/if}
                <span class="font-bold text-text">{q.source}</span>
              </div>
            </div>
          {/each}
        </div>
      {/if}

      {#if topic.historical_context}
        <div class="mt-3.5 px-3 py-2.5 rounded-md bg-bg border border-default text-[12.5px] text-dim leading-relaxed">
          <span class="font-mono text-[10px] font-bold tracking-wide uppercase text-faint mr-1.5">지난 흐름</span>{topic.historical_context}
        </div>
      {/if}
    </div>
  </article>
{/snippet}

<style>
  .nws-serif { font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif; }
  .nws-rule::after { content: ""; flex: 1; height: 1px; background: var(--border); }
  .nws-quote::before {
    content: "\201C"; font-family: Georgia, serif; font-size: 36px; line-height: 0;
    color: var(--accent); position: absolute; left: 0; top: 16px;
  }
</style>
