from django.core.management.base import BaseCommand

from accounts.models import User
from operations.models import Class, Course, Event, Topic
from learning.models import Question


def seed_users():
    users = {}

    admin, _ = User.objects.get_or_create(
        username="admin",
        defaults={
            "role": User.Role.ADMIN,
            "email": "admin@gap.mz",
            "first_name": "Administrador",
            "is_staff": True,
            "is_superuser": True,
        },
    )
    admin.set_password("admin123")
    admin.save()
    users["admin"] = admin

    instructor, _ = User.objects.get_or_create(
        username="formador",
        defaults={
            "role": User.Role.INSTRUCTOR,
            "email": "formador@gap.mz",
            "first_name": "António",
            "last_name": "Langa",
            "phone": "840000001",
        },
    )
    instructor.set_password("instructor123")
    instructor.save()
    users["instructor"] = instructor

    for i, name in enumerate(["Maria", "João", "Ana"]):
        student, created = User.objects.get_or_create(
            username=f"estudante{i + 1}",
            defaults={
                "role": User.Role.STUDENT,
                "email": f"estudante{i + 1}@gap.mz",
                "first_name": name,
                "phone": f"84{i:07d}",
            },
        )
        if created:
            student.set_password("student123")
            student.save()
        users[f"student{i + 1}"] = student

    return users


def seed_course():
    course, _ = Course.objects.get_or_create(
        code="CALCULO-II",
        defaults={
            "name": "Cálculo II",
            "description": "Integrais, equações diferenciais e séries.",
        },
    )
    topics = {}

    integrais, _ = Topic.objects.get_or_create(
        course=course,
        name="Integrais",
        defaults={"description": "Técnicas de integração", "order": 1},
    )
    imediata, _ = Topic.objects.get_or_create(
        course=course,
        name="Integração imediata",
        defaults={"description": "Integrais de funções elementares", "order": 2, "parent": integrais},
    )
    substituicao, _ = Topic.objects.get_or_create(
        course=course,
        name="Substituição",
        defaults={"description": "Método de substituição", "order": 3, "parent": integrais},
    )
    por_partes, _ = Topic.objects.get_or_create(
        course=course,
        name="Integração por partes",
        defaults={"description": "∫ u dv = uv − ∫ v du", "order": 4, "parent": integrais},
    )
    improprios, _ = Topic.objects.get_or_create(
        course=course,
        name="Integrais impróprios",
        defaults={"description": "Integrais com limites infinitos", "order": 5, "parent": integrais},
    )
    edos, _ = Topic.objects.get_or_create(
        course=course,
        name="Equações diferenciais",
        defaults={"description": "Equações de primeira ordem", "order": 6},
    )
    series, _ = Topic.objects.get_or_create(
        course=course,
        name="Séries",
        defaults={"description": "Convergência e séries de potência", "order": 7},
    )

    substituicao.prerequisites.add(imediata)
    por_partes.prerequisites.add(substituicao)
    improprios.prerequisites.add(por_partes)

    topics.update(
        {
            "integrais": integrais,
            "imediata": imediata,
            "substituicao": substituicao,
            "por_partes": por_partes,
            "improprios": improprios,
            "edos": edos,
            "series": series,
        }
    )
    return course, topics


def seed_questions(course, topics, user):
    questions = [
        {
            "statement": "Calcule ∫ x eˣ dx.",
            "topic": topics["por_partes"],
            "difficulty": 2,
            "question_type": "short_answer",
            "options": [],
            "correct_answer": "x eˣ − eˣ + C",
            "explanation": "Use u = x e dv = eˣ dx; ∫ x eˣ dx = x eˣ − ∫ eˣ dx = x eˣ − eˣ + C.",
            "skills": ["identificar u e dv", "aplicar integração por partes", "simplificar resultado"],
        },
        {
            "statement": "Calcule ∫ x² eˣ dx.",
            "topic": topics["por_partes"],
            "difficulty": 3,
            "question_type": "short_answer",
            "options": [],
            "correct_answer": "x² eˣ − 2x eˣ + 2 eˣ + C",
            "explanation": "Aplicar integração por partes duas vezes.",
            "skills": ["aplicar integração por partes"],
        },
        {
            "statement": "∫ (2x + 3) dx é igual a:",
            "topic": topics["imediata"],
            "difficulty": 1,
            "question_type": "multiple_choice",
            "options": ["x² + 3x + C", "2x² + 3x + C", "x² + 3 + C", "2 + 3x + C"],
            "correct_answer": "x² + 3x + C",
            "explanation": "∫ 2x dx = x² e ∫ 3 dx = 3x.",
            "skills": ["integrar polinómios"],
        },
        {
            "statement": "Calcule ∫ sin(x) dx.",
            "topic": topics["imediata"],
            "difficulty": 1,
            "question_type": "short_answer",
            "options": [],
            "correct_answer": "-cos(x) + C",
            "explanation": "A derivada de −cos(x) é sin(x).",
            "skills": ["integrar funções trigonométricas"],
        },
        {
            "statement": "Calcule ∫ 2x e^(x²) dx.",
            "topic": topics["substituicao"],
            "difficulty": 2,
            "question_type": "short_answer",
            "options": [],
            "correct_answer": "e^(x²) + C",
            "explanation": "Seja u = x², du = 2x dx.",
            "skills": ["aplicar substituição"],
        },
        {
            "statement": "A equação y' = ky é uma equação diferencial separável.",
            "topic": topics["edos"],
            "difficulty": 1,
            "question_type": "true_false",
            "options": ["Verdadeiro", "Falso"],
            "correct_answer": "Verdadeiro",
            "explanation": "y' = ky pode ser escrita como dy/y = k dx.",
            "skills": ["identificar equações separáveis"],
        },
    ]

    for q in questions:
        Question.objects.get_or_create(
            statement=q["statement"],
            defaults={
                "course": course,
                "topic": q["topic"],
                "difficulty": q["difficulty"],
                "question_type": q["question_type"],
                "options": q["options"],
                "correct_answer": q["correct_answer"],
                "explanation": q["explanation"],
                "skills": q["skills"],
                "created_by": user,
            },
        )


def seed_operations(users, course):
    from operations.models import Enrollment, Event, EventEnrollment

    turma, created = Class.objects.get_or_create(
        name="Turma Piloto Cálculo II",
        defaults={
            "course": course,
            "instructor": users["instructor"],
            "description": "Turma piloto para validação do GAP Learning Engine.",
            "schedule": "Sábados 9h–11h",
            "mode": Class.Mode.ONLINE,
            "location_or_link": "https://meet.gap.mz/turma-piloto",
            "max_capacity": 30,
            "price": 2500,
            "community_link": "https://chat.gap.mz/turma-piloto",
        },
    )

    for user in users.values():
        if user.is_student:
            Enrollment.objects.get_or_create(
                student=user, klass=turma, defaults={"status": Enrollment.Status.ACTIVE}
            )

    Event.objects.get_or_create(
        title="Aula aberta: Integração por partes",
        defaults={
            "description": "Sessão gratuita de preparação.",
            "instructor": users["instructor"],
            "date": "2026-08-20",
            "time": "18:00",
            "mode": Event.Mode.ONLINE,
            "location_or_link": "https://meet.gap.mz/aula-aberta",
            "max_capacity": 100,
            "allow_guest_enrollment": True,
        },
    )


class Command(BaseCommand):
    help = "Cria dados de desenvolvimento (utilizadores, disciplina Cálculo II, questões, turma piloto)."

    def handle(self, *args, **options):
        users = seed_users()
        course, topics = seed_course()
        seed_questions(course, topics, users["admin"])
        seed_operations(users, course)
        self.stdout.write(
            self.style.SUCCESS(
                "Seed concluído. Credenciais: admin/admin123, formador/instructor123, "
                "estudante1..3/student123"
            )
        )
