"""Command-line entry point for the Dockerized HACCP generator."""

from __future__ import annotations

import argparse
import logging

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger

from .config import AppConfig
from .generator import HaccpGenerator, parse_date
from .google_client import GoogleWorkspaceClient
from .workdays import HungaryWorkdayCalendar

LOGGER = logging.getLogger(__name__)


def build_generator() -> HaccpGenerator:
    """Create the configured generator and API clients."""

    config = AppConfig.from_env()
    google = GoogleWorkspaceClient(config.google_credentials)
    workdays = HungaryWorkdayCalendar()
    return HaccpGenerator(config=config, google=google, workdays=workdays)


def serve() -> None:
    """Run the long-lived scheduler inside Docker."""

    generator = build_generator()
    scheduler = BlockingScheduler(timezone=generator.timezone)
    scheduler.add_job(
        lambda: generator.run_daily("morning"),
        CronTrigger(hour=6, minute=50, timezone=generator.timezone),
        id="morning-haccp-update",
        name="Morning HACCP update",
        jitter=20 * 60,
        max_instances=1,
        coalesce=True,
    )
    scheduler.add_job(
        lambda: generator.run_daily("afternoon"),
        CronTrigger(hour=14, minute=50, timezone=generator.timezone),
        id="afternoon-haccp-update",
        name="Afternoon HACCP and cleaning update",
        jitter=20 * 60,
        max_instances=1,
        coalesce=True,
    )
    LOGGER.info("Scheduler started; jobs run around 07:00 and 15:00 Europe/Budapest")
    scheduler.start()


def backfill(start: str, end: str) -> None:
    """Run the one-shot historical generation command."""

    generator = build_generator()
    start_date = parse_date(start, generator.config.timezone)
    end_date = parse_date(end, generator.config.timezone)
    LOGGER.info("Starting backfill from %s through %s", start_date, end_date)
    generator.backfill(start=start_date, end=end_date)
    LOGGER.info("Backfill completed from %s through %s", start_date, end_date)


def run_once(slot: str) -> None:
    """Run one scheduled update immediately for operational testing."""

    generator = build_generator()
    if slot not in {"morning", "afternoon"}:
        raise ValueError("slot must be either 'morning' or 'afternoon'")
    generator.run_daily(slot)  # type: ignore[arg-type]


def fix_tabs() -> None:
    """Run one-shot tab cleanup and newest-first ordering."""

    generator = build_generator()
    generator.fix_tabs()
    LOGGER.info("Tab cleanup completed")


def parse_args() -> argparse.Namespace:
    """Parse service, backfill, and manual one-shot CLI commands."""

    parser = argparse.ArgumentParser(description="Generate HACCP Google Sheets")
    subparsers = parser.add_subparsers(dest="command")

    subparsers.add_parser("serve", help="run scheduled daily jobs")


    backfill_parser = subparsers.add_parser("backfill", help="generate historical data")
    backfill_parser.add_argument("--start", default="2024-09-01")
    backfill_parser.add_argument("--end", default="today")

    run_once_parser = subparsers.add_parser("run-once", help="run one daily update now")
    run_once_parser.add_argument("slot", choices=("morning", "afternoon"))

    subparsers.add_parser(
        "fix-tabs",
        help="delete default blank tabs and order month tabs newest-first",
    )

    args = parser.parse_args()
    if args.command is None:
        args.command = "serve"
    return args


def main() -> None:
    """Dispatch the requested command."""

    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    )
    args = parse_args()
    if args.command == "serve":
        serve()
    elif args.command == "backfill":
        backfill(args.start, args.end)
    elif args.command == "run-once":
        run_once(args.slot)
    elif args.command == "fix-tabs":
        fix_tabs()
    else:
        raise ValueError(f"Unknown command: {args.command}")


if __name__ == "__main__":
    main()
