import datetime
from pathlib import Path
from typing import Any

from jinja2 import BaseLoader, Environment, select_autoescape

# Embedded HTML Template for the gallery
INDEX_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Index of {{ folder_name }}</title>
    <style>
        :root {
            --bg-color: #f8fafc;
            --container-bg: #ffffff;
            --text-main: #1e293b;
            --text-muted: #64748b;
            --border-color: #e2e8f0;
            --hover-bg: #f1f5f9;
            --accent: #3b82f6;
        }

        @media (prefers-color-scheme: dark) {
            :root {
                --bg-color: #0f172a;
                --container-bg: #1e293b;
                --text-main: #f8fafc;
                --text-muted: #94a3b8;
                --border-color: #334155;
                --hover-bg: #334155;
                --accent: #60a5fa;
            }
        }

        body {
            font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-main);
            margin: 0;
            padding: 2rem;
            line-height: 1.5;
        }

        .container {
            max-width: 1000px;
            margin: 0 auto;
            background: var(--container-bg);
            border-radius: 12px;
            box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
            overflow: hidden;
            border: 1px solid var(--border-color);
        }

        .header {
            padding: 1.5rem 2rem;
            border-bottom: 1px solid var(--border-color);
            background: var(--container-bg);
        }

        .header h1 {
            margin: 0;
            font-size: 1.5rem;
            font-weight: 600;
        }

        .header p {
            margin: 0.5rem 0 0 0;
            color: var(--text-muted);
            font-size: 0.875rem;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            text-align: left;
        }

        th, td {
            padding: 1rem 2rem;
            border-bottom: 1px solid var(--border-color);
        }

        th {
            font-weight: 600;
            color: var(--text-muted);
            font-size: 0.875rem;
            text-transform: uppercase;
            letter-spacing: 0.05em;
        }

        tr:last-child td {
            border-bottom: none;
        }

        tr:hover td {
            background-color: var(--hover-bg);
        }

        a {
            color: var(--accent);
            text-decoration: none;
            display: flex;
            align-items: center;
            gap: 0.75rem;
            font-weight: 500;
        }

        a:hover {
            text-decoration: underline;
        }

        .icon {
            font-size: 1.25rem;
            opacity: 0.9;
        }

        .meta {
            color: var(--text-muted);
            font-size: 0.875rem;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>Index of {{ folder_name }}</h1>
            <p>Generated by ShotX on {{ generation_time }} • {{ total_files }} files, {{ total_size }}</p>
        </div>
        <table>
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Size</th>
                    <th>Last Modified</th>
                </tr>
            </thead>
            <tbody>
                {% if parent_dir %}
                <tr>
                    <td><a href="../"><span class="icon">📁</span> ..</a></td>
                    <td class="meta">-</td>
                    <td class="meta">-</td>
                </tr>
                {% endif %}
                {% for file in files %}
                <tr>
                    <td>
                        <a href="{{ file.name }}">
                            <span class="icon">{{ file.icon }}</span>
                            {{ file.name }}
                        </a>
                    </td>
                    <td class="meta">{{ file.formatted_size }}</td>
                    <td class="meta">{{ file.modified_date }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
</body>
</html>
"""

def format_bytes(size: int) -> str:
    """Format bytes to human readable string."""
    f_size = float(size)
    for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
        if f_size < 1024.0:
            return f"{f_size:.1f} {unit}" if unit != 'B' else f"{int(f_size)} {unit}"
        f_size /= 1024.0
    return f"{f_size:.1f} PB"

def _get_icon_for_file(filepath: Path) -> str:
    """Return a simple emoji icon based on file extension."""
    if filepath.is_dir():
        return "📁"

    ext = filepath.suffix.lower()

    image_exts = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'}
    code_exts = {'.py', '.js', '.ts', '.html', '.css', '.json', '.yaml', '.yml', '.md', '.sh'}
    video_exts = {'.mp4', '.mkv', '.webm', '.avi', '.mov'}
    audio_exts = {'.mp3', '.wav', '.ogg', '.flac'}
    archive_exts = {'.zip', '.tar', '.gz', '.7z', '.rar'}
    document_exts = {'.pdf', '.doc', '.docx', '.txt'}

    if ext in image_exts:
        return "🖼️"
    elif ext in code_exts:
        return "📄"
    elif ext in video_exts:
        return "🎬"
    elif ext in audio_exts:
        return "🎵"
    elif ext in archive_exts:
        return "📦"
    elif ext in document_exts:
        return "📝"

    return "📄"

def generate_directory_index(target_path: str | Path) -> Path:
    """
    Generates an HTML index for the specified directory.
    Returns the path to the generated index.html file.
    """
    target = Path(target_path).resolve()

    if not target.is_dir():
        raise NotADirectoryError(f"Target path does not exist or is not a directory: {target}")

    # Gather file metadata
    file_list: list[dict[str, Any]] = []
    total_bytes = 0
    total_files = 0

    # Pre-sort: directories first, then files alphabetically
    items = sorted(target.iterdir(), key=lambda x: (not x.is_dir(), x.name.lower()))

    for item in items:
        # Skip the index.html we might be overwriting, and hidden files/folders
        if item.name == "index.html" or item.name.startswith('.'):
            continue

        stat = item.stat()
        size = stat.st_size if item.is_file() else 0

        if item.is_file():
            total_bytes += size
            total_files += 1

        mod_time = datetime.datetime.fromtimestamp(stat.st_mtime)

        file_list.append({
            "name": item.name + ("/" if item.is_dir() else ""),
            "path": item.name,
            "is_dir": item.is_dir(),
            "size": size,
            "formatted_size": format_bytes(size) if item.is_file() else "-",
            "modified_date": mod_time.strftime("%Y-%m-%d %H:%M:%S"),
            "icon": _get_icon_for_file(item)
        })

    # Prepare Jinja Template
    env = Environment(loader=BaseLoader(), autoescape=select_autoescape(['html', 'xml']))
    template = env.from_string(INDEX_TEMPLATE)

    # Render
    html_content = template.render(
        folder_name=target.name,
        generation_time=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        total_files=total_files,
        total_size=format_bytes(total_bytes),
        parent_dir=True, # We'll just always assume a parent dir link is useful for navigation
        files=file_list
    )

    # Write to target directory
    output_path = target / "index.html"
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(html_content)

    return output_path
