package extractor

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/tanagram/cli/llm"
	"github.com/tanagram/cli/parser"
)

// ExtractedPolicy represents a policy extracted by the LLM
// Simplified: No types or patterns, all enforcement is LLM-based
type ExtractedPolicy struct {
	Name         string `json:"name"`
	Message      string `json:"message"`
	OriginalText string `json:"original_text"`
}

// ExtractorResponse represents the JSON response from the LLM
type ExtractorResponse struct {
	Policies []ExtractedPolicy `json:"policies"`
}

// ExtractPolicies uses LLM to extract policies from instruction file content
func ExtractPolicies(ctx context.Context, content string) ([]parser.Policy, error) {
	client, err := llm.NewClient()
	if err != nil {
		return nil, err
	}

	prompt := buildExtractionPrompt(content)

	response, err := client.SendMessage(ctx, prompt)
	if err != nil {
		return nil, fmt.Errorf("failed to extract policies: %w", err)
	}

	// Strip markdown code blocks if present
	cleanedResponse := llm.StripMarkdownCodeBlocks(response)

	// Parse JSON response
	var extractorResponse ExtractorResponse
	if err := json.Unmarshal([]byte(cleanedResponse), &extractorResponse); err != nil {
		return nil, fmt.Errorf("failed to parse LLM response: %w\nResponse: %s", err, response)
	}

	// Convert to parser.Policy format
	policies := make([]parser.Policy, 0, len(extractorResponse.Policies))
	for _, ep := range extractorResponse.Policies {
		policies = append(policies, parser.Policy{
			Name:         ep.Name,
			Message:      ep.Message,
			OriginalText: ep.OriginalText,
		})
	}

	return policies, nil
}

// buildExtractionPrompt creates the prompt for policy extraction
func buildExtractionPrompt(content string) string {
	return fmt.Sprintf(`You are a code policy extraction system. Extract ONLY policies that define anti-patterns or bad practices that can be detected by reading code.

IMPORTANT: Extract policies about what the CODE should or shouldn't look like. DO NOT extract policies that require running commands, executing tools, or performing actions.

Extract policies that define CODE ANTI-PATTERNS:
- Code structure and organization anti-patterns (e.g., "Don't use deeply nested functions")
- Coding standards violations (e.g., "Don't use var, use let/const")
- Language-specific anti-patterns (e.g., "Don't use 'any' type in TypeScript")
- Prohibited code patterns (e.g., "Don't hardcode API keys")
- Security anti-patterns in code (e.g., "Don't use eval()")
- Error handling anti-patterns (e.g., "Don't swallow exceptions silently")
- Import/dependency anti-patterns (e.g., "Don't import entire lodash library")

DO NOT extract policies that require ACTIONS or COMMANDS:
- Running tests (e.g., "Run pytest before committing")
- Running linters or formatters (e.g., "Run black on all Python files")
- Building or compiling (e.g., "Build the project to verify")
- Running scripts or commands (e.g., "Execute database migrations")
- Using specific tools (e.g., "Use ruff format" - this requires running ruff)
- Agent behavior instructions (how AI agents should operate)
- Workflow or process instructions
- Communication style guidelines
- Project management policies

CRITICAL: If a policy would require the agent to run a command or tool to fix a violation, DO NOT extract it. Only extract policies about code patterns that can be fixed by editing code directly.

For each code anti-pattern policy, provide:
1. Name: Short descriptive name (2-5 words)
2. Message: The full policy text or a clear summary
3. OriginalText: The exact text from the file

Return ONLY valid JSON (no markdown, no backticks, no code fences):
{
  "policies": [
    {
      "name": "Short policy name",
      "message": "Clear policy description",
      "original_text": "Original text from file"
    }
  ]
}

Instruction File Content:
%s

Remember: Return ONLY the JSON object, no other text, no markdown formatting.`, content)
}


