"""
GitHub Actions Workflow Templates

Provides ready-to-use workflow templates for integrating groknroll
with GitHub Actions.

Examples:
    # Generate workflow YAML
    workflow = generate_workflow_yaml()
    print(workflow)

    # Generate with custom config
    config = WorkflowConfig(
        trigger_phrase="/groknroll",
        default_agent="build",
    )
    workflow = generate_workflow_yaml(config)

    # Get workflow file
    content = get_workflow_content()
"""

from dataclasses import dataclass
from pathlib import Path
from typing import Optional


@dataclass
class WorkflowConfig:
    """Configuration for workflow generation"""

    # Trigger settings
    trigger_phrase: str = "/groknroll"
    alternate_trigger: str = "/gknr"

    # Agent settings
    default_agent: str = "build"
    allow_agent_override: bool = True

    # Execution settings
    timeout_minutes: int = 30
    runs_on: str = "ubuntu-latest"

    # Authentication
    api_key_secret: str = "GROKNROLL_API_KEY"
    openai_key_secret: str = "OPENAI_API_KEY"
    anthropic_key_secret: str = "ANTHROPIC_API_KEY"

    # Features
    enable_issue_comments: bool = True
    enable_pr_comments: bool = True
    enable_new_issues: bool = False
    enable_new_prs: bool = False

    # Output settings
    post_reply_comment: bool = True
    create_pr_on_changes: bool = True


@dataclass
class WorkflowTemplate:
    """A workflow template"""

    name: str
    description: str
    content: str
    filename: str = ".github/workflows/groknroll.yml"
    setup_instructions: str = ""


# Main workflow template
# Note: Line length violations are intentional in this YAML template
ISSUE_COMMENT_WORKFLOW = r'''name: groknroll

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  groknroll:
    # Only run if comment contains trigger phrase
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '{trigger}')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '{trigger}'))
    runs-on: {runs_on}
    timeout-minutes: {timeout}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install groknroll
        run: |
          pip install groknroll

      - name: Extract command from comment
        id: extract
        run: |
          # Extract the task from the comment
          COMMENT_BODY="${{{{ github.event.comment.body }}}}"
          # Find the trigger and extract the rest as task
          TASK=$(echo "$COMMENT_BODY" | grep -oP '(?<={trigger}\\s).*' | head -1)
          echo "task=$TASK" >> $GITHUB_OUTPUT

          # Check for agent override
          if echo "$TASK" | grep -q '\\-\\-agent'; then
            AGENT=$(echo "$TASK" | grep -oP '(?<=--agent\\s)\\w+')
            TASK=$(echo "$TASK" | sed 's/--agent\\s*\\w*//g' | xargs)
            echo "agent=$AGENT" >> $GITHUB_OUTPUT
          else
            echo "agent={default_agent}" >> $GITHUB_OUTPUT
          fi

      - name: Run groknroll
        env:
          OPENAI_API_KEY: ${{{{ secrets.{openai_secret} }}}}
          ANTHROPIC_API_KEY: ${{{{ secrets.{anthropic_secret} }}}}
          GITHUB_TOKEN: ${{{{ secrets.GITHUB_TOKEN }}}}
        run: |
          groknroll ${{{{ steps.extract.outputs.agent }}}} "${{{{ steps.extract.outputs.task }}}}"

      - name: Post result comment
        if: always()
        uses: actions/github-script@v7
        with:
          script: |
            const issue_number = context.issue.number;
            const run_url = `${{{{github.server_url}}}}/${{{{github.repository}}}}/actions/runs/${{{{github.run_id}}}}`;

            let body = '';
            if ('${{{{ job.status }}}}' === 'success') {{
              body = `### groknroll completed successfully\\n\\nTask: \`${{{{ steps.extract.outputs.task }}}}\`\\nAgent: \`${{{{ steps.extract.outputs.agent }}}}\`\\n\\n[View run details](${{run_url}})`;
            }} else {{
              body = `### groknroll encountered an error\\n\\nTask: \`${{{{ steps.extract.outputs.task }}}}\`\\n\\n[View run details](${{run_url}})`;
            }}

            await github.rest.issues.createComment({{
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue_number,
              body: body
            }});
'''


# Minimal workflow template
MINIMAL_WORKFLOW = '''name: groknroll

on:
  issue_comment:
    types: [created]

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  groknroll:
    if: contains(github.event.comment.body, '/groknroll')
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install and run groknroll
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          pip install groknroll
          TASK=$(echo "${{ github.event.comment.body }}" | grep -oP '(?<=/groknroll\\s).*')
          groknroll build "$TASK"
'''


# Setup instructions
SETUP_INSTRUCTIONS = '''# Setting up groknroll GitHub Integration

## Quick Start

1. **Add the workflow file**
   Copy the workflow YAML to `.github/workflows/groknroll.yml` in your repository.

2. **Configure secrets**
   Go to your repository's Settings > Secrets and variables > Actions and add:
   - `OPENAI_API_KEY`: Your OpenAI API key
   - `ANTHROPIC_API_KEY`: Your Anthropic API key (optional)

3. **Test it out**
   Create an issue and add a comment:
   ```
   /groknroll fix the typo in README.md
   ```

## Usage

### Basic usage
```
/groknroll <task description>
```

### With specific agent
```
/groknroll --agent plan review this code for security issues
```

### Available agents
- `build`: Full access agent (default) - can read, write, and execute
- `plan`: Read-only agent - analyzes and plans without making changes

## Customization

### Trigger phrases
By default, the workflow triggers on `/groknroll` or `/gknr`.

### Permissions
The workflow needs these permissions:
- `contents: write` - to push code changes
- `issues: write` - to post comments
- `pull-requests: write` - to create PRs

## Troubleshooting

### Workflow not triggering
- Ensure the comment contains the exact trigger phrase
- Check that the workflow file is in the default branch
- Verify the workflow has the correct permissions

### API key errors
- Verify secrets are configured correctly
- Check that the secret names match the workflow

### Timeout errors
- Increase `timeout-minutes` in the workflow
- Consider breaking down large tasks
'''


def generate_workflow_yaml(config: Optional[WorkflowConfig] = None) -> str:
    """
    Generate workflow YAML content

    Args:
        config: Optional configuration

    Returns:
        Workflow YAML string
    """
    if config is None:
        config = WorkflowConfig()

    return ISSUE_COMMENT_WORKFLOW.format(
        trigger=config.trigger_phrase,
        runs_on=config.runs_on,
        timeout=config.timeout_minutes,
        default_agent=config.default_agent,
        openai_secret=config.openai_key_secret,
        anthropic_secret=config.anthropic_key_secret,
    )


def get_minimal_workflow() -> str:
    """
    Get minimal workflow template

    Returns:
        Minimal workflow YAML
    """
    return MINIMAL_WORKFLOW


def get_setup_instructions() -> str:
    """
    Get setup instructions

    Returns:
        Setup instructions markdown
    """
    return SETUP_INSTRUCTIONS


def get_workflow_template(
    config: Optional[WorkflowConfig] = None,
) -> WorkflowTemplate:
    """
    Get complete workflow template

    Args:
        config: Optional configuration

    Returns:
        WorkflowTemplate with all content
    """
    return WorkflowTemplate(
        name="groknroll",
        description="AI-powered coding assistant that responds to issue and PR comments",
        content=generate_workflow_yaml(config),
        filename=".github/workflows/groknroll.yml",
        setup_instructions=SETUP_INSTRUCTIONS,
    )


def write_workflow_file(
    output_dir: Path,
    config: Optional[WorkflowConfig] = None,
    create_dirs: bool = True,
) -> Path:
    """
    Write workflow file to disk

    Args:
        output_dir: Base directory (usually repo root)
        config: Optional configuration
        create_dirs: Create .github/workflows if needed

    Returns:
        Path to written file
    """
    workflow_dir = output_dir / ".github" / "workflows"

    if create_dirs:
        workflow_dir.mkdir(parents=True, exist_ok=True)

    workflow_path = workflow_dir / "groknroll.yml"
    content = generate_workflow_yaml(config)

    workflow_path.write_text(content)
    return workflow_path


def validate_workflow_config(config: WorkflowConfig) -> list[str]:
    """
    Validate workflow configuration

    Args:
        config: Configuration to validate

    Returns:
        List of validation errors (empty if valid)
    """
    errors = []

    if not config.trigger_phrase:
        errors.append("trigger_phrase is required")

    if not config.trigger_phrase.startswith("/"):
        errors.append("trigger_phrase should start with /")

    if config.default_agent not in ("build", "plan"):
        errors.append(f"Invalid default_agent: {config.default_agent}")

    if config.timeout_minutes < 1:
        errors.append("timeout_minutes must be at least 1")

    if config.timeout_minutes > 360:
        errors.append("timeout_minutes cannot exceed 360 (6 hours)")

    return errors
