from __future__ import annotations

import argparse
import json
import sys
from getpass import getpass
from pathlib import Path

from app.db.session import SessionLocal
from app.models.user import User
from app.services.reference_masterdata import ReferenceMasterdataImportService


def cmd_import_reference_masterdata(args: argparse.Namespace) -> int:
    with SessionLocal() as session:
        service = ReferenceMasterdataImportService(session)
        result = service.import_reference_docx(
            Path(args.reference),
            dry_run=args.dry_run,
            update_existing=args.update_existing,
            create_validation=args.create_validation,
        )
        payload = result.as_dict()
        if args.json_summary:
            print(json.dumps(payload, ensure_ascii=False, default=str))
        else:
            for label in ["created", "updated", "unchanged", "conflicts", "errors"]:
                print(f"{label}: {len(payload[label])}")
                for item in payload[label]:
                    print(f"  - {item}")
            if result.validation_id:
                print(f"validation_id: {result.validation_id}")
        return 0


def cmd_reset_password(args: argparse.Namespace) -> int:
    from app.core.security import hash_password
    from sqlalchemy import select

    with SessionLocal() as session:
        user = session.scalar(select(User).where(User.email == args.email.lower()))
        if user is None:
            raise SystemExit(f"User not found: {args.email}")
        first = getpass("New password: ")
        second = getpass("Repeat password: ")
        if first != second:
            raise SystemExit("Passwords do not match")
        user.password_hash = hash_password(first)
        session.commit()
        print("Password updated")
        return 0


def cmd_create_admin(_: argparse.Namespace) -> int:
    from app.core.security import hash_password
    from app.models.user import UserRole
    from sqlalchemy import select

    email = input("E-Mail: ").strip().lower()
    first_name = input("Vorname: ").strip()
    last_name = input("Nachname: ").strip()
    password = getpass("Passwort: ")
    password_confirmation = getpass("Passwort bestätigen: ")
    if password != password_confirmation:
        raise SystemExit("Passwords do not match")
    with SessionLocal() as session:
        existing = session.scalar(select(User).where(User.email == email))
        if existing is not None:
            raise SystemExit("User already exists")
        session.add(
            User(
                email=email,
                first_name=first_name,
                last_name=last_name,
                role=UserRole.ADMIN.value,
                password_hash=hash_password(password),
                is_active=True,
                must_change_password=False,
            )
        )
        session.commit()
        print("Admin user created")
        return 0


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog="python -m app.cli")
    subparsers = parser.add_subparsers(dest="command", required=True)

    import_parser = subparsers.add_parser("import-reference-masterdata")
    import_parser.add_argument("--reference", required=True)
    import_parser.add_argument("--dry-run", action="store_true")
    import_parser.add_argument("--update-existing", action="store_true")
    import_parser.add_argument("--create-validation", action="store_true")
    import_parser.add_argument("--json-summary", action="store_true")
    import_parser.set_defaults(func=cmd_import_reference_masterdata)

    reset_parser = subparsers.add_parser("reset-password")
    reset_parser.add_argument("--email", required=True)
    reset_parser.set_defaults(func=cmd_reset_password)

    admin_parser = subparsers.add_parser("create-admin")
    admin_parser.set_defaults(func=cmd_create_admin)
    return parser


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)
    return args.func(args)


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
