from __future__ import annotations

import argparse
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from sqlalchemy import create_engine  # noqa: E402

from app.core.config import get_settings  # noqa: E402
from app.services.system_initializer import (  # noqa: E402
    SystemInitializeOptions,
    create_database_if_missing,
    fresh_initialize_database,
    reset_existing_database_with_backup,
)


def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Initialize ForgeFlow ERP database for customer deployment.")
    subparsers = parser.add_subparsers(dest="mode", required=True)

    def add_common_arguments(subparser: argparse.ArgumentParser) -> None:
        subparser.add_argument("--company-name", required=True)
        subparser.add_argument("--admin-name", required=True)
        subparser.add_argument("--admin-phone", required=True)
        subparser.add_argument("--admin-password", required=True)
        subparser.add_argument(
            "--smart-operation-report",
            choices=["on", "off"],
            default="on",
            help="Enable or disable smart miniapp operation report integration.",
        )
        subparser.add_argument("--delete-files", action="store_true")
        subparser.add_argument("--allow-any-database", action="store_true")

    fresh = subparsers.add_parser("fresh", help="Create a database if needed, create schema, and seed a clean skeleton.")
    add_common_arguments(fresh)

    reset = subparsers.add_parser("reset", help="Back up and reset an existing database into a clean skeleton.")
    add_common_arguments(reset)
    reset.add_argument("--confirm-reset", action="store_true")

    return parser.parse_args(argv)


def _options_from_args(args: argparse.Namespace) -> SystemInitializeOptions:
    return SystemInitializeOptions(
        mode=args.mode,
        company_name=args.company_name,
        admin_name=args.admin_name,
        admin_phone=args.admin_phone,
        admin_password=args.admin_password,
        smart_operation_report_enabled=args.smart_operation_report == "on",
        confirm_reset=bool(getattr(args, "confirm_reset", False)),
        delete_files=bool(args.delete_files),
        allow_any_database=bool(args.allow_any_database),
    )


def _print_result(settings: object, result: object, options: SystemInitializeOptions) -> None:
    print(f"mode={options.mode}")
    print(f"database={settings.mysql_host}:{settings.mysql_port}/{settings.mysql_database}")
    print(f"backup_path={result.backup_path or ''}")
    print(f"summary_path={result.summary_path or ''}")
    print(f"admin_username={result.seeded.get('admin_username', '')}")


def main(argv: list[str] | None = None) -> int:
    args = parse_args(argv)
    settings = get_settings()
    options = _options_from_args(args)
    engine = create_engine(settings.mysql_dsn, pool_pre_ping=True, future=True)

    if options.mode == "fresh":
        create_database_if_missing(settings)
        result = fresh_initialize_database(engine, options)
    else:
        result = reset_existing_database_with_backup(engine, settings, options)

    _print_result(settings, result, options)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
