"""Seed the standard NGO Chart of Accounts — no spreadsheet required.

Usage:
    python manage.py seed_chart_of_accounts [--clear]
"""
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from apps.accounting.models import Account
from apps.companies.models import Organization

# code, name, type, normal_balance, is_cash, cash_flow_category, revenue_type
ACCOUNTS = [
    ("1000", "Cash and Bank", "Asset", "Debit", True, "operating", ""),
    ("1100", "Grant Receivable", "Asset", "Debit", False, "operating", ""),
    ("1200", "Employee / Activity Advance", "Asset", "Debit", False, "operating", ""),
    ("1500", "Equipment", "Asset", "Debit", False, "investing", ""),
    ("2000", "Accounts Payable", "Liability", "Credit", False, "operating", ""),
    ("2100", "Deferred Grant Income", "Liability", "Credit", False, "operating", ""),
    ("3000", "Net Assets - Unrestricted", "Equity", "Credit", False, "investing", ""),
    ("3100", "Net Assets - Restricted", "Equity", "Credit", False, "investing", ""),
    ("4000", "Grant Income", "Income", "Credit", False, "operating", "contribution"),
    # Expense group headers. These carry no postings; child accounts roll up to
    # them on the Penerimaan dan Pengeluaran report.
    ("5A00", "Biaya Personel", "Expense", "Debit", False, "operating", ""),
    ("5B00", "Operasional Riset", "Expense", "Debit", False, "operating", ""),
    ("5C00", "Diseminasi dan Publikasi", "Expense", "Debit", False, "operating", ""),
    ("5D00", "Beban Overhead dan Institusi", "Expense", "Debit", False, "operating", ""),
    ("5000", "Personnel Expense", "Expense", "Debit", False, "operating", ""),
    ("5100", "Travel Expense", "Expense", "Debit", False, "operating", ""),
    ("5200", "Workshop Expense", "Expense", "Debit", False, "operating", ""),
    ("5300", "Consultant Expense", "Expense", "Debit", False, "operating", ""),
    ("5400", "Office and Communication", "Expense", "Debit", False, "operating", ""),
    ("1900", "Encumbrance", "Encumbrance", "Debit", False, "none", ""),
    ("2900", "Reserve for Encumbrance", "Encumbrance", "Credit", False, "none", ""),
]

# child code -> (parent header code, expense_class). Drives the report's
# Beban Langsung / Beban Tidak Langsung split and its group headers.
EXPENSE_GROUPING = {
    "5A00": (None, "direct"),
    "5B00": (None, "direct"),
    "5C00": (None, "direct"),
    "5D00": (None, "indirect"),
    "5000": ("5A00", "direct"),
    "5300": ("5A00", "direct"),
    "5100": ("5B00", "direct"),
    "5200": ("5C00", "direct"),
    "5400": ("5D00", "indirect"),
}


class Command(BaseCommand):
    help = "Seed the standard chart of accounts (hardcoded, no xlsx)."

    def add_arguments(self, parser):
        parser.add_argument("--clear", action="store_true", help="Delete existing accounts first.")
        parser.add_argument("--org", help="Organization slug to seed. Defaults to the first organization.")

    def handle(self, *args, **opts):
        org = (
            Organization.objects.filter(slug=opts["org"]).first()
            if opts["org"] else Organization.objects.first()
        )
        if org is None:
            raise CommandError("No organization found. Create one first.")

        with transaction.atomic():
            if opts["clear"]:
                Account.objects.filter(organization=org).delete()
                self.stdout.write(f"Cleared existing accounts for {org.name}.")

            for code, name, type_, normal, is_cash, cf, revenue_type in ACCOUNTS:
                Account.objects.update_or_create(
                    organization=org, code=code,
                    defaults={
                        "name": name, "type": type_, "normal_balance": normal,
                        "is_cash": is_cash, "cash_flow_category": cf,
                        "revenue_type": revenue_type,
                    },
                )

            # Second pass: headers must exist before children can point at them.
            by_code = {a.code: a for a in Account.objects.filter(organization=org)}
            for code, (parent_code, expense_class) in EXPENSE_GROUPING.items():
                account = by_code.get(code)
                if account is None:
                    continue
                account.parent = by_code.get(parent_code) if parent_code else None
                account.expense_class = expense_class
                account.save(update_fields=["parent", "expense_class"])

        self.stdout.write(self.style.SUCCESS(f"Done. Accounts for {org.name}={Account.objects.filter(organization=org).count()}"))
