// @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';
import React from 'react';

const { mockMoveNote, mockBatchClassifyDefault } = vi.hoisted(() => ({
  mockMoveNote: vi.fn(async () => ({ ok: true as const })),
  mockBatchClassifyDefault: vi.fn(async () => ({ assignments: [] }))
}));

vi.mock('../../src/renderer/inbox/api.js', () => ({
  inboxApi: {
    batchClassifyDefault: mockBatchClassifyDefault,
    getContinuity: vi.fn(async () => ({ weekStart: '', weekCount: 0, weekTarget: 7, consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null })),
    countsByStatus: vi.fn(async () => ({ active: 0, completed: 0, trashed: 0 })),
    getSettings: vi.fn(async () => ({ ai_enabled: true })),
    getPendingCount: vi.fn(async () => 0),
    getOllamaStatus: vi.fn(async () => ({ ok: true })),
    getTodayCount: vi.fn(async () => 0),
    getTrashCount: vi.fn(async () => 0),
    listExpired: vi.fn(async () => []),
    getFailedCount: vi.fn(async () => 0),
    listRecallCandidate: vi.fn(async () => null),
    listByStatus: vi.fn(async () => [])
  },
  notebookApi: {
    moveNote: mockMoveNote,
    list: vi.fn(async () => [])
  }
}));

import { BatchMoveModal } from '../../src/renderer/inbox/components/BatchMoveModal';
import { useInbox } from '../../src/renderer/inbox/store';

const baseNote = {
  id: 'n1',
  rawText: '테스트 노트 내용',
  aiTitle: 'AI 제목',
  aiSummary: null,
  aiStatus: 'done' as const,
  aiError: null,
  aiProvider: null,
  aiGeneratedAt: null,
  titleEditedByUser: false,
  summaryEditedByUser: false,
  userIntent: null,
  intentPromptedAt: null,
  dueDate: null,
  dueDateEditedByUser: false,
  deletedAt: null,
  lastRecalledAt: null,
  recallDismissedAt: null,
  status: 'active' as const,
  statusChangedAt: null,
  moveReason: null,
  createdAt: '2026-01-01T00:00:00Z',
  updatedAt: '2026-01-01T00:00:00Z',
  tags: [],
  media: [],
  notebookId: 'nb-default'
};

describe('BatchMoveModal', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    cleanup();
    useInbox.setState({
      batchClassifyResult: null,
      batchClassifying: false,
      notes: [],
      notebooks: []
    } as Partial<ReturnType<typeof useInbox.getState>>);
  });

  it('batchClassifyResult null 시 null 반환', () => {
    useInbox.setState({ batchClassifyResult: null } as Partial<ReturnType<typeof useInbox.getState>>);
    const { container } = render(<BatchMoveModal />);
    expect(container).toBeEmptyDOMElement();
  });

  it('actionable 0건 시 "찾지 못했어요" 메시지 표시', () => {
    useInbox.setState({
      batchClassifyResult: { assignments: [{ noteId: 'n1', notebookId: null, notebookName: null }] }
    } as Partial<ReturnType<typeof useInbox.getState>>);
    render(<BatchMoveModal />);
    expect(screen.getByText(/찾지 못했어요/)).toBeInTheDocument();
  });

  it('actionable 노트 표시 + checkbox 기본 체크', () => {
    useInbox.setState({
      batchClassifyResult: {
        assignments: [
          { noteId: 'n1', notebookId: 'nb1', notebookName: '업무' }
        ]
      },
      notes: [{ ...baseNote, id: 'n1', aiTitle: 'AI 제목' }]
    } as Partial<ReturnType<typeof useInbox.getState>>);
    render(<BatchMoveModal />);
    expect(screen.getByText('AI 제목')).toBeInTheDocument();
    expect(screen.getByText(/→ 업무/)).toBeInTheDocument();
    const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
    expect(checkbox.checked).toBe(true);
  });

  it('checkbox toggle 시 selectedIds 변경 (체크 해제 후 확인 버튼 비활성)', () => {
    useInbox.setState({
      batchClassifyResult: {
        assignments: [
          { noteId: 'n1', notebookId: 'nb1', notebookName: '업무' }
        ]
      },
      notes: [{ ...baseNote, id: 'n1' }]
    } as Partial<ReturnType<typeof useInbox.getState>>);
    render(<BatchMoveModal />);
    const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
    expect(checkbox.checked).toBe(true);

    fireEvent.click(checkbox);
    expect(checkbox.checked).toBe(false);
    const confirmBtn = screen.getByRole('button', { name: /건 이동/ });
    expect(confirmBtn).toBeDisabled();
  });

  it('확인 클릭 → acceptBatchAssignments 호출 후 modal 닫힘', async () => {
    const mockAccept = vi.fn(async () => {});
    useInbox.setState({
      batchClassifyResult: {
        assignments: [
          { noteId: 'n1', notebookId: 'nb1', notebookName: '업무' }
        ]
      },
      notes: [{ ...baseNote, id: 'n1' }],
      acceptBatchAssignments: mockAccept
    } as Partial<ReturnType<typeof useInbox.getState>>);
    render(<BatchMoveModal />);
    const confirmBtn = screen.getByRole('button', { name: /건 이동/ });
    fireEvent.click(confirmBtn);
    await waitFor(() => {
      expect(mockAccept).toHaveBeenCalledWith([{ noteId: 'n1', notebookId: 'nb1' }]);
    });
  });
});
