import inspect
import os
from importlib import import_module

from django.apps import apps
from django.core.management.base import BaseCommand
from django.template import Context, Template

from flexi_tag.utils.models import FlexiTagMixin


class Command(BaseCommand):
    help = "Generate tag models for all models that inherit from FlexiTagMixin"

    def add_arguments(self, parser):
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Show what would be generated without creating files",
        )

    def handle(self, *args, **options):
        dry_run = options.get("dry_run", False)
        # Template for the generated model
        model_template = Template(
            """
# This file is auto-generated. Do not edit manually.
# Generated by the generate_tag_models command.

from django.db import models
from flexi_tag.utils.compat import JSONField
from django.contrib.postgres.indexes import GinIndex


class {{ model_name }}Tag(models.Model):
    instance = models.OneToOneField(
        "{{ app_label }}.{{ model_name }}",
        on_delete=models.CASCADE,
        primary_key=True,
    )
    tags = JSONField(default=list)

    class Meta:
        app_label = "{{ app_label }}"
        db_table = "{{ app_label }}_{{ model_lower_name }}_tag"
        indexes = [GinIndex(fields=["tags"])]

    def __str__(self):
        return "Tags for {}".format(self.instance)
"""
        )

        for app_config in apps.get_app_configs():
            for model in app_config.get_models():
                if issubclass(model, FlexiTagMixin) and model is not FlexiTagMixin:
                    model_name = model.__name__
                    app_label = model._meta.app_label  # noqa
                    model_module = import_module(model.__module__)
                    model_dir = os.path.dirname(inspect.getfile(model_module))

                    context = Context(
                        {
                            "model_name": model_name,
                            "app_label": app_label,
                            "model_lower_name": model_name.lower(),
                        }
                    )

                    model_content = model_template.render(context)

                    file_path = os.path.join(model_dir, "flexi_generated_model.py")

                    if dry_run:
                        self.stdout.write(
                            "Would create file: {file_path}".format(file_path=file_path)
                        )
                        self.stdout.write(model_content)
                        self.stdout.write("-" * 40)
                    else:
                        with open(file_path, "w") as f:
                            f.write(model_content)
                        self.stdout.write(
                            self.style.SUCCESS(
                                "Created tag model for {app_label}.{model_name} at {file_path}".format(
                                    app_label=app_label,
                                    model_name=model_name,
                                    file_path=file_path,
                                )
                            )
                        )

        if dry_run:
            self.stdout.write("Dry run completed. No files were created.")
        else:
            self.stdout.write(
                self.style.SUCCESS("Successfully generated all tag models!")
            )
