// @vitest-environment jsdom
import { describe, it, expect, vi, beforeEach } from 'vitest';
import '@testing-library/jest-dom/vitest';
import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react';

const { mockSetStatus, mockClassify } = vi.hoisted(() => ({
  mockSetStatus: vi.fn(async () => ({ ok: true as const })),
  mockClassify: vi.fn(async () => ({
    recommended: 'completed' as const,
    rationale: '결재 끝'
  }))
}));

vi.mock('../../src/renderer/inbox/api.js', () => ({
  inboxApi: {
    setStatus: mockSetStatus,
    classifyStatus: mockClassify
  }
}));

import { MoveStatusModal } from '../../src/renderer/inbox/components/MoveStatusModal';

describe('MoveStatusModal', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    cleanup();
  });

  it('renders reason textarea + 4 buttons + AI classify button', () => {
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={vi.fn()}
        onMoved={vi.fn()}
      />
    );
    expect(screen.getByRole('textbox')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '완료' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '보관' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '휴지통' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /AI 자동 분류/ })).toBeInTheDocument();
  });

  it('clicking 완료 calls setStatus with reason', async () => {
    const onMoved = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={vi.fn()}
        onMoved={onMoved}
      />
    );
    fireEvent.change(screen.getByRole('textbox'), { target: { value: '결재 끝' } });
    fireEvent.click(screen.getByRole('button', { name: '완료' }));
    await waitFor(() => {
      expect(mockSetStatus).toHaveBeenCalledWith('n1', 'completed', '결재 끝');
      expect(onMoved).toHaveBeenCalledWith('completed', '결재 끝');
    });
  });

  it('AI 자동 분류 → recommendation 표시 + 확정 → setStatus', async () => {
    const onMoved = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={vi.fn()}
        onMoved={onMoved}
      />
    );
    fireEvent.change(screen.getByRole('textbox'), { target: { value: '결재 끝' } });
    fireEvent.click(screen.getByRole('button', { name: /AI 자동 분류/ }));
    await screen.findByText(/AI 추천/);
    expect(screen.getByText(/이유: 결재 끝/)).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: /확정/ }));
    await waitFor(() => expect(onMoved).toHaveBeenCalledWith('completed', '결재 끝'));
  });

  it('currentStatus=completed → Inbox/보관/휴지통 노출, 완료 미노출', () => {
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="completed"
        onClose={vi.fn()}
        onMoved={vi.fn()}
      />
    );
    expect(screen.getByRole('button', { name: 'Inbox' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '보관' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '휴지통' })).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: '완료' })).toBeNull();
  });

  it('currentStatus=archived → Inbox 버튼 클릭 시 setStatus("active") 호출', async () => {
    const onMoved = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="archived"
        onClose={vi.fn()}
        onMoved={onMoved}
      />
    );
    fireEvent.click(screen.getByRole('button', { name: 'Inbox' }));
    await waitFor(() => {
      expect(mockSetStatus).toHaveBeenCalledWith('n1', 'active', null);
      expect(onMoved).toHaveBeenCalledWith('active', null);
    });
  });

  it('currentStatus=trashed → Inbox/완료/보관 노출, 휴지통 미노출', () => {
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="trashed"
        onClose={vi.fn()}
        onMoved={vi.fn()}
      />
    );
    expect(screen.getByRole('button', { name: 'Inbox' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '완료' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '보관' })).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: '휴지통' })).toBeNull();
  });

  it('Escape key → onClose 호출', () => {
    const onClose = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={onClose}
        onMoved={vi.fn()}
      />
    );
    fireEvent.keyDown(document, { key: 'Escape' });
    expect(onClose).toHaveBeenCalled();
  });

  it('overlay 클릭 → onClose, modal body 클릭 → 무반응', () => {
    const onClose = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={onClose}
        onMoved={vi.fn()}
      />
    );
    // body 클릭 (textarea) → onClose 호출 안 됨
    fireEvent.click(screen.getByRole('textbox'));
    expect(onClose).not.toHaveBeenCalled();
    // overlay (dialog) 클릭 → onClose
    fireEvent.click(screen.getByRole('dialog', { name: '이동' }));
    expect(onClose).toHaveBeenCalled();
  });

  it('빈 사유 → null reason 전달', async () => {
    const onMoved = vi.fn();
    render(
      <MoveStatusModal
        noteId="n1"
        rawText="t"
        summary=""
        currentStatus="active"
        onClose={vi.fn()}
        onMoved={onMoved}
      />
    );
    fireEvent.click(screen.getByRole('button', { name: '보관' }));
    await waitFor(() => expect(mockSetStatus).toHaveBeenCalledWith('n1', 'archived', null));
  });
});
