from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from datetime import date, datetime
import re
from students.models import Student, StudentAchievement, AchievementType


class StudentForm(forms.ModelForm):
    """Enhanced student form with comprehensive validation"""
    
    class Meta:
        model = Student
        fields = [
            'name', 'nisn', 'gender', 'birth_date', 'birth_place', 
            'student_class', 'entry_year', 'phone', 'address', 'parent_phone'
        ]
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': 'Nama lengkap siswa',
                'maxlength': '200'
            }),
            'nisn': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': '10 digit NISN',
                'maxlength': '10',
                'pattern': '[0-9]{10}'
            }),
            'gender': forms.Select(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all'
            }),
            'birth_date': forms.DateInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'type': 'date'
            }),
            'birth_place': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': 'Tempat lahir'
            }),
            'student_class': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': 'Contoh: 8A, 7B, 9C',
                'pattern': '[789][A-Z]'
            }),
            'entry_year': forms.NumberInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'min': '2020',
                'max': '2030',
                'value': datetime.now().year
            }),
            'phone': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': 'Nomor HP siswa (opsional)'
            }),
            'address': forms.Textarea(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'rows': 3,
                'placeholder': 'Alamat lengkap (opsional)'
            }),
            'parent_phone': forms.TextInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'placeholder': 'Nomor HP orang tua (opsional)'
            }),
        }
    
    def clean_name(self):
        name = self.cleaned_data.get('name', '').strip()
        
        if not name:
            raise ValidationError('Nama tidak boleh kosong')
        
        if len(name) < 2:
            raise ValidationError('Nama terlalu pendek (minimal 2 karakter)')
        
        if len(name) > 200:
            raise ValidationError('Nama terlalu panjang (maksimal 200 karakter)')
        
        if not re.match(r"^[a-zA-Z\s.\']+$", name):
            raise ValidationError('Nama hanya boleh berisi huruf, spasi, titik, dan apostrof')
        
        if len(name.split()) < 2:
            raise ValidationError('Nama harus minimal 2 kata')
        
        return name.title()
    
    def clean_nisn(self):
        nisn = self.cleaned_data.get('nisn', '').strip()
        
        if not nisn:
            raise ValidationError('NISN tidak boleh kosong')
        
        if not nisn.isdigit():
            raise ValidationError('NISN hanya boleh berisi angka')
        
        if len(nisn) != 10:
            raise ValidationError('NISN harus terdiri dari 10 digit')
        
        queryset = Student.objects.filter(nisn=nisn)
        if self.instance and self.instance.pk:
            queryset = queryset.exclude(pk=self.instance.pk)
        
        if queryset.exists():
            raise ValidationError('NISN sudah digunakan siswa lain')
        
        return nisn
    
    def clean_student_class(self):
        student_class = self.cleaned_data.get('student_class', '').strip().upper()
        
        if not student_class:
            raise ValidationError('Kelas tidak boleh kosong')
        
        if not re.match(r'^[789][A-Z]$', student_class):
            raise ValidationError('Format kelas tidak valid (gunakan format: 7A, 8B, 9C)')
        
        return student_class
    
    def clean_birth_date(self):
        birth_date = self.cleaned_data.get('birth_date')
        
        if not birth_date:
            raise ValidationError('Tanggal lahir tidak boleh kosong')
        
        if birth_date > date.today():
            raise ValidationError('Tanggal lahir tidak boleh di masa depan')
        
        today = date.today()
        age = today.year - birth_date.year - ((today.month, today.day) < (birth_date.month, birth_date.day))
        
        if age < 10:
            raise ValidationError(f'Usia terlalu muda ({age} tahun). Minimal 10 tahun')
        
        if age > 25:
            raise ValidationError(f'Usia terlalu tua ({age} tahun). Maksimal 25 tahun')
        
        return birth_date
    
    def clean_entry_year(self):
        entry_year = self.cleaned_data.get('entry_year')
        current_year = datetime.now().year
        
        if entry_year and (entry_year < 2020 or entry_year > current_year + 1):
            raise ValidationError(f'Tahun masuk harus antara 2020 - {current_year + 1}')
        
        return entry_year
    
    def clean_phone(self):
        phone = self.cleaned_data.get('phone', '').strip()
        
        if phone:
            phone = re.sub(r'[\s\-\(\)\+]', '', phone)
            
            if not re.match(r'^(08|628|\+628)[0-9]{8,12}$', phone):
                raise ValidationError('Format nomor HP tidak valid (gunakan format: 08xxxxxxxxx)')
            
            if phone.startswith('+628'):
                phone = '08' + phone[4:]
            elif phone.startswith('628'):
                phone = '08' + phone[3:]
        
        return phone
    
    def clean_parent_phone(self):
        parent_phone = self.cleaned_data.get('parent_phone', '').strip()
        
        if parent_phone:
            parent_phone = re.sub(r'[\s\-\(\)\+]', '', parent_phone)
            
            if not re.match(r'^(08|628|\+628)[0-9]{8,12}$', parent_phone):
                raise ValidationError('Format nomor HP orang tua tidak valid (gunakan format: 08xxxxxxxxx)')
            
            if parent_phone.startswith('+628'):
                parent_phone = '08' + parent_phone[4:]
            elif parent_phone.startswith('628'):
                parent_phone = '08' + parent_phone[3:]
        
        return parent_phone


# ==================== STUDENT ACHIEVEMENT FORM ====================

class StudentAchievementForm(forms.ModelForm):
    """Form untuk input prestasi siswa"""
    
    class Meta:
        model = StudentAchievement
        fields = ['achievement_type', 'level', 'rank', 'year', 'certificate', 'notes']
        widgets = {
            'achievement_type': forms.Select(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all'
            }),
            'level': forms.Select(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all'
            }),
            'rank': forms.Select(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all'
            }),
            'year': forms.NumberInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'min': '2020',
                'max': datetime.now().year,
                'value': datetime.now().year
            }),
            'certificate': forms.FileInput(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'accept': '.pdf,.jpg,.jpeg,.png'
            }),
            'notes': forms.Textarea(attrs={
                'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all',
                'rows': 3,
                'placeholder': 'Catatan tambahan (opsional)'
            }),
        }
    
    def clean_achievement_type(self):
        achievement_type = self.cleaned_data.get('achievement_type')
        
        if not achievement_type:
            raise ValidationError('Pilih jenis prestasi')
        
        if not achievement_type.is_active:
            raise ValidationError('Jenis prestasi ini tidak aktif')
        
        return achievement_type
    
    def clean_year(self):
        year = self.cleaned_data.get('year')
        current_year = datetime.now().year
        
        if year and (year < 2020 or year > current_year):
            raise ValidationError(f'Tahun prestasi harus antara 2020 - {current_year}')
        
        return year
    
    def clean_certificate(self):
        certificate = self.cleaned_data.get('certificate')
        
        if certificate:
            # Check file size (5MB limit)
            if certificate.size > 5 * 1024 * 1024:
                raise ValidationError('Ukuran file terlalu besar (maksimal 5MB)')
            
            # Check file extension
            allowed_extensions = ['.pdf', '.jpg', '.jpeg', '.png']
            file_extension = certificate.name.lower().split('.')[-1]
            if f'.{file_extension}' not in allowed_extensions:
                raise ValidationError('Format file tidak didukung (gunakan: PDF, JPG, PNG)')
        
        return certificate


class StudentBatchImportForm(forms.Form):
    """Enhanced batch import form"""
    
    csv_file = forms.FileField(
        label='File CSV',
        widget=forms.FileInput(attrs={
            'accept': '.csv',
            'class': 'hidden',
            'id': 'csvFileInput'
        }),
        help_text='Upload file CSV dengan data siswa (maksimal 5MB, 1000 records)'
    )
    
    def clean_csv_file(self):
        file = self.cleaned_data.get('csv_file')
        
        if not file:
            raise ValidationError('File CSV wajib diupload')
        
        if not file.name.lower().endswith('.csv'):
            raise ValidationError('File harus berformat CSV (.csv)')
        
        if file.size > 5 * 1024 * 1024:  # 5MB
            raise ValidationError(f'Ukuran file terlalu besar ({file.size // 1024 // 1024}MB). Maksimal 5MB')
        
        if file.size == 0:
            raise ValidationError('File kosong. Pilih file yang berisi data')
        
        return file
