from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.forms import ModelForm

from mixins.restrictions import RestrictedFormMixin

from .models import (
    AI,
    ChatSession,
    Group,
    Manipulation,
    Message,
    NotificationSettings,
    Person,
    Persona,
    PersonIdentifier,
    QueuedMessage,
    User,
)

# Create your forms here.


class NewUserForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = (
            "username",
            "email",
            "first_name",
            "last_name",
            "password1",
            "password2",
        )

    def save(self, commit=True):
        user = super(NewUserForm, self).save(commit=False)
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
        return user


class NotificationSettingsForm(RestrictedFormMixin, ModelForm):
    class Meta:
        model = NotificationSettings
        fields = (
            "ntfy_topic",
            "ntfy_url",
        )
        help_texts = {
            "ntfy_topic": "The topic to send notifications to.",
            "ntfy_url": "Custom NTFY server. Leave blank to use the default server.",
        }


class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = User
        fields = "__all__"


class AIForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = AI
        fields = ("base_url", "api_key", "model")
        # widgets = {
        #     "api_key": forms.PasswordInput(attrs={"class": "input"}),
        # }
        help_texts = {
            "base_url": "URL of the OpenAI-compatible server.",
            "api_key": "API key for authentication.",
            "model": "Select the AI model to be used.",
        }


class PersonIdentifierForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = PersonIdentifier
        fields = ("identifier", "service")
        help_texts = {
            "identifier": (
                "The unique identifier (e.g., username or phone number) "
                "for the person."
            ),
            "service": (
                "The platform associated with this identifier "
                "(e.g., Signal, WhatsApp, Instagram, XMPP)."
            ),
        }


class PersonForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = Person
        fields = (
            "name",
            "summary",
            "profile",
            "revealed",
            "dislikes",
            "likes",
            "sentiment",
            "timezone",
            "last_interaction",
        )
        help_texts = {
            "name": "The full name of the person.",
            "summary": "A brief summary or description of this person.",
            "profile": "Detailed profile information about this person.",
            "revealed": "Information about what has been revealed to others.",
            "dislikes": "Things this person dislikes.",
            "likes": "Things this person enjoys.",
            "sentiment": "Sentiment score ranging from -1 (disliked) to +1 (trusted).",
            "timezone": "The person's timezone for accurate timestamping.",
            "last_interaction": "The date and time of the last recorded interaction.",
        }


class GroupForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = Group
        fields = ("name", "people")
        help_texts = {
            "name": "The name of the group.",
            "people": "People who are part of this group.",
        }

    people = forms.ModelMultipleChoiceField(
        queryset=Person.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        help_text=Meta.help_texts["people"],
        required=False,
    )


class PersonaForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = Persona
        fields = (
            "alias",
            "mbti",
            "mbti_identity",
            "inner_story",
            "core_values",
            "communication_style",
            "flirting_style",
            "humor_style",
            "likes",
            "dislikes",
            "tone",
            "response_tactics",
            "persuasion_tactics",
            "boundaries",
            "trust",
            "adaptability",
        )
        help_texts = {
            "alias": "The preferred name or identity for this persona.",
            "mbti": "Select the Myers-Briggs Type Indicator (MBTI) personality type.",
            "mbti_identity": (
                "Identity assertiveness: -1 (Turbulent) to +1 (Assertive)."
            ),
            "inner_story": "A brief background or philosophy that shapes this persona.",
            "core_values": "The guiding principles and values of this persona.",
            "communication_style": (
                "How this persona prefers to communicate "
                "(e.g., direct, formal, casual)."
            ),
            "flirting_style": "How this persona expresses attraction.",
            "humor_style": "Preferred style of humor (e.g., dry, dark, sarcastic).",
            "likes": "Topics and things this persona enjoys discussing.",
            "dislikes": "Topics and behaviors this persona prefers to avoid.",
            "tone": (
                "The general tone this persona prefers "
                "(e.g., formal, witty, detached)."
            ),
            "response_tactics": (
                "How this persona handles manipulation "
                "(e.g., gaslighting, guilt-tripping)."
            ),
            "persuasion_tactics": "The methods this persona uses to convince others.",
            "boundaries": "What this persona will not tolerate in conversations.",
            "trust": "Initial trust level (0-100) given in interactions.",
            "adaptability": "How easily this persona shifts tones or styles (0-100).",
        }


class ManipulationForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = Manipulation
        fields = ("name", "group", "ai", "persona", "enabled", "mode", "filter_enabled")
        help_texts = {
            "name": "The name of this manipulation strategy.",
            "group": "The group involved in this manipulation strategy.",
            # "self": "Group for own UUIDs.",
            "ai": "The AI associated with this manipulation.",
            "persona": "The persona used for this manipulation.",
            "enabled": "Whether this manipulation is enabled.",
            "mode": "Mode of operation.",
            "filter_enabled": (
                "Whether incoming messages will be filtered using the persona."
            ),
        }


class SessionForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = ChatSession
        fields = ("identifier", "summary")
        help_texts = {
            "identifier": "Person identifier.",
            "summary": "Summary of chat transcript.",
        }


class MessageForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = Message
        fields = (
            "session",
            "sender_uuid",
            "text",
            "custom_author",
            "delivered_ts",
            "read_ts",
            "read_source_service",
            "read_by_identifier",
            "receipt_payload",
        )
        help_texts = {
            "session": "Chat session this message was sent in.",
            "sender_uuid": "UUID of the sender.",
            "text": "Content of the message.",
            "custom_author": "For detecting USER and BOT messages.",
            "delivered_ts": "Delivery timestamp in unix milliseconds, if known.",
            "read_ts": "Read timestamp in unix milliseconds, if known.",
            "read_source_service": "Service that reported this read receipt.",
            "read_by_identifier": "Identifier that read this message.",
            "receipt_payload": "Raw normalized receipt metadata.",
        }


class QueueForm(RestrictedFormMixin, forms.ModelForm):
    class Meta:
        model = QueuedMessage
        fields = ("session", "manipulation", "text")
        help_texts = {
            "session": "Chat session this message will be sent in.",
            "manipulation": "Manipulation that generated the message.",
            "text": "Content of the proposed message.",
        }


class AIWorkspaceWindowForm(forms.Form):
    """Controls the message window size for AI workspace previews."""

    limit = forms.ChoiceField(
        choices=(
            ("20", "Last 20"),
            ("50", "Last 50"),
            ("100", "Last 100"),
        ),
        initial="20",
        required=True,
        help_text="How many most-recent messages to load for the selected person.",
        widget=forms.Select(attrs={"class": "is-fullwidth"}),
    )
