// @vitest-environment jsdom
import '../../../test/dom-setup';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '../../../test/render-helpers';
import { OverviewTab } from './OverviewTab';
import { __resetDraftPruneForTest } from '../../../hooks/useDraft';
import type { LocalTask } from '../../../api';

const DRAFT_KEY = 'maestro:draft:v1:feedback-comment:7';

const baseTask = {
  id: 7,
  title: 'タスク',
  body: '本文',
  pieceName: 'chat',
  priority: 'medium',
  latestJob: { status: 'succeeded' },
  feedbackRating: null,
  feedbackTags: [],
  feedbackComment: null,
} as unknown as LocalTask;

beforeEach(() => {
  localStorage.clear();
  __resetDraftPruneForTest();
  vi.stubGlobal('fetch', vi.fn(async () => new Response('{}', { status: 404 })));
});

describe('FeedbackPanel comment draft', () => {
  it('👍を押してコメントを書くと下書きが保存され、再マウントで復元される', async () => {
    const user = userEvent.setup();
    const first = renderWithProviders(<OverviewTab task={baseTask} />);
    await user.click(screen.getByRole('button', { name: /👍/ }));
    await user.type(screen.getByRole('textbox'), '精度が良かった');
    first.unmount();
    expect(JSON.parse(localStorage.getItem(DRAFT_KEY)!).text).toBe('精度が良かった');

    renderWithProviders(<OverviewTab task={baseTask} />);
    await user.click(screen.getByRole('button', { name: /👍/ }));
    expect(screen.getByRole('textbox')).toHaveValue('精度が良かった');
  });

  it('保存済みコメントがあるタスクではそちらを優先する', async () => {
    localStorage.setItem(DRAFT_KEY, JSON.stringify({ text: '古い下書き', updatedAt: Date.now() }));
    const saved = {
      ...baseTask,
      feedbackRating: 'good',
      feedbackComment: '確定済みコメント',
    } as unknown as LocalTask;
    const user = userEvent.setup();
    renderWithProviders(<OverviewTab task={saved} />);
    // 保存済み表示 → change で編集に入る
    await user.click(screen.getByRole('button', { name: /change|変更/i }));
    expect(screen.getByRole('textbox')).toHaveValue('確定済みコメント');
  });

  it('フィードバック送信が成功すると下書きが削除される', async () => {
    // 送信前にデバウンス書き込みのタイミングに依存しないよう、下書きは
    // localStorage へ直接シードする（既存テストと同じ堅牢なパターン）。
    localStorage.setItem(DRAFT_KEY, JSON.stringify({ text: '送信予定のコメント', updatedAt: Date.now() }));
    vi.stubGlobal('fetch', vi.fn(async (url: string, init?: RequestInit) => {
      if (typeof url === 'string' && url.includes('/feedback') && init?.method === 'PUT') {
        return new Response(JSON.stringify({ task: { ...baseTask, feedbackRating: 'good' } }), { status: 200 });
      }
      return new Response('{}', { status: 404 });
    }));
    const user = userEvent.setup();
    renderWithProviders(<OverviewTab task={baseTask} />);
    await user.click(screen.getByRole('button', { name: /👍/ }));
    await user.click(screen.getByRole('button', { name: /submit|送信/i }));
    await waitFor(() => expect(localStorage.getItem(DRAFT_KEY)).toBeNull());
  });

  it('キャンセルすると下書きが削除される', async () => {
    const saved = {
      ...baseTask,
      feedbackRating: 'good',
      feedbackComment: '確定済みコメント',
    } as unknown as LocalTask;
    const user = userEvent.setup();
    renderWithProviders(<OverviewTab task={saved} />);
    await user.click(screen.getByRole('button', { name: /change|変更/i }));
    await user.type(screen.getByRole('textbox'), '書きかけの変更');
    // saveDraft はデバウンス書き込みのため、反映を待ってからキャンセルする
    await waitFor(() => expect(JSON.parse(localStorage.getItem(DRAFT_KEY)!).text).toContain('書きかけの変更'));
    await user.click(screen.getByRole('button', { name: /cancel|キャンセル/i }));
    expect(localStorage.getItem(DRAFT_KEY)).toBeNull();
  });
});
