from rest_framework import serializers

from apps.core.fields import LocalizedDateTimeField
from apps.userprofile.services import ProfileServices
from apps.customers.models import Customer
from apps.calls.models import Call, CallActivity
from apps.companies.models import Company, DealershipDepartment
from apps.companies.serializers import (
    DealershipCallSerializer,
    DealershipDepartmentCallSerializer
)


class CompanySerializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = ['id', 'name']


class CallSerializer(serializers.ModelSerializer):

    class Meta:
        model = Call
        fields = [
            'id',
            'caller_name',
            'from_number',
            'to_number',
            'company',
            'status',
            'duration',
            'cost',
            'call_id',
            'twilio_call_sid'
        ]
        read_only_fields = ['id']


class CallDetailSerializer(serializers.ModelSerializer):
    """Serializer for call detail view."""
    created_at = LocalizedDateTimeField()
    caller_name = serializers.SerializerMethodField()
    company = CompanySerializer(read_only=True)
    customer = serializers.SerializerMethodField()
    transfer_user = serializers.SerializerMethodField()
    # transfer_department = serializers.SerializerMethodField()
    activities = serializers.SerializerMethodField()
    dealership = DealershipCallSerializer(read_only=True)

    transcript = serializers.SerializerMethodField()

    class Meta:
        model = Call
        fields = [
            'id',
            'caller_name',
            'from_number',
            'to_number',
            'status',
            'duration',
            'cost',
            'bot_type',
            'sentiment',
            'transfer_status',
            'call_time_category',
            'created_at',
            'read_at',
            'call_id',
            'twilio_call_sid',
            'customer',
            'company',
            'transfer_user',
            # 'transfer_department',
            'activities',
            'dealership',
            'summary',
            'transcript',
        ]
        read_only_fields = ['id']

    def get_caller_name(self, obj):
        value = getattr(obj, 'sort_name', None)

        if value:
            return value

        if obj.caller_name:
            return obj.caller_name

        return 'Unknown'

    def get_customer(self, obj):
        customer = Customer.objects.filter(phone=obj.from_number, company=obj.company).first()
        if customer:
            return CustomerSerializer(customer).data
        return None

    def get_transfer_user(self, obj):
        advisor = obj.transfer_user
        if not advisor:
            bdc_number = obj.transfer_number
            if not bdc_number:
                return None
            return {
                'id': None,
                'name': 'BDC',
            }

        status = advisor.status_for_company(obj.company)

        resolved_name = getattr(obj, 'sort_advisor_name', None)
        if resolved_name:
            resolved_name = ProfileServices.capitalize_first_letters(resolved_name)

        return {
            "id": advisor.id,
            "name": f"{resolved_name or advisor.username or 'Unknown'}{status['suffix']}",
        }

    def get_activities(self, obj):
        """Return activities ordered descending by performed_at."""
        activities = obj.activities.order_by('-performed_at')
        return CallActivitySerializer(activities, many=True).data

    # def get_transfer_department(self, obj):
    #     phone_number = obj.transfer_number
    #     if phone_number:
    #         department = DealershipDepartment.objects.filter(
    #             phone_number=phone_number
    #         ).first()
    #         return DealershipDepartmentCallSerializer(
    #             department,
    #             read_only=True
    #         ).data
    #     return None

    def get_transcript(self, obj):
        if self.context.get('view') and self.context['view'].action == 'list':
            return ""

        return obj.transcript or ""


class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['name']


class CallActivitySerializer(serializers.ModelSerializer):
    user_fullname = serializers.SerializerMethodField()

    class Meta:
        model = CallActivity
        fields = ['user_fullname', 'action', 'performed_at', 'duration_played']

    def get_user_fullname(self, obj):
        profile = getattr(obj.user, 'profile', None)
        if profile:
            return f"{profile.first_name} {profile.last_name}"
        return None


class SalesCallDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Call
        fields = [
            'id',
            'caller_name',
            'from_number',
            'sentiment',
            'created_at'
        ]
        read_only_fields = ['id']


class SalesCallSerializer(serializers.ModelSerializer):
    caller_name = serializers.SerializerMethodField()

    name = serializers.SerializerMethodField()
    offtime = serializers.SerializerMethodField()
    customer = serializers.SerializerMethodField()
    activities = serializers.SerializerMethodField()

    class Meta:
        model = Call

        fields = [
            'id',
            'name',
            'caller_name',
            'from_number',
            'sentiment',
            'offtime',
            'created_at',
            'customer',
            'activities',
        ]
        read_only_fields = ['id']

    def get_caller_name(self, obj):
        value = getattr(obj, 'sort_name', None)

        if value:
            return value

        if obj.caller_name:
            return obj.caller_name

        return 'Unknown'

    def get_customer(self, obj):
        customer = Customer.objects.filter(phone=obj.from_number, company=obj.company).first()
        if customer:
            return CustomerSerializer(customer).data
        return None

    def get_name(self, obj):
        return obj.appointment_set.first().name if obj.appointment_set.first() else None

    def get_offtime(self, obj):
        return obj.appointment_set.first().offtime if obj.appointment_set.first() else 1

    def get_activities(self, obj):
        """Return activities ordered descending by performed_at."""
        activities = obj.activities.order_by('-performed_at')
        return CallActivitySerializer(activities, many=True).data


class TopRepeatedCallersSerializer(serializers.Serializer):
    limit = serializers.IntegerField(default=10, min_value=1, max_value=100)
    start_date = serializers.DateTimeField(required=True)
    end_date = serializers.DateTimeField(required=True)
    call_id = serializers.CharField(required=False)

    def validate(self, data):
        if data['end_date'] < data['start_date']:
            raise serializers.ValidationError("End date must be after start date")
        return data


class DateRangeSerializer(serializers.Serializer):
    start_date = serializers.DateTimeField(required=True)
    end_date = serializers.DateTimeField(required=True)

    def validate(self, data):
        start = data["start_date"]
        end = data["end_date"]

        if start > end:
            raise serializers.ValidationError("start_date must be <= end_date")

        return data


class ReadCallSerializer(serializers.Serializer):
    """Serializer for marking a call as read."""
    id = serializers.IntegerField(required=True)

    def validate_id(self, value):
        if value <= 0:
            raise serializers.ValidationError("ID must be a positive integer")
        return value
