"""Info command implementation."""

import json
from argparse import ArgumentParser, Namespace
from pathlib import Path

from .. import reader
from ..metadata import header_to_toml
from .base import BaseCommand, CommandError


class InfoCommand(BaseCommand):
    """Command to display dictionary information."""

    @property
    def help_text(self) -> str:
        return "Display dictionary information and metadata"

    def add_arguments(self, parser: ArgumentParser) -> None:
        """Add info command arguments."""
        parser.add_argument("file", help="Dictionary file (MDX/MDD/DB)")
        parser.add_argument(
            "--format", choices=["text", "json", "toml"], default="text", help="Output format (default: text)"
        )
        parser.add_argument(
            "-o", "--output", dest="output_file", metavar="FILE", help="Output to file instead of stdout"
        )
        parser.add_argument("--substyle", action="store_true", help="Use substyle when reading")
        parser.add_argument("--passcode", metavar="CODE", help="Passcode for encrypted dictionaries")

    def execute(self, args: Namespace) -> None:
        """Execute the info command."""
        dict_file = Path(args.file)
        if not dict_file.exists():
            raise CommandError(f"Dictionary file not found: {dict_file}")

        # Validate file type
        valid_extensions = [".mdx", ".mdd", ".db"]
        if dict_file.suffix.lower() not in valid_extensions:
            raise CommandError(f"Invalid file type: {dict_file.suffix}. Expected {', '.join(valid_extensions)}")

        try:
            # Get metadata
            meta_dict = reader.meta(str(dict_file), substyle=args.substyle, passcode=args.passcode)

            # Format output based on requested format
            if args.format == "json":
                output = self._format_json(meta_dict)
            elif args.format == "toml":
                output = self._format_toml(meta_dict)
            else:  # text
                output = self._format_text(meta_dict, dict_file.name)

            # Output result
            if args.output_file:
                output_path = Path(args.output_file)
                with open(output_path, "w", encoding="utf-8") as f:
                    f.write(output)
                print(f"✅ Info saved to {output_path}")
            else:
                print(output)

        except Exception as e:
            raise CommandError(f"Failed to read dictionary info: {e}") from e

    def _format_text(self, meta_dict: dict, filename: str) -> str:
        """Format metadata as human-readable text."""
        lines = [f"📚 Dictionary Information: {filename}", "=" * 50]

        # Basic information
        if "title" in meta_dict:
            lines.append(f"Title: {meta_dict['title']}")
        if "version" in meta_dict:
            lines.append(f"Version: {meta_dict['version']}")
        if "record" in meta_dict:
            record_count = meta_dict["record"]
            if isinstance(record_count, str) and record_count.isdigit():
                record_count = f"{int(record_count):,}"
            lines.append(f"Records: {record_count}")
        if "encoding" in meta_dict:
            lines.append(f"Encoding: {meta_dict['encoding']}")

        # Additional metadata
        skip_keys = {"title", "version", "record", "encoding"}
        other_info = []

        for key, value in meta_dict.items():
            if key.lower() not in skip_keys:
                # Format key name
                display_key = key.replace("_", " ").title()
                if key.lower() == "creationdate":
                    display_key = "Creation Date"
                elif key.lower() == "generatedbyengineversion":
                    display_key = "Generated By Engine"
                elif key.lower() == "requiredengineversion":
                    display_key = "Required Engine"

                # Handle multi-line values (like description)
                if isinstance(value, str) and ("\n" in value or len(value) > 80):
                    other_info.append(f"{display_key}:")
                    for line in value.split("\n"):
                        other_info.append(f"  {line}")
                else:
                    other_info.append(f"{display_key}: {value}")

        if other_info:
            lines.extend(["", "Additional Information:"] + other_info)

        return "\n".join(lines)

    def _format_json(self, meta_dict: dict) -> str:
        """Format metadata as JSON."""
        return json.dumps(meta_dict, indent=2, ensure_ascii=False)

    def _format_toml(self, meta_dict: dict) -> str:
        """Format metadata as TOML."""
        try:
            # Convert meta_dict to header format for header_to_toml
            header_data = {}
            for key, value in meta_dict.items():
                if isinstance(value, str):
                    header_data[key.encode("utf-8")] = value.encode("utf-8")

            version = meta_dict.get("version", "2.0")
            toml_data = header_to_toml(header_data, version)

            # Convert to TOML string
            import io

            import tomli_w

            output = io.BytesIO()
            tomli_w.dump(toml_data, output)
            return output.getvalue().decode("utf-8")

        except Exception:
            # Fallback to simple format if conversion fails
            lines = ["# Dictionary Metadata", "[dictionary]"]
            for key, value in meta_dict.items():
                if isinstance(value, str) and "\n" in value:
                    # Multi-line string
                    lines.append(f'{key} = """')
                    lines.append(value)
                    lines.append('"""')
                else:
                    # Simple value
                    lines.append(f'{key} = "{value}"')

            return "\n".join(lines)
