import React, { useEffect, useState } from 'react';
import { useInbox, selectFilteredNotes } from './store.js';
import { inboxApi } from './api.js';
import { isRecoveryDismissedToday, markRecoveryDismissed } from './recoveryToast.js';
import { NoteCard } from './components/NoteCard.js';
import { ContinuityBadge } from './components/ContinuityBadge.js';
import { IdentityCounter } from './components/IdentityCounter.js';
import { PendingBanner } from './components/PendingBanner.js';
import { OllamaBanner } from './components/OllamaBanner.js';
import { RecoveryToast } from './components/RecoveryToast.js';
import { TagUndoToast } from './components/TagUndoToast.js';
import { ExpiryBanner } from './components/ExpiryBanner.js';
import { FailedBanner } from './components/FailedBanner.js';
import { RecallBanner } from './components/RecallBanner.js';
import { SettingsPage } from './components/SettingsPage.js';
import { OnboardingWizard } from './components/OnboardingWizard.js';
import { SearchBox } from './components/SearchBox.js';
import { ReviewView } from './components/ReviewView.js';
import type { InboxView } from './store.js';

export function App(): React.ReactElement {
  const {
    notes, trashNotes, trashCount, showTrash,
    loading, loadInitial, refreshMeta, upsertNote, removeNote,
    continuity, tagFilter, setTagFilter,
    toggleShowTrash, restoreNote, permanentDeleteNote, emptyTrash
  } = useInbox();
  const showSettings = useInbox((s) => s.showSettings);
  const setShowSettings = useInbox((s) => s.setShowSettings);
  // v0.2.9 Cut B Task 5 — 4탭 (Inbox/완료/보관/휴지통).
  const view = useInbox((s) => s.view);
  const counts = useInbox((s) => s.counts);
  const setView = useInbox((s) => s.setView);
  const searchResults = useInbox((s) => s.searchResults);
  const [recoveryDismissed, setRecoveryDismissed] = useState(isRecoveryDismissedToday());
  // v0.2.9 Cut B Task 12 — 첫 launch onboarding 분기. null = 로딩, true = 표시, false = 미표시.
  const [showOnboarding, setShowOnboarding] = useState<boolean | null>(null);

  useEffect(() => {
    void (async () => {
      try {
        const settings = await inboxApi.getSettings();
        setShowOnboarding(!settings.onboarding_completed);
      } catch {
        // 안전한 fallback — settings 읽기 실패 시 wizard 미표시 (기존 사용자 무영향).
        setShowOnboarding(false);
      }
    })();
  }, []);

  useEffect(() => {
    void loadInitial();
    const unsubNote = inboxApi.onNoteUpdated((note) => {
      upsertNote(note);
      void refreshMeta();
    });
    const unsubOllama = inboxApi.onOllamaStatus((status) => {
      useInbox.setState({ ollamaStatus: status });
    });
    const unsubNav = inboxApi.onNavigate((view) => {
      // v0.2.9 Cut B Task 4 — setView 가 mirror state (showTrash/showSettings) 동기 갱신.
      useInbox.getState().setView(view);
    });
    const onFocus = () => { void refreshMeta(); };
    window.addEventListener('focus', onFocus);
    return () => { unsubNote(); unsubOllama(); unsubNav(); window.removeEventListener('focus', onFocus); };
    // onOllamaStatus 콜백은 useInbox.setState 직접 호출 — store reference 가 안정적이라
    // deps array 에 추가 불필요. mount 시 1회 구독 + unmount 시 해제.
  }, [loadInitial, refreshMeta, upsertNote]);

  if (showOnboarding === null) return <></>;
  if (showOnboarding) return <OnboardingWizard onClose={() => setShowOnboarding(false)} />;

  if (view === 'review-daily') return <ReviewView period="daily" />;
  if (view === 'review-weekly') return <ReviewView period="weekly" />;
  if (view === 'review-monthly') return <ReviewView period="monthly" />;

  if (showSettings) return <SettingsPage />;

  const showRecovery = continuity.showRecoveryToast && !recoveryDismissed;
  const filtered = selectFilteredNotes({ notes, tagFilter });
  const displayed = searchResults !== null ? searchResults : filtered;

  const tabBtnStyle = (active: boolean): React.CSSProperties => ({
    background: active ? '#0a4b80' : 'transparent',
    color: active ? '#fff' : '#0a4b80',
    border: '1px solid #0a4b80',
    borderRadius: 4,
    padding: '4px 10px',
    fontSize: 12,
    cursor: 'pointer'
  });

  return (
    <>
      <div className="header">
        <h1 style={{ fontSize: 18, margin: 0 }}>Inkling</h1>
        <div style={{ display: 'flex', gap: 6, marginLeft: 12 }}>
          {(
            [
              { key: 'inbox', label: 'Inbox', count: counts.active },
              { key: 'completed', label: '완료', count: counts.completed },
              { key: 'archived', label: '보관', count: counts.archived },
              { key: 'trash', label: '휴지통', count: counts.trashed }
            ] as const
          ).map((t) => (
            <button
              key={t.key}
              type="button"
              role="tab"
              aria-selected={view === t.key}
              onClick={() => setView(t.key)}
              style={tabBtnStyle(view === t.key)}
            >
              {t.label}({t.count})
            </button>
          ))}
        </div>
        <select
          aria-label="회고 기간"
          value={view.startsWith('review-') ? view.replace('review-', '') : ''}
          onChange={(e) => {
            const v = e.target.value;
            if (v === 'daily' || v === 'weekly' || v === 'monthly') setView(`review-${v}` as InboxView);
          }}
          style={{ marginLeft: 8, fontSize: 12, padding: '4px 6px', border: '1px solid #0a4b80', borderRadius: 4, color: '#0a4b80', background: 'transparent' }}
        >
          <option value="">📅 회고…</option>
          <option value="daily">일간</option>
          <option value="weekly">주간</option>
          <option value="monthly">월간</option>
        </select>
        <SearchBox />
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2, marginLeft: 'auto' }}>
          <ContinuityBadge />
          <IdentityCounter />
        </div>
        <button
          aria-label="설정 열기"
          onClick={() => setShowSettings(true)}
          style={{
            background: 'transparent',
            border: 'none',
            cursor: 'pointer',
            padding: 4,
            fontSize: 16,
            marginLeft: 8
          }}
        >
          ⚙
        </button>
      </div>
      <main className="main">
        {!showTrash && (
          <>
            <OllamaBanner onOpenSettings={() => setShowSettings(true)} />
            <RecoveryToast
              show={showRecovery}
              onDismiss={() => { markRecoveryDismissed(); setRecoveryDismissed(true); }}
            />
            <PendingBanner />
            <FailedBanner />
            <ExpiryBanner />
            <RecallBanner />
            {tagFilter !== null && (
              <div style={{
                background: '#eaf3ff', color: '#0a4b80', padding: '6px 12px',
                borderRadius: 6, margin: '8px 0', fontSize: 12,
                display: 'flex', alignItems: 'center', gap: 8
              }}>
                <span>🔎 필터: <strong>#{tagFilter}</strong></span>
                <span style={{ color: '#666' }}>({filtered.length}개)</span>
                <button
                  onClick={() => setTagFilter(null)}
                  style={{ marginLeft: 'auto', background: 'none', border: 'none', color: '#0a4b80', cursor: 'pointer', fontSize: 12 }}
                  title="필터 해제"
                >
                  ✕ 해제
                </button>
              </div>
            )}
            {loading && notes.length === 0 ? (
              <div className="empty">불러오는 중…</div>
            ) : searchResults !== null && displayed.length === 0 ? (
              <div className="empty">검색 결과가 없습니다.</div>
            ) : notes.length === 0 ? (
              <div className="empty">머릿속에 떠다니는 한 줄을 적어보세요. <code>Ctrl+Shift+J</code></div>
            ) : displayed.length === 0 ? (
              <div className="empty">이 태그의 노트가 없습니다.</div>
            ) : (
              displayed.map((n) => (
                <NoteCard
                  key={n.id} note={n} mode="inbox"
                  onDeleted={() => removeNote(n.id)}
                  onUpdated={(u) => upsertNote(u)}
                />
              ))
            )}
          </>
        )}
        {showTrash && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', margin: '8px 0' }}>
              <div style={{ fontSize: 13, color: '#666' }}>
                {trashCount === 0 ? '휴지통이 비어있습니다.' : `${trashCount}개 보관 중`}
              </div>
              <button
                onClick={() => void emptyTrash()}
                disabled={trashCount === 0}
                style={{
                  background: trashCount === 0 ? '#666' : '#a33', color: '#fff',
                  border: 'none', borderRadius: 4, padding: '4px 10px',
                  fontSize: 12, cursor: trashCount === 0 ? 'not-allowed' : 'pointer'
                }}
              >
                휴지통 비우기 ({trashCount}개)
              </button>
            </div>
            {trashNotes.length === 0 ? null : (
              trashNotes.map((n) => (
                <NoteCard
                  key={n.id} note={n} mode="trash"
                  onUpdated={(u) => upsertNote(u)}
                  onRestore={() => void restoreNote(n.id)}
                  onPermanentDelete={() => void permanentDeleteNote(n.id)}
                />
              ))
            )}
          </>
        )}
      </main>
      <TagUndoToast />
    </>
  );
}
