from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.db import transaction
from apps.banking.models import Account


class Command(BaseCommand):
    help = "Initializes the cooperative's main accounts."

    @transaction.atomic
    def handle(self, *args, **options):
        User = get_user_model()
        self.stdout.write(
            self.style.SUCCESS("--- Initializing Cooperative Accounts ---")
        )

        try:
            # Recherche n'importe quel superutilisateur existant
            admin_user = User.objects.filter(is_superuser=True, is_active=True).first()
            if not admin_user:
                raise User.DoesNotExist("Aucun superutilisateur actif trouvé")
            self.stdout.write(
                self.style.SUCCESS(
                    f"Utilisation du superutilisateur: {admin_user.email}"
                )
            )
        except User.DoesNotExist:
            self.stdout.write(
                self.style.ERROR(
                    "Un superutilisateur actif est requis pour posséder les comptes de la coopérative."
                )
            )
            self.stdout.write(
                self.style.WARNING(
                    "Veuillez créer un superutilisateur d'abord avec : python manage.py createsuperuser"
                )
            )
            return

        # Définir les comptes à créer pour la coopérative
        accounts_to_create = [
            {"name": "Caisse Principale", "type": Account.AccountType.CASH_DESK},
            {"name": "Capital Social", "type": Account.AccountType.SHARE_CAPITAL},
            {
                "name": "Fonds de Solidarité",
                "type": Account.AccountType.SOLIDARITY_FUND,
            },
            {"name": "Compte Mobile Money", "type": Account.AccountType.MOBILE_MONEY},
            {"name": "Fonds de Prêt", "type": Account.AccountType.LOAN_FUND},
            {"name": "Fonds de Réserve", "type": Account.AccountType.RESERVE_FUND},
            {"name": "Compte Épargne Général", "type": Account.AccountType.SAVINGS},
            {
                "name": "Réserve pour Créances Douteuses",
                "type": Account.AccountType.LOAN_LOSS_RESERVE,
            },
        ]

        for account_data in accounts_to_create:
            account, created = Account.objects.get_or_create(
                name=account_data["name"],
                type=account_data["type"],
                defaults={
                    "owner": admin_user,
                    "balance": 0.00,
                    "created_by": admin_user,
                    "account_number": self.generate_account_number(
                        account_data["type"]
                    ),
                },
            )

            if created:
                self.stdout.write(
                    self.style.SUCCESS(
                        f"Account '{account.name}' ({account.get_type_display()}) created."
                    )
                )
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f"Account '{account.name}' ({account.get_type_display()}) already exists."
                    )
                )

        self.stdout.write(
            self.style.SUCCESS("--- Cooperative Accounts Initialization Complete ---")
        )

    def generate_account_number(self, account_type):
        """Génère un numéro de compte basé sur le type."""
        type_prefixes = {
            Account.AccountType.CASH_DESK: "CASH",
            Account.AccountType.SHARE_CAPITAL: "CAPT",
            Account.AccountType.SOLIDARITY_FUND: "SOLID",
            Account.AccountType.MOBILE_MONEY: "MOBILE",
            Account.AccountType.LOAN_FUND: "LOAN",
            Account.AccountType.RESERVE_FUND: "RESRV",
            Account.AccountType.SAVINGS: "SAV",
            Account.AccountType.LOAN_LOSS_RESERVE: "LLRES",
            Account.AccountType.CURRENT: "CURR",
            Account.AccountType.INTEREST_INCOME: "INTINC",
        }

        prefix = type_prefixes.get(account_type, "GEN")

        # Compter les comptes existants du même type pour générer un numéro unique
        existing_count = Account.objects.filter(type=account_type).count()
        number = str(existing_count + 1).zfill(3)  # Ex: 001, 002, etc.

        return f"AMIFOND-{prefix}-{number}"
