/*
 * File: aiPredictionAPI.test.ts
 * Description: Unit tests for AI Prediction API service
 * Design & Developed by Tech4Biz Solutions
 * Copyright (c) Spurrin Innovations. All rights reserved.
 */

import { aiPredictionAPI } from '../services/aiPredictionAPI';

// Mock apisauce
jest.mock('apisauce', () => ({
  create: jest.fn(() => ({
    get: jest.fn(),
    post: jest.fn(),
    put: jest.fn(),
    delete: jest.fn(),
  })),
}));

// Mock API utilities
jest.mock('../../../shared/utils', () => ({
  API_CONFIG: {
    BASE_URL: 'https://test-api.com',
  },
  buildHeaders: jest.fn((options = {}) => ({
    headers: {
      'Content-Type': 'application/json',
      ...(options.token && { Authorization: `Bearer ${options.token}` }),
    },
  })),
}));

// ============================================================================
// MOCK DATA
// ============================================================================

const mockToken = 'test-token-123';
const mockResponse = {
  ok: true,
  data: {
    success: true,
    data: [
      {
        patid: 'test-001',
        hospital_id: 'hospital-001',
        prediction: {
          label: 'test finding',
          finding_type: 'pathology',
          clinical_urgency: 'urgent',
          confidence_score: 0.95,
          finding_category: 'abnormal',
          primary_severity: 'high',
          anatomical_location: 'brain',
        },
      },
    ],
  },
};

// ============================================================================
// UNIT TESTS
// ============================================================================

describe('AI Prediction API', () => {
  let mockApi: any;

  beforeEach(() => {
    // Reset mocks
    jest.clearAllMocks();
    
    // Get the mocked API instance
    const { create } = require('apisauce');
    mockApi = create();
  });

  // ============================================================================
  // GET ALL PREDICTIONS TESTS
  // ============================================================================

  describe('getAllPredictions', () => {
    it('should call GET endpoint with correct parameters', async () => {
      mockApi.get.mockResolvedValue(mockResponse);

      const params = {
        page: 1,
        limit: 20,
        urgency: 'urgent',
        search: 'test',
      };

      await aiPredictionAPI.getAllPredictions(mockToken, params);

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/all-prediction-results',
        params,
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });

    it('should call GET endpoint without parameters', async () => {
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.getAllPredictions(mockToken);

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/all-prediction-results',
        {},
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // GET CASE DETAILS TESTS
  // ============================================================================

  describe('getCaseDetails', () => {
    it('should call GET endpoint with correct case ID', async () => {
      const caseId = 'test-case-001';
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.getCaseDetails(caseId, mockToken);

      expect(mockApi.get).toHaveBeenCalledWith(
        `/api/ai-cases/prediction-details/${caseId}`,
        {},
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // UPDATE CASE REVIEW TESTS
  // ============================================================================

  describe('updateCaseReview', () => {
    it('should call PUT endpoint with correct data', async () => {
      const caseId = 'test-case-001';
      const reviewData = {
        review_status: 'reviewed' as const,
        reviewed_by: 'Dr. Test',
        review_notes: 'Test notes',
        priority: 'high' as const,
      };

      mockApi.put.mockResolvedValue(mockResponse);

      await aiPredictionAPI.updateCaseReview(caseId, reviewData, mockToken);

      expect(mockApi.put).toHaveBeenCalledWith(
        `/api/ai-cases/review/${caseId}`,
        reviewData,
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // GET STATISTICS TESTS
  // ============================================================================

  describe('getPredictionStats', () => {
    it('should call GET endpoint with time range parameter', async () => {
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.getPredictionStats(mockToken, 'week');

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/statistics',
        { timeRange: 'week' },
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });

    it('should call GET endpoint without time range parameter', async () => {
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.getPredictionStats(mockToken);

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/statistics',
        {},
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // SEARCH PREDICTIONS TESTS
  // ============================================================================

  describe('searchPredictions', () => {
    it('should call GET endpoint with search query and filters', async () => {
      const query = 'test search';
      const filters = {
        urgency: ['urgent', 'emergency'],
        severity: ['high'],
        dateRange: { start: '2024-01-01', end: '2024-01-31' },
      };

      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.searchPredictions(query, mockToken, filters);

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/search',
        {
          q: query,
          filters: JSON.stringify(filters),
        },
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });

    it('should call GET endpoint with only search query', async () => {
      const query = 'test search';
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.searchPredictions(query, mockToken);

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/search',
        { q: query },
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // BULK OPERATIONS TESTS
  // ============================================================================

  describe('bulkUpdateReviews', () => {
    it('should call PUT endpoint with case IDs and review data', async () => {
      const caseIds = ['case-001', 'case-002', 'case-003'];
      const reviewData = {
        review_status: 'reviewed' as const,
        reviewed_by: 'Dr. Test',
        review_notes: 'Bulk review',
      };

      mockApi.put.mockResolvedValue(mockResponse);

      await aiPredictionAPI.bulkUpdateReviews(caseIds, reviewData, mockToken);

      expect(mockApi.put).toHaveBeenCalledWith(
        '/api/ai-cases/bulk-review',
        { caseIds, reviewData },
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // SUBMIT FEEDBACK TESTS
  // ============================================================================

  describe('submitPredictionFeedback', () => {
    it('should call POST endpoint with feedback data', async () => {
      const caseId = 'test-case-001';
      const feedbackData = {
        accuracy_rating: 4 as const,
        is_accurate: true,
        physician_diagnosis: 'Confirmed midline shift',
        feedback_notes: 'Accurate prediction',
        improvement_suggestions: 'None',
      };

      mockApi.post.mockResolvedValue(mockResponse);

      await aiPredictionAPI.submitPredictionFeedback(caseId, feedbackData, mockToken);

      expect(mockApi.post).toHaveBeenCalledWith(
        `/api/ai-cases/feedback/${caseId}`,
        feedbackData,
        expect.objectContaining({
          headers: expect.objectContaining({
            Authorization: `Bearer ${mockToken}`,
          }),
        })
      );
    });
  });

  // ============================================================================
  // ERROR HANDLING TESTS
  // ============================================================================

  describe('Error handling', () => {
    it('should handle API errors gracefully', async () => {
      const errorResponse = {
        ok: false,
        problem: 'NETWORK_ERROR',
        data: null,
      };

      mockApi.get.mockResolvedValue(errorResponse);

      const result = await aiPredictionAPI.getAllPredictions(mockToken);
      expect(result).toEqual(errorResponse);
    });

    it('should handle missing token', async () => {
      mockApi.get.mockResolvedValue(mockResponse);

      await aiPredictionAPI.getAllPredictions('');

      expect(mockApi.get).toHaveBeenCalledWith(
        '/api/ai-cases/all-prediction-results',
        {},
        expect.objectContaining({
          headers: expect.objectContaining({
            'Content-Type': 'application/json',
          }),
        })
      );
    });
  });
});

/*
 * End of File: aiPredictionAPI.test.ts
 * Design & Developed by Tech4Biz Solutions
 * Copyright (c) Spurrin Innovations. All rights reserved.
 */
