/**
 * Tests for API Reference Template
 */

import { ApiReferenceTemplate } from './api-reference-template';
import { TemplateContext } from './base-template';
import { DocumentationIntent } from '../../../types/workflow';

describe('ApiReferenceTemplate', () => {
  let template: ApiReferenceTemplate;

  beforeEach(() => {
    template = new ApiReferenceTemplate();
  });

  it('should handle api_reference intent type', () => {
    const intent: DocumentationIntent = { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
    };

    expect(template.canHandle(intent)).toBe(true);
  });

  it('should not handle other intent types', () => {
    const intent: DocumentationIntent = { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
    };

    expect(template.canHandle(intent)).toBe(false);
  });

  it('should generate API reference from models', () => {
    const context: TemplateContext = {
      intent: { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-api',
          name: 'Test API',
          version: '1.0.0',
          description: 'Test API description',
        },
        stack: {},
      },
      extendedWorkflow: {
        models: {
          User: {
            description: 'User model',
            fields: {
              name: {
                type: 'string',
                required: true,
                description: 'User name',
              },
              email: {
                type: 'string',
                required: true,
                description: 'User email',
              },
              role: {
                type: 'enum',
                enum_values: ['admin', 'user'],
                required: true,
              },
            },
            timestamps: true,
            soft_delete: false,
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    // Should contain API Reference title
    expect(result).toContain('# API Reference');

    // Should contain base URL section
    expect(result).toContain('## Base URL');
    expect(result).toContain('/api');

    // Should contain Data Models section
    expect(result).toContain('## Data Models');
    expect(result).toContain('### User');
    expect(result).toContain('User model');

    // Should contain field table
    expect(result).toContain('| Field | Type | Required | Description |');
    expect(result).toContain('| `name` | string | Yes | User name |');
    expect(result).toContain('| `email` | string | Yes | User email |');
    expect(result).toContain('| `role` | enum (admin, user) | Yes |');

    // Should contain timestamp fields
    expect(result).toContain('| `created_at` | timestamp | Yes | Creation timestamp |');
    expect(result).toContain('| `updated_at` | timestamp | Yes | Last update timestamp |');

    // Should contain example JSON
    expect(result).toContain('**Example:**');
    expect(result).toContain('```json');

    // Should contain error responses section
    expect(result).toContain('## Error Responses');
  });

  it('should generate authentication section when auth is enabled', () => {
    const context: TemplateContext = {
      intent: { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-api',
          name: 'Test API',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        auth: {
          enabled: true,
          provider: 'clerk',
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Authentication');
    expect(result).toContain('Clerk');
    expect(result).toContain('Authorization: Bearer');
  });

  it('should generate endpoints section', () => {
    const context: TemplateContext = {
      intent: { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-api',
          name: 'Test API',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        models: {
          User: {
            fields: {
              name: { type: 'string', required: true, unique: false, system_field: false, exclude_from_forms: false },
            },
            timestamps: true,
      soft_delete: false,
          },
        },
        api: {
          base_path: '/api',
          endpoints: [
            { path: '/users', method: 'GET', component: 'users', description: 'Get all users',
              auth: 'required',
              roles: ['admin', 'user'],
              response: 'User',
            },
            { path: '/users/:id', method: 'GET', component: 'users', description: 'Get user by ID',
              auth: 'required',
              roles: ['admin', 'user'],
              response: 'User',
            },
          ],
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Endpoints');
    expect(result).toContain('### Users');
    expect(result).toContain('#### GET /users');
    expect(result).toContain('Get all users');
    expect(result).toContain('🔒 **Authentication Required**');
    expect(result).toContain('**Allowed Roles:** admin, user');
  });

  it('should generate relationships section', () => {
    const context: TemplateContext = {
      intent: { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-api',
          name: 'Test API',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        relationships: [
          {
            type: 'one_to_many',
            from: 'User',
            to: 'Post',
            description: 'A user can have many posts',
            api_access: {
              queryable: true,
            },
          },
        ],
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Relationships');
    expect(result).toContain('### User → Post');
    expect(result).toContain('**Type:** one to many');
    expect(result).toContain('A user can have many posts');
    expect(result).toContain('include=post');
  });

  it('should generate example values for different field types', () => {
    const context: TemplateContext = {
      intent: { type: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-api',
          name: 'Test API',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        models: {
          Product: {
            fields: {
              name: { type: 'string', required: true, unique: false, system_field: false, exclude_from_forms: false },
              price: { type: 'decimal', required: true, unique: false, system_field: false, exclude_from_forms: false },
              inStock: { type: 'boolean', required: true, unique: false, system_field: false, exclude_from_forms: false },
              quantity: { type: 'integer', required: true, unique: false, system_field: false, exclude_from_forms: false },
              metadata: { type: 'json', required: false, unique: false, system_field: false, exclude_from_forms: false },
              tags: { type: 'array', required: false, unique: false, system_field: false, exclude_from_forms: false },
            },
            timestamps: false,
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    // Check example contains appropriate values
    expect(result).toContain('"price": 99.99');
    expect(result).toContain('"inStock": true');
    expect(result).toContain('"quantity": 42');
    expect(result).toContain('"metadata": {');
    expect(result).toContain('"tags": [');
  });
});
