# content/management/commands/check_admission_flow.py
from decimal import Decimal
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from django.db import transaction

from django.contrib.auth import get_user_model
from content.models import (
    Course, AcademicClass, Subject, ExamTerm,
    AdmissionApplication, StudentProfile, StudentMarksheet,
)
# If your row model is in reportcards as MarkRow, use that. Adjust import if different.
try:
    from reportcards.models import MarkRow
except Exception:
    # fallback name commonly used in this project
    from content.models import StudentMarksheetItem as MarkRow  # adjust if needed

User = get_user_model()


class Command(BaseCommand):
    help = "Quick check: simulate an admission -> approve() -> verify marksheet rows."

    def handle(self, *args, **options):
        results = []
        # We'll run changes for real here; wrap each major step so you can inspect DB after if desired.
        try:
            with transaction.atomic():
                # 1. Setup fixtures (use get_or_create to be idempotent)
                admin_user, _ = User.objects.get_or_create(username="adm-checker", defaults={"email":"adm-checker@example.com"})
                course, _ = Course.objects.get_or_create(
                    title="CHECK: Test Course",
                    defaults={
                        "admission_fee": Decimal("100.00"),
                        "first_month_tuition": Decimal("200.00"),
                        "exam_fee": Decimal("50.00"),
                        "bus_fee": Decimal("0.00"),
                        "hostel_fee": Decimal("0.00"),
                        "marksheet_fee": Decimal("0.00"),
                        "is_active": True,
                    }
                )
                cls, _ = AcademicClass.objects.get_or_create(name="6", section="A", year=timezone.localdate().year)
                sub1, _ = Subject.objects.get_or_create(name="Math", school_class=cls, defaults={"is_active": True, "order": 1})
                sub2, _ = Subject.objects.get_or_create(name="English", school_class=cls, defaults={"is_active": True, "order": 2})
                # ensure inactive subject exists to test it's ignored
                Subject.objects.get_or_create(name="OldSub", school_class=cls, defaults={"is_active": False, "order": 99})
                term, _ = ExamTerm.objects.get_or_create(name="Auto Term Test", defaults={"start_date": timezone.localdate(), "year": timezone.localdate().year})

                results.append("Fixtures ready.")

                # 2. create admission app
                app = AdmissionApplication.objects.create(
                    full_name="Check Student",
                    email="check.student@example.com",
                    phone="000999000",
                    desired_course=course,
                    enroll_class=cls,
                    enroll_section="A",
                    add_marksheet=True,
                )
                results.append(f"AdmissionApplication created: {app.pk}")

                # 3. call approve (create_first_month_invoice=False to avoid invoice side-effects if you want)
                sp = app.approve(by_user=admin_user, create_first_month_invoice=False)
                results.append(f"approve() returned StudentProfile: {sp}")

                # 4. find marksheet
                current_term = term  # we created/get_or_create above
                ms_qs = StudentMarksheet.objects.filter(
                    school_class=cls,
                    term=current_term,
                    student_full_name=sp.user.get_full_name(),
                    roll_number=sp.roll_number,
                    section=sp.section,
                )
                if not ms_qs.exists():
                    raise CommandError("Marksheet not created for student; check approve() logic.")
                ms = ms_qs.get()
                results.append(f"Marksheet found: id={ms.pk}")

                # 5. rows count — adjust query model name if needed
                try:
                    rows_qs = MarkRow.objects.filter(marksheet=ms)
                except Exception:
                    # try alternate name
                    from content.models import StudentMarksheetItem as Row
                    rows_qs = Row.objects.filter(marksheet=ms)

                rows_count = rows_qs.count()
                active_subjects = Subject.objects.filter(school_class=cls, is_active=True).count()
                results.append(f"Rows for marksheet: {rows_count}; Active subjects: {active_subjects}")

                if rows_count != active_subjects:
                    raise CommandError(f"Rows count ({rows_count}) != active subject count ({active_subjects})")

                # 6. re-run approve() to ensure no duplicate rows
                app2_sp = app.approve(by_user=admin_user, create_first_month_invoice=False)
                rows_count_after = rows_qs.count()
                results.append(f"After re-approve rows: {rows_count_after}")

                if rows_count_after != rows_count:
                    raise CommandError("Duplicate rows created on re-approve.")

                # success
                self.stdout.write(self.style.SUCCESS("Admission approve flow check PASSED."))
                for line in results:
                    self.stdout.write(f"- {line}")

        except CommandError as e:
            self.stdout.write(self.style.ERROR(f"FAILED: {e}"))
            raise
        except Exception as e:
            self.stdout.write(self.style.ERROR(f"Unexpected error: {e}"))
            raise
