import json
from datetime import datetime
from typing import List

from .types import ParsedProject, FileInfo, ProjectStructure, ConversionOptions

class MarkdownConverter:
    def __init__(self, options: ConversionOptions = None):
        self.options = options or ConversionOptions()
    
    def convert_to_markdown(self, project: ParsedProject) -> str:
        """Convert parsed project to markdown"""
        sections = []
        
        # Header
        sections.append(self._generate_header(project))
        
        # Table of Contents
        sections.append(self._generate_table_of_contents(project))
        
        # Project Summary
        sections.append(self._generate_project_summary(project))
        
        # Project Structure
        sections.append(self._generate_project_structure(project.structure))
        
        # File Contents
        sections.append(self._generate_file_contents(project.files))
        
        # Footer
        sections.append(self._generate_footer())
        
        return '\n\n'.join(sections)
    
    def _generate_header(self, project: ParsedProject) -> str:
        """Generate markdown header"""
        project_name = project.structure.name
        return f"""# {project_name} - Codebase Documentation

> Generated by autoMarkdown - Intelligent codebase to markdown converter

---"""
    
    def _generate_table_of_contents(self, project: ParsedProject) -> str:
        """Generate table of contents"""
        lines = [
            '## Table of Contents',
            '',
            '- [Project Summary](#project-summary)',
            '- [Project Structure](#project-structure)',
            '- [File Contents](#file-contents)'
        ]
        
        # Add file links
        for i, file in enumerate(project.files):
            sanitized_path = self._sanitize_anchor(file.path)
            lines.append(f'  - [{file.path}](#file-{i + 1}-{sanitized_path})')
        
        return '\n'.join(lines)
    
    def _generate_project_summary(self, project: ParsedProject) -> str:
        """Generate project summary section"""
        languages = list(set(f.language for f in project.files))
        total_size = sum(f.size for f in project.files)
        top_files = [f.path for f in project.files[:5]]
        
        return f"""## Project Summary

{project.summary}

### Key Statistics
- **Total Files**: {len(project.files)}
- **Languages**: {', '.join(languages)}
- **Total Size**: {total_size / 1024:.2f} KB
- **Most Important Files**: {', '.join(top_files)}"""
    
    def _generate_project_structure(self, structure: ProjectStructure) -> str:
        """Generate project structure section"""
        return f"""## Project Structure

```
{self._render_structure_tree(structure)}
```"""
    
    def _render_structure_tree(self, structure: ProjectStructure, level: int = 0) -> str:
        """Render structure as tree"""
        indent = '  ' * level
        icon = '├──' if structure.type == 'directory' else '├──'
        result = f"{indent}{icon} {structure.name}\n"
        
        if structure.children:
            for child in structure.children:
                result += self._render_structure_tree(child, level + 1)
        
        return result
    
    def _generate_file_contents(self, files: List[FileInfo]) -> str:
        """Generate file contents section"""
        sections = ['## File Contents']
        
        for i, file in enumerate(files):
            sanitized_path = self._sanitize_anchor(file.path)
            file_section = [
                f'### File {i + 1}: `{file.path}`',
                f'<a id="file-{i + 1}-{sanitized_path}"></a>',
                '',
                self._generate_file_metadata(file),
                '',
                f'```{file.language}',
                file.content,
                '```'
            ]
            sections.append('\n'.join(file_section))
        
        return '\n\n'.join(sections)
    
    def _generate_file_metadata(self, file: FileInfo) -> str:
        """Generate file metadata"""
        if not self.options.include_metadata:
            return ''
        
        return f"**Language**: {file.language} | **Size**: {file.size} bytes | **Importance**: {file.importance:.1f}/10"
    
    def _generate_footer(self) -> str:
        """Generate markdown footer"""
        timestamp = datetime.now().isoformat()
        return f"""---

*Documentation generated on {timestamp} by [autoMarkdown](https://github.com/harshpreet931/autoMarkdown)*

**Tips for LLM Processing:**
- This markdown contains the complete codebase structure and content
- Files are ordered by importance (most important first)
- Use the table of contents for navigation
- Each file includes metadata for context
- The project structure shows the overall organization"""
    
    def _sanitize_anchor(self, text: str) -> str:
        """Sanitize text for use as anchor"""
        import re
        return re.sub(r'[^a-zA-Z0-9]', '-', text).lower()
    
    def convert_to_json(self, project: ParsedProject) -> str:
        """Convert project to JSON"""
        def convert_structure(struct: ProjectStructure) -> dict:
            result = {
                'name': struct.name,
                'type': struct.type,
                'path': struct.path
            }
            if struct.children:
                result['children'] = [convert_structure(child) for child in struct.children]
            return result
        
        data = {
            'files': [
                {
                    'path': f.path,
                    'content': f.content,
                    'language': f.language,
                    'size': f.size,
                    'importance': f.importance
                }
                for f in project.files
            ],
            'structure': convert_structure(project.structure),
            'summary': project.summary
        }
        
        return json.dumps(data, indent=2)