import argparse
import sys
from devplacepy.database import get_table
from devplacepy.utils import strip_html


def cmd_role_get(args):
    users = get_table("users")
    user = users.find_one(username=args.username)
    if not user:
        print(f"User '{args.username}' not found")
        sys.exit(1)
    print(user.get("role", "member").lower())


def cmd_role_set(args):
    role = args.role.lower()
    if role not in ("member", "admin"):
        print("Role must be 'member' or 'admin'")
        sys.exit(1)

    users = get_table("users")
    user = users.find_one(username=args.username)
    if not user:
        print(f"User '{args.username}' not found")
        sys.exit(1)

    users.update({"uid": user["uid"], "role": role.capitalize()}, ["uid"])
    print(f"User '{args.username}' role set to '{role}'")


def cmd_news_clear(args):
    from devplacepy.database import db
    for table in ("news", "news_images", "news_sync"):
        if table in db.tables:
            count = len(list(db[table].all()))
            db[table].delete()
            print(f"Deleted {count} rows from '{table}'")
        else:
            print(f"Table '{table}' does not exist, skipping")
    print("News data cleared")


def cmd_news_sanitize(args):
    from devplacepy.database import db
    if "news" not in db.tables:
        print("News table does not exist")
        return
    news_table = db["news"]
    updated = 0
    for row in news_table.all():
        desc = (strip_html(row.get("description", "") or ""))[:5000]
        content = (strip_html(row.get("content", "") or ""))[:10000]
        if desc != row.get("description", "") or content != row.get("content", ""):
            news_table.update({"id": row["id"], "description": desc, "content": content}, ["id"])
            updated += 1
    print(f"Sanitized {updated} news article(s)")


def cmd_attachments_prune(args):
    from devplacepy.database import db
    from devplacepy.config import STATIC_DIR
    import os
    deleted_records = 0
    deleted_files = 0
    freed_bytes = 0

    if "attachments" in db.tables:
        orphans = list(db["attachments"].find(resource_uid=""))
        orphans += list(db["attachments"].find(resource_type=""))
        seen = set()
        unique_orphans = []
        for o in orphans:
            if o["uid"] not in seen:
                seen.add(o["uid"])
                unique_orphans.append(o)

        for att in unique_orphans:
            sp = att.get("storage_path", "")
            if sp:
                fp = STATIC_DIR / "uploads" / sp
                try:
                    if fp.exists():
                        freed_bytes += fp.stat().st_size
                        fp.unlink()
                        deleted_files += 1
                    parent = fp.parent
                    if parent.exists() and not any(parent.iterdir()):
                        parent.rmdir()
                    grandparent = parent.parent
                    if grandparent.exists() and not any(grandparent.iterdir()):
                        grandparent.rmdir()
                except Exception as e:
                    print(f"  Error deleting {sp}: {e}")
            db["attachments"].delete(id=att["id"])
            deleted_records += 1

    print(f"Pruned {deleted_records} orphan records, {deleted_files} files, {freed_bytes / 1024:.1f} KB freed")


def main():
    parser = argparse.ArgumentParser(description="DevPlace admin CLI")
    sub = parser.add_subparsers(title="commands", dest="command")

    role = sub.add_parser("role", help="Manage user roles")
    role_sub = role.add_subparsers(title="action", dest="action")

    role_get = role_sub.add_parser("get", help="Get a user's role")
    role_get.add_argument("username")
    role_get.set_defaults(func=cmd_role_get)

    role_set = role_sub.add_parser("set", help="Set a user's role")
    role_set.add_argument("username")
    role_set.add_argument("role", choices=["member", "admin"])
    role_set.set_defaults(func=cmd_role_set)

    news = sub.add_parser("news", help="News management")
    news_sub = news.add_subparsers(title="action", dest="action")
    news_clear = news_sub.add_parser("clear", help="Delete all news from local database")
    news_clear.set_defaults(func=cmd_news_clear)
    news_sanitize = news_sub.add_parser("sanitize", help="Strip HTML from all existing news descriptions and content")
    news_sanitize.set_defaults(func=cmd_news_sanitize)

    attachments = sub.add_parser("attachments", help="Attachment management")
    att_sub = attachments.add_subparsers(title="action", dest="action")
    att_prune = att_sub.add_parser("prune", help="Remove orphaned attachment records and files")
    att_prune.set_defaults(func=cmd_attachments_prune)

    args = parser.parse_args()
    if hasattr(args, "func"):
        args.func(args)
    else:
        parser.print_help()
        sys.exit(1)


if __name__ == "__main__":
    main()
