from __future__ import annotations

import argparse
import sys

from .config import load_config, load_env
from .table import print_table
from .task_catalog import (
    load_groups,
    load_tasks,
    print_task_list,
    task_by_number,
    task_by_selection,
    tasks_by_group_number,
    tasks_by_selection_group,
)
from .tasks.pla_settings_check import run_check_pla_settings
from .tasks.pla_cl1_sync import run_sync_pla_cl1
from .tasks.product_feed_optimization import (
    run_fill_product_unit_pricing,
    run_optimize_product_categories,
    run_optimize_product_feed,
    run_optimize_product_titles,
)


def choose_index(label: str, options: list[str]) -> int | None:
    print(f"\n{label}")
    for i, option in enumerate(options, 1):
        print(f"{i}. {option}")
    try:
        raw = input("Wybierz numer albo Enter aby wyjsc: ").strip()
    except EOFError:
        print()
        return None
    if not raw:
        return None
    try:
        idx = int(raw)
    except ValueError:
        print("Nieprawidlowy numer.")
        return None
    if idx < 1 or idx > len(options):
        print("Nieprawidlowy numer.")
        return None
    return idx - 1


def main() -> None:
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    parser = argparse.ArgumentParser(description="Google Ads ver 2")
    parser.add_argument(
        "command",
        nargs="?",
        choices=["analiza-klienta"],
        help="Tryb prowadzony etapami dla agenta lub terminala",
    )
    parser.add_argument("--client", help="Domena klienta z config/clients.toml")
    parser.add_argument("--client-number", type=int, help="Numer klienta z listy analiza-klienta")
    parser.add_argument(
        "--task",
        choices=[
            "sync_pla_cl1",
            "check_pla_settings",
            "optimize_product_feed",
            "optimize_product_titles",
            "optimize_product_categories",
            "fill_product_unit_pricing",
        ],
        help="Zadanie do uruchomienia bez menu",
    )
    parser.add_argument("--select", help="Wybór z listy zadan, np. 1.1, 1.0 albo ALL")
    parser.add_argument("--task-number", type=int, help="Numer zadania z listy analiza-klienta")
    parser.add_argument("--group-number", type=int, help="Uruchom wszystkie zadania z grupy o podanym numerze")
    parser.add_argument("--group-all-current", action="store_true", help="Uruchom wszystkie zadania z pierwszej widocznej grupy")
    parser.add_argument("--all-groups", action="store_true", help="Uruchom wszystkie zadania ze wszystkich grup")
    parser.add_argument("--plan-only", action="store_true", help="Tylko przygotuj plan i zapisz go do pliku")
    parser.add_argument("--apply-plan", help="Wdroz zapisany plan JSON")
    parser.add_argument(
        "--confirm-apply",
        help="Wymagane przy --apply-plan. Uzyj dokladnie: TAK",
    )
    args = parser.parse_args()

    load_env()
    try:
        cfg = load_config()
    except Exception as exc:
        print(exc)
        sys.exit(1)

    domains = sorted(cfg.clients)
    if not domains:
        print("Brak klientow w config/clients.toml.")
        return

    tasks = load_tasks()
    groups = load_groups()
    selected_domain = args.client
    if args.client_number:
        if args.client_number < 1 or args.client_number > len(domains):
            print(f"Nie ma klienta numer {args.client_number}.")
            return
        selected_domain = domains[args.client_number - 1]

    if args.command == "analiza-klienta":
        if not selected_domain:
            print("\nWybierz klienta:")
            print_table(["Nr", "Domena"], [[str(i), domain] for i, domain in enumerate(domains, 1)])
            print("\nNastepny krok:")
            print("python gads.py analiza-klienta --client-number <numer>")
            return

        if selected_domain not in cfg.clients:
            print(f"Nie znaleziono klienta {selected_domain} w config/clients.toml.")
            return

        if not args.select and not args.task_number and not args.group_number and not args.group_all_current and not args.all_groups:
            print(f"\nKlient: {selected_domain}")
            print_task_list(tasks)
            print("\nNastepny krok:")
            print(
                "python gads.py analiza-klienta "
                f"--client-number {domains.index(selected_domain) + 1} "
                "--select <nr> --plan-only"
            )
            return

        if args.select:
            selected = args.select.strip()
            if selected.upper() == "ALL":
                run_task_sequence(
                    tasks,
                    cfg.clients[selected_domain],
                    cfg.global_rules,
                    plan_only=args.plan_only,
                )
                return
            selected_group_tasks = tasks_by_selection_group(tasks, groups, selected)
            if selected_group_tasks:
                run_task_sequence(
                    selected_group_tasks,
                    cfg.clients[selected_domain],
                    cfg.global_rules,
                    plan_only=args.plan_only,
                )
                return
            selected_task = task_by_selection(tasks, selected)
            if not selected_task:
                print(f"Nie ma wyboru {selected}.")
                return
            run_task(
                selected_task.id,
                cfg.clients[selected_domain],
                cfg.global_rules,
                plan_only=args.plan_only,
                apply_plan_path=args.apply_plan,
                confirm_apply=args.confirm_apply,
            )
            return

        if args.group_all_current:
            first_group_number = groups[0].number if groups else None
            selected_tasks = tasks_by_group_number(tasks, groups, first_group_number) if first_group_number else []
            if not selected_tasks:
                print("Brak zadan w pierwszej grupie.")
                return
            run_task_sequence(
                selected_tasks,
                cfg.clients[selected_domain],
                cfg.global_rules,
                plan_only=args.plan_only,
            )
            return

        if args.group_number:
            selected_tasks = tasks_by_group_number(tasks, groups, args.group_number)
            if not selected_tasks:
                print(f"Nie ma grupy numer {args.group_number}.")
                return
            run_task_sequence(
                selected_tasks,
                cfg.clients[selected_domain],
                cfg.global_rules,
                plan_only=args.plan_only,
            )
            return

        if args.all_groups:
            run_task_sequence(
                tasks,
                cfg.clients[selected_domain],
                cfg.global_rules,
                plan_only=args.plan_only,
            )
            return

        selected_task = task_by_number(tasks, args.task_number)
        if not selected_task:
            print(f"Nie ma zadania numer {args.task_number}.")
            return
        run_task(
            selected_task.id,
            cfg.clients[selected_domain],
            cfg.global_rules,
            plan_only=args.plan_only,
            apply_plan_path=args.apply_plan,
            confirm_apply=args.confirm_apply,
        )
        return

    if args.client or args.task:
        if not args.client or not args.task:
            print("Dla trybu bez menu podaj jednoczesnie --client i --task.")
            return
        if args.client not in cfg.clients:
            print(f"Nie znaleziono klienta {args.client} w config/clients.toml.")
            return
        run_task(
            args.task,
            cfg.clients[args.client],
            cfg.global_rules,
            plan_only=args.plan_only,
            apply_plan_path=args.apply_plan,
            confirm_apply=args.confirm_apply,
        )
        return

    client_idx = choose_index("Klient", domains)
    if client_idx is None:
        return
    client = cfg.clients[domains[client_idx]]

    task_labels = [task.name for task in tasks]
    task_idx = choose_index("Zadanie", task_labels)
    if task_idx is None:
        return

    run_task(tasks[task_idx].id, client, cfg.global_rules)


def run_task(
    task_id,
    client,
    global_rules,
    plan_only: bool = False,
    apply_plan_path: str | None = None,
    confirm_apply: str | None = None,
    show_navigation: bool = True,
) -> None:
    if task_id == "sync_pla_cl1":
        run_sync_pla_cl1(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    if task_id == "check_pla_settings":
        run_check_pla_settings(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    if task_id == "optimize_product_feed":
        run_optimize_product_feed(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    if task_id == "optimize_product_titles":
        run_optimize_product_titles(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    if task_id == "optimize_product_categories":
        run_optimize_product_categories(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    if task_id == "fill_product_unit_pricing":
        run_fill_product_unit_pricing(
            client,
            global_rules,
            plan_only=plan_only,
            apply_plan_path=apply_plan_path,
            confirm_apply=confirm_apply,
            show_navigation=show_navigation,
        )
        return
    print(f"Zadanie {task_id} nie ma jeszcze implementacji.")


def run_task_sequence(tasks, client, global_rules, plan_only: bool = False) -> None:
    total = len(tasks)
    if plan_only:
        print("Tryb zbiorczy plan-only przygotuje plany po kolei.")
        print("Agent powinien analizowac i wdrazac kazdy plan osobno, przed przejsciem do kolejnego zadania.")
    for index, task in enumerate(tasks, 1):
        print()
        print("#" * 72)
        print(f"Zadanie {index}/{total}: {task.group_name} / {task.name}")
        print("#" * 72)
        run_task(task.id, client, global_rules, plan_only=plan_only, show_navigation=False)
    print()
    print("Zakonczono sekwencje zadan.")
    print_sequence_navigation(client.domain)


def print_sequence_navigation(domain: str) -> None:
    print("\nCo dalej:")
    print(f"1. Lista zadan klienta {domain}")
    print("2. Lista klientow")
    print("3. Zakoncz")
    print("\nKomendy:")
    print(f"1 -> python gads.py analiza-klienta --client {domain}")
    print("2 -> python gads.py analiza-klienta")


def print_next_navigation(client_number: int | None = None) -> None:
    print("\nCo dalej:")
    if client_number:
        print(f"1. Lista zadan klienta numer {client_number}")
        print("2. Lista klientow")
        print("3. Zakoncz")
        print("\nKomendy:")
        print(f"1 -> python gads.py analiza-klienta --client-number {client_number}")
        print("2 -> python gads.py analiza-klienta")
    else:
        print("1. Lista klientow")
        print("2. Zakoncz")
        print("\nKomendy:")
        print("1 -> python gads.py analiza-klienta")
