# Django imports
from django import forms

# Local imports
from .models import Geo, Modulation, ObjItem, Parameter, Polarization, Satellite, Standard

class UploadFileForm(forms.Form):
    file = forms.FileField(
        label="Выберите файл", 
        widget=forms.FileInput(attrs={
            'class': 'form-file-input'
        })
    )


class LoadExcelData(forms.Form):
    file = forms.FileField(
        label="Выберите Excel файл",
        widget=forms.FileInput(attrs={
            'class': 'form-control',
            'accept': '.xlsx,.xls'
        })
    )
    sat_choice = forms.ModelChoiceField(
        queryset=Satellite.objects.all(),
        label="Выберите спутник",
        widget=forms.Select(attrs={
            'class': 'form-select'
        })
    )
    number_input = forms.IntegerField(
        label="Введите число объектов",
        min_value=0,
        widget=forms.NumberInput(attrs={
            'class': 'form-control'
        })
    )

class LoadCsvData(forms.Form):
    file = forms.FileField(
        label="Выберите CSV файл",
        widget=forms.FileInput(attrs={
            'class': 'form-control',
            'accept': '.csv'
        })
    )

class UploadVchLoad(UploadFileForm):
    sat_choice = forms.ModelChoiceField(
        queryset=Satellite.objects.all(),
        label="Выберите спутник",
        widget=forms.Select(attrs={
            'class': 'form-select'
        })
    )


class VchLinkForm(forms.Form):
    sat_choice = forms.ModelChoiceField(
        queryset=Satellite.objects.all(),
        label="Выберите спутник",
        widget=forms.Select(attrs={
            'class': 'form-select'
        })
    )
    # ku_range = forms.ChoiceField(
    #     choices=[(9750.0, '9750'), (10750.0, '10750')],
    #     # coerce=lambda x: x == 'True',
    #     widget=forms.Select(attrs={'class': 'form-select'}),
    #     label='Выбор диапазона'
    # )
    value1 = forms.FloatField(
        label="Разброс по частоте (не используется)",
        required=False,
        initial=0.0,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'placeholder': 'Не используется - погрешность определяется автоматически'
        })
    )
    value2 = forms.FloatField(
        label="Разброс по полосе (в %)", 
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'placeholder': 'Введите погрешность полосы в процентах',
            'step': '0.1'
        })
    )


class NewEventForm(forms.Form):
    # sat_choice = forms.ModelChoiceField(
    #     queryset=Satellite.objects.all(),
    #     label="Выберите спутник",
    #     widget=forms.Select(attrs={
    #         'class': 'form-select'
    #     })
    # )
    # pol_choice = forms.ModelChoiceField(
    #     queryset=Polarization.objects.all(),
    #     label="Выберите поляризацию",
    #     widget=forms.Select(attrs={
    #         'class': 'form-select'
    #     })
    # )
    file = forms.FileField(
        label="Выберите файл",
        widget=forms.FileInput(attrs={
            'class': 'form-control',
            'accept': '.xlsx,.xls'
        })
    )


class FillLyngsatDataForm(forms.Form):
    """Форма для заполнения данных из Lyngsat с поддержкой кеширования"""
    
    REGION_CHOICES = [
        ('europe', 'Европа'),
        ('asia', 'Азия'),
        ('america', 'Америка'),
        ('atlantic', 'Атлантика'),
    ]
    
    satellites = forms.ModelMultipleChoiceField(
        queryset=Satellite.objects.all().order_by('name'),
        label="Выберите спутники",
        widget=forms.SelectMultiple(attrs={
            'class': 'form-select',
            'size': '10'
        }),
        required=True,
        help_text="Удерживайте Ctrl (Cmd на Mac) для выбора нескольких спутников"
    )
    
    regions = forms.MultipleChoiceField(
        choices=REGION_CHOICES,
        label="Выберите регионы",
        widget=forms.SelectMultiple(attrs={
            'class': 'form-select',
            'size': '4'
        }),
        required=True,
        initial=['europe', 'asia', 'america', 'atlantic'],
        help_text="Удерживайте Ctrl (Cmd на Mac) для выбора нескольких регионов"
    )
    
    use_cache = forms.BooleanField(
        label="Использовать кеширование",
        required=False,
        initial=True,
        widget=forms.CheckboxInput(attrs={
            'class': 'form-check-input'
        }),
        help_text="Использовать кешированные данные (ускоряет повторные запросы)"
    )
    
    force_refresh = forms.BooleanField(
        label="Принудительно обновить данные",
        required=False,
        initial=False,
        widget=forms.CheckboxInput(attrs={
            'class': 'form-check-input'
        }),
        help_text="Игнорировать кеш и получить свежие данные с сайта"
    )


class LinkLyngsatForm(forms.Form):
    """Форма для привязки источников LyngSat к объектам"""
    
    satellites = forms.ModelMultipleChoiceField(
        queryset=Satellite.objects.all().order_by('name'),
        label="Выберите спутники",
        widget=forms.SelectMultiple(attrs={
            'class': 'form-select',
            'size': '10'
        }),
        required=False,
        help_text="Оставьте пустым для обработки всех спутников"
    )
    
    frequency_tolerance = forms.FloatField(
        label="Допуск по частоте (МГц)",
        initial=0.5,
        min_value=0,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'step': '0.1'
        }),
        help_text="Допустимое отклонение частоты при сравнении"
    )
class ParameterForm(forms.ModelForm):
    """
    Форма для создания и редактирования параметров ВЧ загрузки.
    
    Работает с одним экземпляром Parameter, связанным с ObjItem через OneToOne связь.
    """
    
    class Meta:
        model = Parameter
        fields = [
            'id_satellite', 'frequency', 'freq_range', 'polarization',
            'bod_velocity', 'modulation', 'snr', 'standard'
        ]
        widgets = {
            'id_satellite': forms.Select(attrs={
                'class': 'form-select',
                'required': True
            }),
            'frequency': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.000001',
                'min': '0',
                'max': '50000',
                'placeholder': 'Введите частоту в МГц'
            }),
            'freq_range': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.000001',
                'min': '0',
                'max': '1000',
                'placeholder': 'Введите полосу частот в МГц'
            }),
            'bod_velocity': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.001',
                'min': '0',
                'placeholder': 'Введите символьную скорость в БОД'
            }),
            'snr': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.001',
                'min': '-50',
                'max': '100',
                'placeholder': 'Введите ОСШ в дБ'
            }),
            'polarization': forms.Select(attrs={'class': 'form-select'}),
            'modulation': forms.Select(attrs={'class': 'form-select'}),
            'standard': forms.Select(attrs={'class': 'form-select'}),
        }
        labels = {
            'id_satellite': 'Спутник',
            'frequency': 'Частота (МГц)',
            'freq_range': 'Полоса частот (МГц)',
            'polarization': 'Поляризация',
            'bod_velocity': 'Символьная скорость (БОД)',
            'modulation': 'Модуляция',
            'snr': 'ОСШ (дБ)',
            'standard': 'Стандарт',
        }
        help_texts = {
            'frequency': 'Частота в диапазоне от 0 до 50000 МГц',
            'freq_range': 'Полоса частот в диапазоне от 0 до 1000 МГц',
            'bod_velocity': 'Символьная скорость должна быть положительной',
            'snr': 'Отношение сигнал/шум в диапазоне от -50 до 100 дБ',
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # Динамически загружаем choices для select полей
        self.fields['id_satellite'].queryset = Satellite.objects.all().order_by('name')
        self.fields['polarization'].queryset = Polarization.objects.all().order_by('name')
        self.fields['modulation'].queryset = Modulation.objects.all().order_by('name')
        self.fields['standard'].queryset = Standard.objects.all().order_by('name')
        
        # Делаем спутник обязательным полем
        self.fields['id_satellite'].required = True
    
    def clean(self):
        """
        Дополнительная валидация формы.
        
        Проверяет соотношение между частотой, полосой частот и символьной скоростью.
        """
        cleaned_data = super().clean()
        frequency = cleaned_data.get('frequency')
        freq_range = cleaned_data.get('freq_range')
        bod_velocity = cleaned_data.get('bod_velocity')
        
        # Проверка что частота больше полосы частот
        if frequency and freq_range:
            if freq_range > frequency:
                self.add_error('freq_range', 'Полоса частот не может быть больше частоты')
        
        # Проверка что символьная скорость соответствует полосе частот
        if bod_velocity and freq_range:
            if bod_velocity > freq_range * 1000000:  # Конвертация МГц в Гц
                self.add_error('bod_velocity', 'Символьная скорость не может превышать полосу частот')
        
        return cleaned_data

class GeoForm(forms.ModelForm):
    class Meta:
        model = Geo
        fields = ['location', 'comment', 'is_average']
        widgets = {
            'location': forms.TextInput(attrs={'class': 'form-control'}),
            'comment': forms.TextInput(attrs={'class': 'form-control'}),
            'is_average': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

class ObjItemForm(forms.ModelForm):
    """
    Форма для создания и редактирования объектов (источников сигнала).
    
    Работает с моделью ObjItem. Параметры ВЧ загрузки обрабатываются отдельно
    через ParameterForm с использованием OneToOne связи.
    """
    
    class Meta:
        model = ObjItem
        fields = ['name']
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Введите название объекта',
                'maxlength': '100'
            }),
        }
        labels = {
            'name': 'Название объекта',
        }
        help_texts = {
            'name': 'Уникальное название объекта/источника сигнала',
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Делаем поле name необязательным, так как оно может быть пустым
        self.fields['name'].required = False
    
    def clean_name(self):
        """
        Валидация поля name.
        
        Проверяет что название не состоит только из пробелов.
        """
        name = self.cleaned_data.get('name')
        
        if name:
            # Удаляем лишние пробелы
            name = name.strip()
            
            # Проверяем что после удаления пробелов что-то осталось
            if not name:
                raise forms.ValidationError('Название не может состоять только из пробелов')
        
        return name