import { beforeEach, describe, expect, it, vi } from 'vitest';
import {
  createPolicyDocument,
  deletePolicyDocument,
  listPolicyDocuments,
  updatePolicyDocument,
} from '@/shared/api/policyDocuments';
import { apiRequest } from '@/shared/api/httpClient';
import type { ApiListResponse } from '@/shared/types/api';
import type { PolicyDocumentDto } from '@/shared/types/policyDocuments';

vi.mock('@/shared/api/httpClient', () => ({
  apiRequest: vi.fn(),
}));

const apiRequestMock = vi.mocked(apiRequest);

describe('policyDocuments API', () => {
  beforeEach(() => {
    apiRequestMock.mockReset();
  });

  describe('listPolicyDocuments', () => {
    it('fetches policy documents by category', async () => {
      const response: ApiListResponse<PolicyDocumentDto> = {
        rows: [
          {
            id: 'doc-1',
            title: 'Fire Drill Procedures',
            body: null,
            category: 'safety_protocol',
            tag: 'fire',
            author: 'Dr. Sarah Williams',
            steps: ['Step 1', 'Step 2'],
            autism_considerations: ['Consideration 1'],
            version: 1,
            active: true,
            organizationId: 'org-1',
            campusId: 'campus-1',
            createdAt: '2024-01-01T00:00:00Z',
            updatedAt: '2024-01-01T00:00:00Z',
          },
        ],
        count: 1,
      };
      apiRequestMock.mockResolvedValueOnce(response);

      await expect(listPolicyDocuments('safety_protocol')).resolves.toEqual(
        response,
      );

      expect(apiRequestMock).toHaveBeenCalledWith(
        '/policy_documents?category=safety_protocol',
      );
    });
  });

  describe('createPolicyDocument', () => {
    it('creates a new policy document', async () => {
      apiRequestMock.mockResolvedValueOnce(true);

      await expect(
        createPolicyDocument({
          title: 'New Handbook Policy',
          category: 'handbook_policy',
          body: 'Policy content here',
          tag: 'Operations',
        }),
      ).resolves.toBe(true);

      expect(apiRequestMock).toHaveBeenCalledWith('/policy_documents', {
        method: 'POST',
        body: {
          data: {
            title: 'New Handbook Policy',
            category: 'handbook_policy',
            body: 'Policy content here',
            tag: 'Operations',
          },
        },
      });
    });
  });

  describe('updatePolicyDocument', () => {
    it('updates an existing policy document', async () => {
      apiRequestMock.mockResolvedValueOnce(true);

      await expect(
        updatePolicyDocument('doc-1', {
          title: 'Updated Safety Protocol',
          category: 'safety_protocol',
          steps: ['Updated step 1', 'Updated step 2'],
          active: true,
        }),
      ).resolves.toBe(true);

      expect(apiRequestMock).toHaveBeenCalledWith('/policy_documents/doc-1', {
        method: 'PUT',
        body: {
          id: 'doc-1',
          data: {
            title: 'Updated Safety Protocol',
            category: 'safety_protocol',
            steps: ['Updated step 1', 'Updated step 2'],
            active: true,
          },
        },
      });
    });
  });

  describe('deletePolicyDocument', () => {
    it('deletes a policy document', async () => {
      apiRequestMock.mockResolvedValueOnce(true);

      await expect(deletePolicyDocument('doc-1')).resolves.toBe(true);

      expect(apiRequestMock).toHaveBeenCalledWith('/policy_documents/doc-1', {
        method: 'DELETE',
      });
    });
  });
});
