from django import forms
from django.contrib.auth import get_user_model
from decimal import Decimal
from django.utils import timezone
from django.contrib.contenttypes.models import ContentType

from .models import (
    MaterialCategory,
    Material,
    Customer,
    CustomerSite,
)
from orgs.models import UserProfile


class MaterialCategoryForm(forms.ModelForm):
    class Meta:
        model = MaterialCategory
        fields = ["organization", "name"]


class MaterialForm(forms.ModelForm):
    class Meta:
        model = Material
        fields = ["organization", "category", "name", "code", "default_unit"]


class CustomerForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = ["organization", "name", "email", "phone", "billing_address", "price_list"]


class CustomerSiteForm(forms.ModelForm):
    class Meta:
        model = CustomerSite
        fields = ["customer", "name", "address", "contact_name", "contact_phone", "contact_email"]


# Operational forms ----------------------------------------------------------

User = get_user_model()


class PickupAssignForm(forms.Form):
    driver = forms.ModelChoiceField(queryset=User.objects.all(), required=True, label="Assign Driver")


class PickupStatusForm(forms.Form):
    status = forms.ChoiceField(choices=(), required=True, label="Set Status")

    def __init__(self, *args, **kwargs):
        from .models import PickupOrder

        super().__init__(*args, **kwargs)
        self.fields["status"].choices = PickupOrder.STATUS_CHOICES


class PaymentForm(forms.Form):
    amount = forms.DecimalField(max_digits=14, decimal_places=2)
    received_at = forms.DateTimeField(required=False, initial=timezone.now)
    reference = forms.CharField(max_length=128, required=False)


class DocumentForm(forms.Form):
    organization = forms.ModelChoiceField(queryset=None)
    file = forms.FileField()
    kind = forms.CharField(max_length=64, required=False)
    content_type = forms.ModelChoiceField(queryset=ContentType.objects.all(), required=True, label="Attach To Model")
    object_id = forms.IntegerField(required=True, label="Object ID")

    def __init__(self, *args, **kwargs):
        from orgs.models import Organization as Org

        super().__init__(*args, **kwargs)
        self.fields["organization"].queryset = Org.objects.all()


# User management ------------------------------------------------------------


class UserCreateForm(forms.Form):
    username = forms.CharField(max_length=150)
    email = forms.EmailField(required=False)
    role = forms.ChoiceField(choices=UserProfile.ROLE_CHOICES)
    password1 = forms.CharField(widget=forms.PasswordInput)
    password2 = forms.CharField(widget=forms.PasswordInput)

    def clean_username(self):
        User = get_user_model()
        username = self.cleaned_data["username"].strip()
        if User.objects.filter(username__iexact=username).exists():
            raise forms.ValidationError("Username already taken")
        return username

    def clean(self):
        cleaned = super().clean()
        p1 = cleaned.get("password1")
        p2 = cleaned.get("password2")
        if p1 and p2 and p1 != p2:
            self.add_error("password2", "Passwords do not match")
        return cleaned


class UserEditForm(forms.Form):
    email = forms.EmailField(required=False)
    role = forms.ChoiceField(choices=UserProfile.ROLE_CHOICES)
    password1 = forms.CharField(widget=forms.PasswordInput, required=False)
    password2 = forms.CharField(widget=forms.PasswordInput, required=False)

    def clean(self):
        cleaned = super().clean()
        p1 = cleaned.get("password1")
        p2 = cleaned.get("password2")
        if (p1 or p2) and p1 != p2:
            self.add_error("password2", "Passwords do not match")
        return cleaned
