from django import forms
from django.contrib.auth import get_user_model
from django.db.models import Q
from django.utils import timezone

from .constants import ACTIVITY_TYPES, OUTCOMES
from .models import Contact, Lead
from schools.phone_numbers import PhoneNumberField

User = get_user_model()


class LeadForm(forms.ModelForm):
    activity_kind = forms.ChoiceField(
        choices=[("", "No activity") , *ACTIVITY_TYPES],
        required=False,
        label="Activity type",
    )
    activity_outcome = forms.ChoiceField(
        choices=OUTCOMES,
        required=False,
        label="Outcome",
    )
    activity_occurred_at = forms.DateTimeField(
        required=False,
        label="When",
        input_formats=["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"],
        widget=forms.DateTimeInput(attrs={"type": "datetime-local"}, format="%Y-%m-%dT%H:%M"),
    )
    activity_notes = forms.CharField(
        required=False,
        label="Activity notes",
        widget=forms.Textarea(attrs={"rows": 3}),
    )

    class Meta:
        model = Lead
        fields = ["stage", "priority", "owner", "next_followup", "next_action", "deal_value", "lost_reason"]
        widgets = {"next_followup": forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d"),
                   "deal_value": forms.NumberInput(attrs={"min": 0, "step": "any"})}
        labels = {"next_followup": "Next follow-up", "next_action": "What to do next",
                  "deal_value": "Deal value", "lost_reason": "Why was it lost?"}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["owner"].queryset = User.objects.filter(is_active=True).filter(
            Q(is_superuser=True) | Q(access_profile__crm_access="edit")).order_by("username")
        self.fields["owner"].empty_label = "Unassigned"

    def clean(self):
        d = super().clean()
        if d.get("stage") == "lost" and not (d.get("lost_reason") or "").strip():
            self.add_error("lost_reason", "Say why this lead was lost.")
        if d.get("deal_value") is not None and d["deal_value"] < 0:
            self.add_error("deal_value", "Deal value cannot be negative.")

        activity_kind = d.get("activity_kind") or ""
        activity_outcome = d.get("activity_outcome") or ""
        activity_notes = (d.get("activity_notes") or "").strip()
        activity_time = d.get("activity_occurred_at")
        activity_details_provided = bool(activity_kind or activity_outcome or activity_notes or activity_time)

        if activity_details_provided and not activity_kind:
            if activity_notes and not activity_outcome:
                d["activity_kind"] = "note"
                activity_kind = "note"
            else:
                self.add_error("activity_kind", "Choose an activity type.")
        if activity_kind == "note" and not activity_notes:
            self.add_error("activity_notes", "A note needs some text.")
        if activity_time and activity_time > timezone.now() + timezone.timedelta(days=1):
            self.add_error("activity_occurred_at", "That time is in the future.")
        return d


class ActivityForm(forms.Form):
    kind = forms.ChoiceField(choices=ACTIVITY_TYPES, label="Type")
    outcome = forms.ChoiceField(choices=OUTCOMES, required=False, label="Outcome")
    occurred_at = forms.DateTimeField(
        label="When", input_formats=["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"],
        widget=forms.DateTimeInput(attrs={"type": "datetime-local"}, format="%Y-%m-%dT%H:%M"))
    notes = forms.CharField(required=False, label="Notes", widget=forms.Textarea(attrs={"rows": 3}))
    followup_date = forms.DateField(required=False, label="Set next follow-up",
                                    widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d"))
    followup_action = forms.CharField(required=False, max_length=200, label="Follow-up task")

    @staticmethod
    def blank():
        return ActivityForm(initial={"occurred_at": timezone.localtime().replace(second=0, microsecond=0),
                                     "kind": "call"})

    def clean(self):
        d = super().clean()
        if d.get("kind") == "note" and not (d.get("notes") or "").strip():
            self.add_error("notes", "A note needs some text.")
        if d.get("occurred_at") and d["occurred_at"] > timezone.now() + timezone.timedelta(days=1):
            self.add_error("occurred_at", "That time is in the future.")
        return d


class ContactForm(forms.ModelForm):
    phone = PhoneNumberField(required=False, widget=forms.TextInput(
        attrs={"type": "tel", "inputmode": "tel"}))

    class Meta:
        model = Contact
        fields = ["name", "role", "phone", "email", "is_primary"]
