#!/usr/bin/env python3

"""
wittrans

A command-line tool to search for translated strings and source messages in localization files used by Linux distributions.

Website: https://codeberg.org/artnay/wittrans

SPDX-FileCopyrightText: 2024 Jiri Grönroos <jiri.gronroos@iki.fi>

SPDX-License-Identifier: LGPL-3.0-or-later
"""

import multiprocessing
import sys
import time

from rich.console import Console
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn

from .cli import parse_arguments
from .exceptions import InvalidLanguageCode, TranslationDirectoryNotFound
from .language import get_language_name
from .models import SearchStatistics
from .output import (
    display_results,
    display_search_summary,
    write_tsv_output,
)
from .paths import validate_language_paths
from .search import search_directory
from .system import check_platform


def main() -> None:
    """Main function to run the translation search."""
    console = Console()
    check_platform()

    try:
        # Parse command line arguments
        args = parse_arguments()

        search_term = args.search_term
        lang_code = args.language_code.lower()

        # Validate language code and get existing paths for all translation sources
        translation_paths = validate_language_paths(
            lang_code, include_flatpak=not args.no_flatpak
        )

        # Track statistics
        total_directories_searched = 0
        total_mo_files_found = 0
        search_start_time = time.time()

        with (
            Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                transient=True,
            ) as progress,
            multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool,
        ):
            # Search all translation categories
            results_by_category = {}

            # Define category mapping for display purposes
            categories = [
                ("system_locale", "System Locale"),
                ("user_locale", "User Locale"),
                ("system_gnome_extensions", "System GNOME Extensions"),
                ("system_kde_plasmoids", "System KDE Plasmoids"),
                ("user_gnome_extensions", "User GNOME Extensions"),
                ("user_kde_plasmoids", "User KDE Plasmoids"),
                ("system_flatpak", "System Flatpak"),
                ("user_flatpak", "User Flatpak"),
            ]

            for category_key, display_name in categories:
                category_paths = getattr(translation_paths, category_key)
                category_results = []
                category_mo_files = 0

                for path in category_paths:
                    results, mo_file_count = search_directory(
                        path,
                        search_term,
                        progress,
                        search_source=not args.translation,
                        search_translation=not args.source,
                        whole_word=args.whole_word,
                        pool=pool,
                    )
                    category_results.extend(results)
                    category_mo_files += mo_file_count

                # Count directories searched (paths that exist)
                directories_in_category = len(category_paths)
                total_directories_searched += directories_in_category
                total_mo_files_found += category_mo_files

                results_by_category[category_key] = {
                    "results": category_results,
                    "display_name": display_name,
                    "has_paths": len(category_paths) > 0,
                    "directories_searched": directories_in_category,
                    "mo_files_found": category_mo_files,
                }

        # Search duration for statistics
        search_end_time = time.time()
        search_duration = search_end_time - search_start_time

        # Calculate total matches
        total_matches = sum(
            len(matches)
            for category_data in results_by_category.values()
            for _, matches in category_data["results"]
        )

        # Create search statistics
        search_stats = SearchStatistics(
            directories_searched=total_directories_searched,
            mo_files_found=total_mo_files_found,
            total_matches=total_matches,
            search_duration_seconds=search_duration,
        )

        # Handle output format
        if args.output == "tsv":
            # Generate output filename
            if args.output_file:
                output_filename = args.output_file
            else:
                safe_search_term = "".join(
                    c for c in search_term if c.isalnum() or c in (" ", "-", "_")
                ).strip()
                safe_search_term = safe_search_term.replace(" ", "_")[:20]
                output_filename = f"{safe_search_term}_{lang_code}.tsv"

            # Write TSV output
            write_tsv_output(
                results_by_category,
                search_term,
                lang_code,
                output_filename,
                search_stats,
            )

            language_name = get_language_name(lang_code)

            # Message depending on results
            if total_matches == 0:
                console.print(
                    f"[green]Empty results written to:[/green] {output_filename}"
                )
            else:
                console.print(f"[green]Results written to:[/green] {output_filename}")

            # Show statistics
            console.print(
                f"[green]Searched {search_stats.directories_searched} "
                f"{'directory' if search_stats.directories_searched == 1 else 'directories'}, "
                f"found {search_stats.mo_files_found} .mo "
                f"{'file' if search_stats.mo_files_found == 1 else 'files'} "
                f"in {language_name}, "
                f"total matches: {search_stats.total_matches} "
                f"({search_stats.search_duration_seconds:.2f}s)[/green]"
            )

            sys.exit(0)

        # Console output (no TSV)
        if total_matches == 0:
            language_name = get_language_name(lang_code)

            # Statistics message
            stats_msg = (
                f"Searched {search_stats.directories_searched} "
                f"{'directory' if search_stats.directories_searched == 1 else 'directories'}, "
                f"found {search_stats.mo_files_found} .mo "
                f"{'file' if search_stats.mo_files_found == 1 else 'files'} "
                f"in {language_name} "
                f"in {search_stats.search_duration_seconds:.2f}s"
            )

            console.print(
                Panel(
                    f"[yellow]No matches found for:[/yellow] [bold red]'{search_term}'[/bold red] "
                    f"in {language_name} translations\n"
                    f"[dim]{stats_msg}[/dim]",
                    title="Search Results",
                    border_style="yellow",
                )
            )
            sys.exit(0)

        # Display results in console by category
        first_section = True
        for category_key, display_name in categories:
            category_data = results_by_category[category_key]

            # Only display categories that have results or paths
            if category_data["results"] or category_data["has_paths"]:
                if not first_section:
                    console.print("\n")

                display_results(
                    category_data["results"],
                    search_term,
                    lang_code,
                    display_name,
                    args.indicate,
                    category_data["directories_searched"],
                    category_data["mo_files_found"],
                )
                first_section = False

        display_search_summary(search_term, search_stats, lang_code)

    except TranslationDirectoryNotFound as e:
        console.print(
            Panel(
                str(e),
                title="[red]Error: Translation Directory Not Found[/red]",
                border_style="red",
            )
        )
        sys.exit(1)
    except InvalidLanguageCode as e:
        console.print(
            Panel(
                str(e),
                title="[red]Error: Invalid Language Code[/red]",
                border_style="red",
            )
        )
        sys.exit(1)
    except KeyboardInterrupt:
        console.print("\n[yellow]Search cancelled by user[/yellow]")
        sys.exit(0)
    except Exception as e:
        console.print(
            Panel(
                f"An unexpected error occurred: {str(e)}",
                title="[red]Error[/red]",
                border_style="red",
            )
        )
        sys.exit(1)


if __name__ == "__main__":
    main()
