/**
 * Tests for Architecture Template
 */

import { ArchitectureTemplate } from './architecture-template';
import { TemplateContext } from './base-template';
import { DocumentationIntent } from '../../../types/workflow';

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

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

  it('should handle architecture intent type', () => {
    const intent: DocumentationIntent = { type: 'architecture', 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 architecture documentation with technology stack', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test Application',
          version: '1.0.0',
          description: 'Test app description',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          frontend: {
            framework: 'react',
            language: 'typescript',
            styling: 'tailwind',
          },
          backend: {
            framework: 'express',
            language: 'typescript',
            orm: 'prisma',
          },
                 
          database: {
            type: 'postgresql',
            version: '15',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('# Architecture Documentation');
    expect(result).toContain('## System Overview');
    expect(result).toContain('## Technology Stack');
    expect(result).toContain('### Frontend');
    expect(result).toContain('**Framework:** React');
    expect(result).toContain('### Backend');
    expect(result).toContain('**Framework:** Express');
    expect(result).toContain('### Database');
    expect(result).toContain('**Type:** Postgresql');
  });

  it('should generate data architecture section', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          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 },
              email: { type: 'string', required: true, unique: false, system_field: false, exclude_from_forms: false },
            },
            timestamps: true,
            soft_delete: false,
          },
          Post: {
            fields: {
              title: { type: 'string', required: true, unique: false, system_field: false, exclude_from_forms: false },
              content: { type: 'text', required: true, unique: false, system_field: false, exclude_from_forms: false },
            },
            timestamps: true,
      soft_delete: false,
          },
        },
        relationships: [
          {
            type: 'one_to_many',
            from: 'User',
            to: 'Post',
            description: 'Users can have many posts',
          },
        ],
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Data Architecture');
    expect(result).toContain('### Entity Relationship Model');
    expect(result).toContain('#### User');
    expect(result).toContain('#### Post');
    expect(result).toContain('### Relationships');
    expect(result).toContain('User 1---* Post');
  });

  it('should generate API architecture section', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        api: {
          base_path: '/api',
          endpoints: [
            { path: '/users', method: 'GET', component: 'users', auth: 'none' as const, description: 'Get all users',
            },
            { path: '/users/:id', method: 'GET', component: 'users', auth: 'none' as const, description: 'Get user by ID',
            },
            { path: '/posts', method: 'GET', component: 'posts', auth: 'none' as const, description: 'Get all posts',
            },
          ],
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## API Architecture');
    expect(result).toContain('### RESTful API');
    expect(result).toContain('**Base Path:** `/api`');
    expect(result).toContain('**Total Endpoints:** 3');
    expect(result).toContain('**Endpoints by Method:**');
    expect(result).toContain('- GET: 3');
    expect(result).toContain('**Endpoints by Component:**');
    expect(result).toContain('- Users: 2 endpoints');
    expect(result).toContain('- Posts: 1 endpoints');
  });

  it('should generate data flow section with events', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        events: {
          user_created: {
            description: 'User account created',
            payload: {
              user_id: 'string',
              email: 'string',
            },
          },
          post_published: {
            description: 'Post published',
            payload: {
              post_id: 'string',
              user_id: 'string',
            },
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Data Flow');
    expect(result).toContain('### Event-Driven Architecture');
    expect(result).toContain('#### user_created');
    expect(result).toContain('User account created');
    expect(result).toContain('**Payload:**');
  });

  it('should generate security architecture section', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        auth: {
          enabled: true,
          provider: 'clerk',
          strategies: ['email', 'oauth'],
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Security Architecture');
    expect(result).toContain('### Authentication & Authorization');
    expect(result).toContain('**Provider:** Clerk');
    expect(result).toContain('**Strategies:** email, oauth');
    expect(result).toContain('### API Security');
  });

  it('should generate deployment architecture section', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        stages: {
          local: {
            domain: 'localhost:3000',
            database: 'postgresql://localhost/test_dev',
            config: {
              log_level: 'debug',
            },
          },
          production: {
            domain: 'app.example.com',
            infrastructure: {
              databases: {
                primary: 'postgresql://prod/db',
              },
            },
            config: {
              log_level: 'error',
            },
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Deployment Architecture');
    expect(result).toContain('### Containerization');
    expect(result).toContain('### Environments');
    expect(result).toContain('#### Local');
    expect(result).toContain('#### Production');
  });

  it('should generate components section', () => {
    const context: TemplateContext = {
      intent: { type: 'architecture', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {
          auth: {
            type: 'backend',
            technology: 'clerk',
            services: {
              jwt: {
                type: 'auth_provider',
                config: {},
              },
            },
          },
        },
      },
      extendedWorkflow: {},
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## System Components');
    expect(result).toContain('### Stack Components');
    expect(result).toContain('#### Auth');
    expect(result).toContain('- **Type:** backend');
    expect(result).toContain('- **Technology:** clerk');
  });
});
