"""Core functionality for processing markdown files and adding tags."""

from pathlib import Path
from typing import Tuple
import os
import frontmatter


def has_valid_frontmatter(content: str) -> bool:
    """Check if content has valid YAML frontmatter (starts and ends with ---)."""
    lines = content.splitlines()
    if not lines or not lines[0].strip() == "---":
        return False
    
    for i, line in enumerate(lines[1:], start=2):
        if line.strip() == "---":
            return True
    
    return False


def has_tags_in_frontmatter(content: str) -> bool:
    """Check if frontmatter contains a tags key."""
    if not has_valid_frontmatter(content):
        return False
    
    try:
        post = frontmatter.loads(content)
        return "tags" in post.metadata
    except Exception:
        return False


def get_frontmatter_and_content(content: str) -> Tuple[dict, str]:
    """Extract frontmatter as dict and remaining content."""
    try:
        post = frontmatter.loads(content)
        return post.metadata, post.content
    except Exception:
        return {}, content


def add_tags_to_file(
    filepath: Path, 
    tags: list[str], 
    only_untagged: bool,
    dry_run: bool = False
) -> Tuple[bool, str]:
    """
    Add tags to a markdown file's frontmatter.
    
    Args:
        filepath: Path to the markdown file
        tags: List of tags to add
        only_untagged: If True, skip files that already have tags
        dry_run: If True, don't actually modify the file
    
    Returns:
        Tuple of (was_modified: bool, status_message: str)
    """
    try:
        content = filepath.read_text(encoding='utf-8')
    except Exception as e:
        return False, f"ERROR (read failed): {filepath} - {str(e)}"
    
    if not content.strip():
        return False, f"SKIP (empty): {filepath}"
    
    has_frontmatter = has_valid_frontmatter(content)
    has_tags = has_tags_in_frontmatter(content)
    
    if only_untagged and has_tags:
        return False, f"SKIP (already has tags): {filepath}"
    
    if has_frontmatter:
        try:
            post = frontmatter.loads(content)
            existing_tags = post.metadata.get("tags", [])
            
            if not isinstance(existing_tags, list):
                existing_tags = [existing_tags] if existing_tags else []
            
            new_tags = [tag for tag in tags if tag not in existing_tags]
            
            if not new_tags:
                return False, f"SKIP (tags already present): {filepath}"
            
            post.metadata["tags"] = existing_tags + new_tags
            
            if not dry_run:
                output = frontmatter.dumps(post)
                output = output.replace('---\n\n', '---\n', 1)
                filepath.write_text(output, encoding='utf-8')
            
            action = "WOULD ADD" if dry_run else "ADDED"
            tags_str = ", ".join(new_tags)
            return True, f"{action} tags [{tags_str}] to frontmatter: {filepath}"
        except Exception as e:
            return False, f"ERROR (frontmatter parse failed): {filepath} - {str(e)}"
    else:
        if not dry_run:
            post = frontmatter.Post(content, tags=tags)
            output = frontmatter.dumps(post)
            output = output.replace('---\n\n', '---\n', 1)
            filepath.write_text(output, encoding='utf-8')
        
        action = "WOULD ADD" if dry_run else "ADDED"
        tags_str = ", ".join(tags)
        return True, f"{action} new frontmatter with tags [{tags_str}]: {filepath}"


def find_markdown_files(directory: Path, recursive: bool = True) -> list[Path]:
    """
    Find all markdown files in a directory.
    
    Args:
        directory: Directory to search
        recursive: If True, search recursively
    
    Returns:
        List of Path objects for markdown files
    """
    pattern = "**/*.md" if recursive else "*.md"
    files = []
    
    for filepath in directory.glob(pattern):
        if filepath.is_symlink():
            continue
        
        if not filepath.is_file():
            continue
        
        if not os.access(filepath, os.R_OK):
            continue
        
        if any(part.startswith('.') and part != '.' for part in filepath.parts):
            continue
        
        files.append(filepath)
    
    return sorted(files)
