/**
 * Tests for Refinement State Management in ChatStore
 *
 * Story 2.3: Refinement Loop (Regeneration)
 *
 * Tests cover:
 * - Refinement state management (isRefining, refinementDraftId, originalDraft)
 * - startRefinement action
 * - submitRefinementFeedback action
 * - cancelRefinement action
 */

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { useChatStore } from './chat-store';
import type { Draft } from '../db/draft-service';
import { ChatService } from '../../services/chat-service';

// Mock dependencies
vi.mock('../../services/chat-service');

describe('ChatStore - Refinement State Management', () => {
  beforeEach(() => {
    // Reset store state before each test
    useChatStore.getState().clearDraft();
  });

  describe('Initial Refinement State', () => {
    it('should have refinement state initialized correctly', () => {
      const isRefining = useChatStore.getState().isRefining;
      const refinementDraftId = useChatStore.getState().refinementDraftId;
      const originalDraft = useChatStore.getState().originalDraft;

      expect(isRefining).toBe(false);
      expect(refinementDraftId).toBeNull();
      expect(originalDraft).toBeNull();
    });
  });

  describe('startRefinement Action', () => {
    it('should enter refinement mode when startRefinement is called', async () => {
      const mockDraft: Draft = {
        id: 123,
        sessionId: 'session-1',
        title: 'Test Draft',
        content: 'Test content',
        tags: ['test'],
        createdAt: Date.now(),
        status: 'draft',
      };

      // Mock ChatService.startRefinement
      vi.mocked(ChatService.startRefinement).mockResolvedValue(mockDraft);

      const startRefinement = useChatStore.getState().startRefinement;
      if (startRefinement) {
        await startRefinement(123);
      }

      // Verify refinement state is set
      const isRefining = useChatStore.getState().isRefining;
      const refinementDraftId = useChatStore.getState().refinementDraftId;
      const originalDraft = useChatStore.getState().originalDraft;

      expect(isRefining).toBe(true);
      expect(refinementDraftId).toBe(123);
      expect(originalDraft).toEqual(mockDraft);
    });

    it('should call ChatService.startRefinement with correct draft ID', async () => {
      const mockDraft: Draft = {
        id: 123,
        sessionId: 'session-1',
        title: 'Test Draft',
        content: 'Test content',
        tags: ['test'],
        createdAt: Date.now(),
        status: 'draft',
      };

      vi.mocked(ChatService.startRefinement).mockResolvedValue(mockDraft);

      const startRefinement = useChatStore.getState().startRefinement;
      if (startRefinement) {
        await startRefinement(123);
      }

      expect(ChatService.startRefinement).toHaveBeenCalledWith(123);
    });
  });

  describe('submitRefinementFeedback Action', () => {
    it('should submit feedback and regenerate draft', async () => {
      const mockDraft: Draft = {
        id: 123,
        sessionId: 'session-1',
        title: 'Test Draft',
        content: 'Test content',
        tags: ['test'],
        createdAt: Date.now(),
        status: 'draft',
      };

      const refinedMockDraft: Draft = {
        ...mockDraft,
        id: 124,
        content: 'Refined content',
        status: 'regenerated'
      };

      vi.mocked(ChatService.startRefinement).mockResolvedValue(mockDraft);
      vi.mocked(ChatService.submitRefinementFeedback).mockResolvedValue(refinedMockDraft);

      const startRefinement = useChatStore.getState().startRefinement;
      if (startRefinement) {
        await startRefinement(123);
      }

      const submitFeedback = useChatStore.getState().submitRefinementFeedback;
      if (submitFeedback) {
        await submitFeedback('Make it shorter');
      }

      expect(ChatService.submitRefinementFeedback).toHaveBeenCalledWith('Make it shorter', mockDraft);

      // After regeneration, refinement mode should be exited
      const isRefining = useChatStore.getState().isRefining;
      expect(isRefining).toBe(false);

      // Current draft should be updated
      const currentDraft = useChatStore.getState().currentDraft;
      expect(currentDraft).toEqual(refinedMockDraft);
    });
  });

  describe('cancelRefinement Action', () => {
    it('should exit refinement mode and clear state', async () => {
      const mockDraft: Draft = {
        id: 123,
        sessionId: 'session-1',
        title: 'Test Draft',
        content: 'Test content',
        tags: ['test'],
        createdAt: Date.now(),
        status: 'draft',
      };

      vi.mocked(ChatService.startRefinement).mockResolvedValue(mockDraft);

      const startRefinement = useChatStore.getState().startRefinement;
      if (startRefinement) {
        await startRefinement(123);
      }

      // Verify we're in refinement mode
      let isRefining = useChatStore.getState().isRefining;
      expect(isRefining).toBe(true);

      // Cancel refinement
      const cancelRefinement = useChatStore.getState().cancelRefinement;
      if (cancelRefinement) {
        cancelRefinement();
      }

      // Verify refinement state is cleared
      isRefining = useChatStore.getState().isRefining;
      const refinementDraftId = useChatStore.getState().refinementDraftId;
      const originalDraft = useChatStore.getState().originalDraft;

      expect(isRefining).toBe(false);
      expect(refinementDraftId).toBeNull();
      expect(originalDraft).toBeNull();
    });
  });
});
