import { DisputeFlowService } from '../../backend/src/dispute-flow/dispute-flow.service';
import { db } from '../../backend/src/db';

// Mock the database connection for testing
jest.mock('../../backend/src/db', () => ({
  db: {
    query: jest.fn()
  }
}));

describe('DisputeFlowService', () => {
  let service: DisputeFlowService;

  beforeEach(() => {
    service = new DisputeFlowService();
    // Reset all mocks before each test
    jest.clearAllMocks();
  });

  describe('createDispute', () => {
    it('should create a new dispute', async () => {
      const mockDispute = {
        id: 1,
        dealId: 123,
        openedByUserId: 456,
        status: 'open',
        reasonCode: 'NO_SHOW',
        summary: 'Helper did not show up',
        requestedOutcome: 'refund',
        createdAt: new Date(),
        updatedAt: new Date()
      };

      (db.query as jest.Mock).mockResolvedValue({ rows: [mockDispute] });

      const result = await service.createDispute({
        dealId: 123,
        openedByUserId: 456,
        reasonCode: 'NO_SHOW',
        summary: 'Helper did not show up',
        requestedOutcome: 'refund'
      });

      expect(db.query).toHaveBeenCalled();
      expect(result).toEqual(mockDispute);
    });
  });

  describe('addEvidence', () => {
    it('should add evidence to a dispute', async () => {
      (db.query as jest.Mock).mockResolvedValue({});

      await service.addEvidence(1, { file: 'test.jpg' }, 456);

      expect(db.query).toHaveBeenCalled();
    });
  });

  describe('updateDisputeStatus', () => {
    it('should update dispute status', async () => {
      (db.query as jest.Mock).mockResolvedValue({});

      await service.updateDisputeStatus(1, 'evidence', 456);

      expect(db.query).toHaveBeenCalled();
    });
  });

  describe('resolveDispute', () => {
    it('should resolve a dispute', async () => {
      (db.query as jest.Mock).mockResolvedValue({});

      await service.resolveDispute(1, { decision: 'refund', decisionReason: 'Helper did not show up' }, 456);

      expect(db.query).toHaveBeenCalled();
    });
  });

  describe('getDisputeById', () => {
    it('should get dispute by ID', async () => {
      const mockDispute = {
        id: 1,
        dealId: 123,
        openedByUserId: 456,
        status: 'open',
        reasonCode: 'NO_SHOW',
        summary: 'Helper did not show up',
        requestedOutcome: 'refund',
        createdAt: new Date(),
        updatedAt: new Date()
      };

      (db.query as jest.Mock).mockResolvedValue({ rows: [mockDispute] });

      const result = await service.getDisputeById(1);

      expect(db.query).toHaveBeenCalled();
      expect(result).toEqual(mockDispute);
    });
  });

  describe('getDisputeEvents', () => {
    it('should get dispute events', async () => {
      const mockEvents = [
        {
          id: 1,
          disputeId: 1,
          eventType: 'evidence',
          actorUserId: 456,
          payloadJson: JSON.stringify({ file: 'test.jpg' }),
          createdAt: new Date()
        }
      ];

      (db.query as jest.Mock).mockResolvedValue({ rows: mockEvents });

      const result = await service.getDisputeEvents(1);

      expect(db.query).toHaveBeenCalled();
      expect(result).toEqual(mockEvents);
    });
  });
});