/**
 * Tests for Tutorial Template
 */

import { TutorialTemplate } from './tutorial-template';
import { TemplateContext } from './base-template';
import { DocumentationIntent } from '../../../types/workflow';

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

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

  it('should handle tutorial intent type', () => {
    const intent: DocumentationIntent = { type: 'tutorial', 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: 'api_reference', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
    };

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

  it('should generate getting started tutorial by default', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test application',
        },
        stack: {},
      },
      extendedWorkflow: {
        models: {
          User: {
            fields: {
              name: { type: 'string', required: true, unique: false, system_field: false, exclude_from_forms: false },
            },
            timestamps: true,
      soft_delete: false,
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('# Tutorial');
    expect(result).toContain('## Getting Started');
    expect(result).toContain('### Step 1: Set Up Your Environment');
    expect(result).toContain('### Step 2: Understanding the Data Models');
    expect(result).toContain('### Step 3: Make Your First API Call');
  });

  it('should generate TypeScript/Express endpoint tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['create_endpoint'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          backend: {
            language: 'typescript',
            framework: 'express',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Creating Your First API Endpoint');
    expect(result).toContain('### Step 1: Define the Route');
    expect(result).toContain('backend/src/routes/items.ts');
    expect(result).toContain("import { Router } from 'express'");
    expect(result).toContain('router.get');
    expect(result).toContain('### Step 2: Register the Route');
    expect(result).toContain('### Step 3: Test the Endpoint');
    expect(result).toContain('curl http://localhost:3001/api/items');
  });

  it('should generate Python/Flask endpoint tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['create_endpoint'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          backend: {
            language: 'python',
            framework: 'flask',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Creating Your First API Endpoint');
    expect(result).toContain('### Step 1: Create a Blueprint');
    expect(result).toContain('backend/routes/items.py');
    expect(result).toContain('from flask import Blueprint');
    expect(result).toContain('items_bp = Blueprint');
    expect(result).toContain('### Step 2: Register the Blueprint');
    expect(result).toContain('app.register_blueprint');
  });

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

    const result = template.generate(context);

    expect(result).toContain('## Adding Authentication');
    expect(result).toContain('### Step 1: Install Clerk SDK');
    expect(result).toContain('### Step 2: Protect an Endpoint');
    expect(result).toContain('requireAuth');
    expect(result).toContain('### Step 3: Test');
    expect(result).toContain('getToken');
    expect(result).toContain("'Authorization'");
  });

  it('should generate Prisma model tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['create_model'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          backend: {
            orm: 'prisma',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Creating a Data Model');
    expect(result).toContain('### Step 1: Define the Model');
    expect(result).toContain('backend/prisma/schema.prisma');
    expect(result).toContain('model Task');
    expect(result).toContain('### Step 2: Run Migration');
    expect(result).toContain('npx prisma migrate dev');
    expect(result).toContain('### Step 3: Use the Model');
    expect(result).toContain('prisma.task.findMany');
  });

  it('should generate relationship tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['add_relationship'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {},
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Adding Relationships Between Models');
    expect(result).toContain('### One-to-Many Example');
    expect(result).toContain('model User');
    expect(result).toContain('model Task');
    expect(result).toContain('tasks Task[]');
    expect(result).toContain('@relation');
  });

  it('should generate React integration tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['frontend_integration'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          frontend: {
            framework: 'react',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Connecting Frontend to Backend');
    expect(result).toContain('### Step 1: Create an API Client');
    expect(result).toContain('frontend/src/api/client.ts');
    expect(result).toContain('import.meta.env.VITE_API_URL');
    expect(result).toContain('### Step 2: Use in a Component');
    expect(result).toContain('useEffect');
    expect(result).toContain('fetchItems');
  });

  it('should generate testing tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['testing'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {},
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Writing Tests');
    expect(result).toContain('### Backend Tests');
    expect(result).toContain("import request from 'supertest'");
    expect(result).toContain('.expect(200)');
  });

  it('should generate deployment tutorial', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['deployment'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {},
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Deploying Your Application');
    expect(result).toContain('### Using Docker');
    expect(result).toContain('docker compose up -d');
  });

  it('should handle multiple topics', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['create_endpoint', 'add_authentication'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          backend: {
            language: 'typescript',
            framework: 'express',
          },
        },
        auth: {
          enabled: true,
          provider: 'clerk',
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    // Should contain both tutorials
    expect(result).toContain('## Creating Your First API Endpoint');
    expect(result).toContain('## Adding Authentication');
  });

  it('should generate tutorial with custom scope', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        scope: 'api',
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {
        technology: {
          backend: {
            language: 'typescript',
            framework: 'express',
          },
        },
      },
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('# Tutorial: Api');
    expect(result).toContain('## Creating Your First API Endpoint');
  });

  it('should handle unknown topics gracefully', () => {
    const context: TemplateContext = {
      intent: { type: 'tutorial', audience: 'developer', overwrite: 'always', includeExamples: false, includeCommonIssues: false,
        topics: ['unknown_topic'],
      },
      workflow: {
        workflow: {
          id: 'test-app',
          name: 'Test App',
          version: '1.0.0',
          description: 'Test',
        },
        stack: {},
      },
      extendedWorkflow: {},
      versions: {},
      outputDirectory: '/test',
    };

    const result = template.generate(context);

    expect(result).toContain('## Unknown topic');
    expect(result).toContain('Tutorial for unknown_topic coming soon');
  });
});
