from __future__ import annotations

import argparse
import logging
import sys

from blackout_notifier.clients import EitaaClient, SaapaClient
from blackout_notifier.config import Config, ConfigurationError
from blackout_notifier.models import tehran_now
from blackout_notifier.service import OutageService
from blackout_notifier.state import StateError, StateRepository


class ConsoleNotifier:
    def send(self, chat_id: str, text: str) -> None:
        print(f"\n--- notification preview for chat {chat_id} ---")
        print(text)


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="Check and announce planned power outages")
    subparsers = parser.add_subparsers(dest="command", required=True)
    check_parser = subparsers.add_parser("check", help="fetch and process planned outages")
    check_parser.add_argument(
        "--dry-run",
        action="store_true",
        help="print notifications without sending them or changing state",
    )
    return parser


def main(argv: list[str] | None = None) -> int:
    arguments = build_parser().parse_args(argv)
    logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")

    try:
        config = Config.from_env()
        state_repository = StateRepository(config.state_file)
        notifier = (
            ConsoleNotifier()
            if arguments.dry_run
            else EitaaClient(
                config.eitaayar_token,
                timeout=config.request_timeout_seconds,
            )
        )
        service = OutageService(
            bill_chat_ids=config.bill_chat_ids,
            lookahead_days=config.lookahead_days,
            saapa=SaapaClient(
                config.bargheman_token,
                timeout=config.request_timeout_seconds,
                max_events_per_bill=config.max_events_per_bill,
            ),
            notifier=notifier,
            state_repository=state_repository,
        )
        result = service.run(tehran_now(), persist=not arguments.dry_run)
    except (ConfigurationError, StateError) as error:
        print(f"Configuration/state error: {error}", file=sys.stderr)
        return 2

    print(
        f"Check complete: sent={result.sent}, state_changed={result.state_changed}, "
        f"errors={len(result.errors)}"
    )
    return 1 if result.errors else 0
