
import random
from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils.text import slugify
from organization.models import Organization
from departments.models import Department
from teacher_management.models import Teacher
from course.models import Course, CourseTeacher
from status.models import Status
from django.contrib.auth.models import User # Assuming User model for teachers if needed, though not directly used in Teacher model

class Command(BaseCommand):
    help = 'Seeds the database with default organizations, departments, teachers, and courses.'

    def handle(self, *args, **kwargs):
        self.stdout.write(self.style.SUCCESS('Starting database seeding...'))

        with transaction.atomic():
            self._create_statuses()
            organizations = self._create_organizations()
            
            for org in organizations:
                self.stdout.write(self.style.SUCCESS(f'Seeding data for organization: {org.name}'))
                departments = self._create_departments(org)
                teachers = self._create_teachers(org, departments)
                courses = self._create_courses(org, departments)
                self._assign_teachers_to_courses(courses, teachers)

        self.stdout.write(self.style.SUCCESS('Database seeding completed successfully!'))

    def _create_statuses(self):
        self.stdout.write('Creating default Status objects...')
        Status.objects.get_or_create(
            title='Active', type='teacher',
            defaults={'description': 'Teacher is currently active', 'slug': 'active-teacher'}
        )
        Status.objects.get_or_create(
            title='Inactive', type='teacher',
            defaults={'description': 'Teacher is currently inactive', 'slug': 'inactive-teacher'}
        )
        Status.objects.get_or_create(
            title='Active', type='department',
            defaults={'description': 'Department is currently active', 'slug': 'active-department'}
        )
        Status.objects.get_or_create(
            title='Inactive', type='department',
            defaults={'description': 'Department is currently inactive', 'slug': 'inactive-department'}
        )
        self.stdout.write(self.style.SUCCESS('Default Status objects created/ensured.'))

    def _create_organizations(self):
        self.stdout.write('Creating two Organization instances...')
        org1, created1 = Organization.objects.get_or_create(
            name='University of Example',
            defaults={
                'code': 'UOE',
                'email': 'info@uoe.edu',
                'external_id': 'uoe-ext-id-1',
                'external_source': 'seed_data',
                'description': 'A leading educational institution.',
                'address_line1': '123 University Rd',
                'city': 'Exampleville',
                'state': 'EX',
                'postal_code': '12345',
                'country': 'USA',
            }
        )
        if created1:
            self.stdout.write(self.style.SUCCESS(f'Created organization: {org1.name}'))
        else:
            self.stdout.write(self.style.WARNING(f'Organization already exists: {org1.name}'))

        org2, created2 = Organization.objects.get_or_create(
            name='Tech Institute',
            defaults={
                'code': 'TI',
                'email': 'contact@techinst.org',
                'external_id': 'ti-ext-id-2',
                'external_source': 'seed_data',
                'description': 'Specializing in technology and innovation.',
                'address_line1': '456 Innovation Dr',
                'city': 'Tech City',
                'state': 'TX',
                'postal_code': '67890',
                'country': 'USA',
            }
        )
        if created2:
            self.stdout.write(self.style.SUCCESS(f'Created organization: {org2.name}'))
        else:
            self.stdout.write(self.style.WARNING(f'Organization already exists: {org2.name}'))
        
        return [org1, org2]

    def _create_departments(self, organization):
        self.stdout.write(f'Creating departments for {organization.name}...')
        departments = []
        active_dept_status = Status.objects.get(slug='active-department')

        dept_names = ['Computer Science', 'Electrical Engineering']
        for i, name in enumerate(dept_names):
            dept, created = Department.objects.get_or_create(
                organization=organization,
                department_name=f'{organization.code} {name}',
                defaults={
                    'department_code': f'{organization.code}-{name[:3].upper()}{i+1}',
                    'status': active_dept_status,
                }
            )
            if created:
                self.stdout.write(self.style.SUCCESS(f'Created department: {dept.department_name}'))
            else:
                self.stdout.write(self.style.WARNING(f'Department already exists: {dept.department_name}'))
            departments.append(dept)
        return departments

    def _create_teachers(self, organization, departments):
        self.stdout.write(f'Creating teachers for {organization.name}...')
        teachers = []
        active_teacher_status = Status.objects.get(slug='active-teacher')
        
        for i in range(5):
            first_name = f'Teacher{i+1}'
            last_name = f'Org{organization.code}'
            email = f'teacher{i+1}.{organization.code.lower()}@example.com'
            code = f'T{organization.code}{i+1}'
            
            teacher, created = Teacher.objects.get_or_create(
                organization=organization,
                email=email,
                defaults={
                    'first_name': first_name,
                    'last_name': last_name,
                    'code': code,
                    'phone': f'555-100-{1000 + i}',
                    'title': random.choice(['Professor', 'Associate Professor', 'Assistant Professor', 'Lecturer']),
                    'department': random.choice(departments),
                    'status': active_teacher_status,
                }
            )
            if created:
                self.stdout.write(self.style.SUCCESS(f'Created teacher: {str(teacher)}'))
            else:
                self.stdout.write(self.style.WARNING(f'Teacher already exists: {teacher.full_name}'))
            teachers.append(teacher)
        return teachers

    def _create_courses(self, organization, departments):
        self.stdout.write(f'Creating courses for {organization.name}...')
        courses = []
        
        for i in range(5):
            course_name = f'Course {i+1} for {organization.code}'
            course_code = f'{organization.code}-C{i+1}'
            
            course, created = Course.objects.get_or_create(
                organization=organization,
                code=course_code,
                defaults={
                    'name': course_name,
                    'credit': random.choice([3.00, 3.50, 4.00]),
                    'credit_hours': random.choice([3.0, 3.0, 4.0]),
                    'department': random.choice(departments),
                    # 'year': None, # Assuming these are optional for now
                    # 'semester': None, # Assuming these are optional for now
                }
            )
            if created:
                self.stdout.write(self.style.SUCCESS(f'Created course: {course.name}'))
            else:
                self.stdout.write(self.style.WARNING(f'Course already exists: {course.name}'))
            courses.append(course)
        return courses

    def _assign_teachers_to_courses(self, courses, teachers):
        self.stdout.write('Assigning teachers to courses...')
        for course in courses:
            # Ensure each course has two unique teachers
            assigned_teachers = random.sample(teachers, 2)
            for teacher in assigned_teachers:
                CourseTeacher.objects.get_or_create(course=course, teacher=teacher)
                self.stdout.write(self.style.SUCCESS(f'Assigned {str(teacher)} to {course.name}'))
        self.stdout.write(self.style.SUCCESS('Teachers assigned to courses.'))
