#!/usr/bin/env python3
"""Admin CLI: user operations."""
from __future__ import annotations

import argparse
import os
import shutil
from pathlib import Path

import db
from functions import load_config_variables


def list_users(configs: dict) -> None:
    for entry in configs["users"]:
        print(entry["name"])


def prompt_yes_no(message: str) -> bool:
    while True:
        raw = input(f"{message} [y/n]: ").strip().lower()
        if raw in ("y", "yes"):
            return True
        if raw in ("n", "no"):
            return False


def merge_dirs(src: Path, dst: Path) -> None:
    for root, _, files in os.walk(src):
        rel = Path(root).relative_to(src)
        target_dir = dst / rel
        target_dir.mkdir(parents=True, exist_ok=True)
        for filename in files:
            src_file = Path(root) / filename
            dst_file = target_dir / filename
            if dst_file.exists():
                print(f"Skip existing file: {dst_file}")
                continue
            shutil.move(str(src_file), str(dst_file))

    for root, dirs, files in os.walk(src, topdown=False):
        if not dirs and not files:
            Path(root).rmdir()


def move_user_outputs(
    configs: dict, user_name: str, old_handle: str, new_handle: str
) -> None:
    user_cfg = next((u for u in configs["users"] if u["name"] == user_name), None)
    if not user_cfg:
        print(f"Unknown user: {user_name}")
        return

    base_dirs = [Path(user_cfg["download-dir"])]
    for base in base_dirs:
        old_path = base / old_handle
        new_path = base / new_handle
        if not old_path.exists():
            print(f"Missing: {old_path}")
            continue
        if not new_path.exists():
            old_path.rename(new_path)
            continue
        if not prompt_yes_no(
            f"Merge contents from {old_path} into existing {new_path}?"
        ):
            continue
        merge_dirs(old_path, new_path)


def cmd_users(_: argparse.Namespace) -> None:
    configs = load_config_variables()
    list_users(configs)


def cmd_user_rename(args: argparse.Namespace) -> None:
    configs = load_config_variables()
    with db.connect(configs) as conn:
        result = db.bulk_rename_handle(
            conn,
            user_name=args.user,
            site=args.site,
            old_handle=args.old,
            new_handle=args.new,
        )
        conn.commit()
    print(result)
    move_user_outputs(configs, args.user, args.old, args.new)
