from django.core.management import call_command
from django.core.management.base import BaseCommand

from oscar.core.loading import get_model

Category = get_model("catalogue", "Category")


def sort_categories_by_field(categories, fieldname):
    # Sort categories by fieldname
    categories = sorted(categories, key=lambda cat: getattr(cat, fieldname).lower())

    for idx, cat in enumerate(categories):
        try:
            # Find the next category in line
            next_cat = categories[idx + 1]
        except IndexError:
            pass
        else:
            # Move the categories accordingly
            next_cat.move(cat, pos="last-sibling")

        # Refresh the category after moving it because the local object is no good anymore
        cat.refresh_from_db()

        # Check all categories if they have children, if they do; sort them also
        if not cat.is_leaf():
            sort_categories_by_field(cat.get_children(), fieldname)


class Command(BaseCommand):
    def add_arguments(self, parser):
        # Positional arguments
        parser.add_argument("fieldname", type=str)
        parser.add_argument(
            "--depth",
            type=int,
            default=1,
            help="Depth of categories to sort (default: 1)",
        )

    def handle(self, *args, **options):
        fieldname = options["fieldname"]
        depth = options["depth"]

        sort_categories_by_field(Category.objects.filter(depth=depth), fieldname)
        call_command("fix_catalogue_tree")
