from rest_framework import serializers
from django.contrib.auth.models import User
from .models import RegisteredMember, AttendanceRecord, ScannerAssignment


class RegisteredMemberSerializer(serializers.ModelSerializer):
    has_attended = serializers.ReadOnlyField()
    is_paid = serializers.ReadOnlyField()
    event_category_name = serializers.CharField(source='event_category.name', read_only=True)
    has_attended_event = serializers.SerializerMethodField()
    attendance_status = serializers.SerializerMethodField()
    check_in_time = serializers.SerializerMethodField()
    session_time = serializers.SerializerMethodField()
    check_out_time = serializers.SerializerMethodField()

    class Meta:
        model = RegisteredMember
        fields = [
            'id', 'registration_code', 'email', 'full_name',
            'membership_number', 'document_number',
            'event_category', 'event_category_name', 'status', 'payment_status',
            'package_name', 'package_description', 'activity_price',
            'has_attended', 'has_attended_event', 'attendance_status',
            'check_in_time', 'session_time', 'check_out_time',
            'is_paid', 'created_at', 'updated_at',
        ]

    def _get_event_id(self):
        request = self.context.get('request')
        if request:
            return request.query_params.get('event_id')
        return None

    def get_has_attended_event(self, obj):
        event_id = self._get_event_id()
        if event_id:
            return obj.attendance_records.filter(event_id=event_id, scan_type='CHECK_IN').exists()
        return obj.attendance_records.filter(scan_type='CHECK_IN').exists()

    def get_attendance_status(self, obj):
        event_id = self._get_event_id()
        if event_id:
            return obj.get_attendance_status(event_id)
        return None

    def _get_scan_time(self, obj, scan_type):
        event_id = self._get_event_id()
        if not event_id:
            return None
        record = obj.attendance_records.filter(event_id=event_id, scan_type=scan_type).first()
        return record.scan_time.isoformat() if record else None

    def get_check_in_time(self, obj):
        return self._get_scan_time(obj, 'CHECK_IN')

    def get_session_time(self, obj):
        return self._get_scan_time(obj, 'SESSION')

    def get_check_out_time(self, obj):
        return self._get_scan_time(obj, 'CHECK_OUT')


class AttendanceRecordSerializer(serializers.ModelSerializer):
    member_name = serializers.CharField(source='member.full_name', read_only=True)
    member_email = serializers.CharField(source='member.email', read_only=True)
    member_code = serializers.CharField(source='member.registration_code', read_only=True)
    event_name = serializers.CharField(source='event.name', read_only=True)
    scan_type_display = serializers.CharField(source='get_scan_type_display', read_only=True)
    recorded_by_name = serializers.SerializerMethodField()

    class Meta:
        model = AttendanceRecord
        fields = [
            'id', 'member', 'member_name', 'member_email', 'member_code',
            'event', 'event_name', 'scan_type', 'scan_type_display',
            'scan_time', 'recorded_by', 'recorded_by_name',
        ]

    def get_recorded_by_name(self, obj):
        if obj.recorded_by:
            return obj.recorded_by.get_full_name() or obj.recorded_by.username
        return None


class ScannerAssignmentSerializer(serializers.ModelSerializer):
    event_name = serializers.CharField(source='event.name', read_only=True)
    event_start_date = serializers.DateTimeField(source='event.start_date', read_only=True)
    username = serializers.CharField(source='user.username', read_only=True)

    class Meta:
        model = ScannerAssignment
        fields = ['id', 'user', 'username', 'event', 'event_name', 'event_start_date', 'is_active', 'assigned_at']


class ScanBarcodeSerializer(serializers.Serializer):
    registration_code = serializers.CharField(max_length=100)
    event_id = serializers.IntegerField()
    scan_type = serializers.ChoiceField(
        choices=['CHECK_IN', 'SESSION', 'CHECK_OUT'],
        default='CHECK_IN',
    )


class CSVUploadSerializer(serializers.Serializer):
    csv_file = serializers.FileField()
    event_category_id = serializers.IntegerField(required=False, allow_null=True)
