from django import forms
from .models import (
    CustomUser, Company, Branch,
    PlatformBankAccount, PlatformMobileBanking, CompanyPayment,
)
from .branch_utils import ensure_main_branch


class CompanyRegistrationForm(forms.ModelForm):
    password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}))
    password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm Password'}))
    username = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Username'}))
    owner_email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Owner Email'}))

    class Meta:
        model = Company
        fields = ['name', 'logo', 'establishment_date', 'owner_name', 'owner_email', 'owner_phone', 'address']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Company Name'}),
            'establishment_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'owner_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Owner Full Name'}),
            'owner_phone': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Owner Phone'}),
            'address': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'logo': forms.FileInput(attrs={'class': 'form-control'}),
        }

    def clean_password2(self):
        p1 = self.cleaned_data.get('password1')
        p2 = self.cleaned_data.get('password2')
        if p1 and p2 and p1 != p2:
            raise forms.ValidationError("Passwords don't match")
        return p2

    def clean_username(self):
        u = self.cleaned_data.get('username')
        if CustomUser.objects.filter(username=u).exists():
            raise forms.ValidationError("Username already exists")
        return u

    def save(self, commit=True):
        company = super().save(commit=commit)
        if commit:
            user = CustomUser.objects.create_user(
                username=self.cleaned_data['username'],
                password=self.cleaned_data['password1'],
                email=self.cleaned_data['owner_email'],
                role='admin',
                company=company,
            )
            user.is_active = True
            user.save()
            # Every company starts with a Main Branch; more can be added later.
            ensure_main_branch(company)
        return company


class UserForm(forms.ModelForm):
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Leave blank to keep current password'}),
        required=False,
    )

    def __init__(self, *args, company=None, **kwargs):
        super().__init__(*args, **kwargs)
        # Company admins can create/manage only company-admin and sales-person
        # accounts. The platform super-admin role is never exposed here.
        self.fields["role"].choices = [
            ("admin", "Admin"),
            ("sales_person", "Sales Person"),
        ]
        branch_field = self.fields["branch"]
        branch_field.queryset = (
            Branch.objects.filter(company=company, is_active=True) if company is not None
            else Branch.objects.none()
        )
        branch_field.required = False
        branch_field.empty_label = "— No branch (admin sees all) —"
        branch_field.label = "Branch"
        branch_field.help_text = "Required for Sales Person: they can only sell from and see this branch."

    class Meta:
        model = CustomUser
        fields = ['username', 'first_name', 'last_name', 'email', 'phone', 'role', 'branch', 'password', 'is_active']
        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control'}),
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'phone': forms.TextInput(attrs={'class': 'form-control'}),
            'role': forms.Select(attrs={'class': 'form-control'}),
            'branch': forms.Select(attrs={'class': 'form-control'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def clean(self):
        cleaned = super().clean()
        if cleaned.get('role') == 'sales_person' and not cleaned.get('branch'):
            self.add_error('branch', 'Select the branch this sales person works in.')
        return cleaned

    def save(self, commit=True):
        user = super().save(commit=False)
        if self.cleaned_data.get('password'):
            user.set_password(self.cleaned_data['password'])
        if commit:
            user.save()
        return user


class BranchForm(forms.ModelForm):
    class Meta:
        model = Branch
        fields = ['name', 'code', 'phone', 'email', 'manager_name', 'address', 'is_active']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g. Uttara Branch'}),
            'code': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g. UTR'}),
            'phone': forms.TextInput(attrs={'class': 'form-control'}),
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'manager_name': forms.TextInput(attrs={'class': 'form-control'}),
            'address': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def __init__(self, *args, company=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.company = company

    def clean_name(self):
        name = self.cleaned_data['name'].strip()
        clash = Branch.objects.filter(company=self.company, name__iexact=name)
        if self.instance.pk:
            clash = clash.exclude(pk=self.instance.pk)
        if clash.exists():
            raise forms.ValidationError("You already have a branch with this name.")
        return name

    def clean_is_active(self):
        active = self.cleaned_data.get('is_active')
        if self.instance.pk and self.instance.is_main and not active:
            raise forms.ValidationError("The main branch cannot be deactivated.")
        return active


class BankAccountForm(forms.ModelForm):
    class Meta:
        model = PlatformBankAccount
        fields = [
            'bank_name', 'account_holder_name', 'account_number',
            'branch_name', 'routing_number', 'swift_code',
            'instructions', 'is_active',
        ]
        widgets = {
            'bank_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g. Dutch-Bangla Bank'}),
            'account_holder_name': forms.TextInput(attrs={'class': 'form-control'}),
            'account_number': forms.TextInput(attrs={'class': 'form-control'}),
            'branch_name': forms.TextInput(attrs={'class': 'form-control'}),
            'routing_number': forms.TextInput(attrs={'class': 'form-control'}),
            'swift_code': forms.TextInput(attrs={'class': 'form-control'}),
            'instructions': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }


class MobileBankingForm(forms.ModelForm):
    class Meta:
        model = PlatformMobileBanking
        fields = [
            'provider', 'provider_other_name', 'account_number',
            'account_type', 'instructions', 'is_active',
        ]
        widgets = {
            'provider': forms.Select(attrs={'class': 'form-control'}),
            'provider_other_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': "Only if provider is 'Other'"}),
            'account_number': forms.TextInput(attrs={'class': 'form-control'}),
            'account_type': forms.Select(attrs={'class': 'form-control'}),
            'instructions': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }


class CompanyPaymentForm(forms.ModelForm):
    class Meta:
        model = CompanyPayment
        fields = [
            'amount', 'method', 'bank_account', 'mobile_account',
            'transaction_id', 'payment_date', 'status', 'note',
        ]
        widgets = {
            'amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
            'method': forms.Select(attrs={'class': 'form-control', 'id': 'id_method'}),
            'bank_account': forms.Select(attrs={'class': 'form-control'}),
            'mobile_account': forms.Select(attrs={'class': 'form-control'}),
            'transaction_id': forms.TextInput(attrs={'class': 'form-control', 'placeholder': "Sender's TrxID / reference"}),
            'payment_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'status': forms.Select(attrs={'class': 'form-control'}),
            'note': forms.TextInput(attrs={'class': 'form-control'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['bank_account'].queryset = PlatformBankAccount.objects.filter(is_active=True)
        self.fields['bank_account'].required = False
        self.fields['mobile_account'].queryset = PlatformMobileBanking.objects.filter(is_active=True)
        self.fields['mobile_account'].required = False

    def clean(self):
        cleaned = super().clean()
        method = cleaned.get('method')
        if method == 'bank' and not cleaned.get('bank_account'):
            self.add_error('bank_account', 'Select which bank account received this payment.')
        if method == 'mobile_banking' and not cleaned.get('mobile_account'):
            self.add_error('mobile_account', 'Select which mobile banking number received this payment.')
        return cleaned


class MakePaymentForm(forms.ModelForm):
    """Used by a company admin on the 'Make Payment' page to submit proof of payment."""
    class Meta:
        model = CompanyPayment
        fields = [
            'amount', 'method', 'bank_account', 'mobile_account',
            'transaction_id', 'payment_date', 'note',
        ]
        widgets = {
            'amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'placeholder': 'Amount you sent'}),
            'method': forms.Select(attrs={'class': 'form-control', 'id': 'id_method'}),
            'bank_account': forms.Select(attrs={'class': 'form-control'}),
            'mobile_account': forms.Select(attrs={'class': 'form-control'}),
            'transaction_id': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Transaction / TrxID you received'}),
            'payment_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'note': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional note'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['bank_account'].queryset = PlatformBankAccount.objects.filter(is_active=True)
        self.fields['bank_account'].required = False
        self.fields['mobile_account'].queryset = PlatformMobileBanking.objects.filter(is_active=True)
        self.fields['mobile_account'].required = False

    def clean(self):
        cleaned = super().clean()
        method = cleaned.get('method')
        if method == 'bank' and not cleaned.get('bank_account'):
            self.add_error('bank_account', 'Select which bank account you paid into.')
        if method == 'mobile_banking' and not cleaned.get('mobile_account'):
            self.add_error('mobile_account', 'Select which mobile banking number you paid into.')
        return cleaned
