from rest_framework import serializers
from .models import CompanyCalendar, ContentCalendar, DailyReport, OfficeExpense, Activity
import json

class ListToTextField(serializers.CharField):
    def to_internal_value(self, data):
        if isinstance(data, list):
            return "\n".join(str(item) for item in data)
        return super().to_internal_value(data)

    def to_representation(self, value):
        if value is None:
            return []
        if isinstance(value, str):
            return [item.strip() for item in value.split("\n") if item.strip()]
        if isinstance(value, list):
            return [str(item).strip() for item in value if str(item).strip()]
        return [str(value).strip()] if str(value).strip() else []


class ContentCalendarSerializer(serializers.ModelSerializer):
    company_id = serializers.UUIDField(write_only=True, required=False)
    company = serializers.UUIDField(write_only=True, required=False)

    class Meta:
        model = ContentCalendar
        fields = [
            'id',
            'company_id',
            'company',
            'activities',
            'content',
            'sales_order_no',
            'target_date',
            'completion_date',
            'approved',
            'remarks',
            'created_at',
            'updated_at'
        ]

    def validate(self, data):
        # Check if either company_id or company is provided
        company_id = data.get('company_id') or data.get('company')
        if not company_id:
            raise serializers.ValidationError({
                'company': 'Either company_id or company field is required.'
            })
        
        # Check if the company exists
        try:
            CompanyCalendar.objects.get(id=company_id)
        except CompanyCalendar.DoesNotExist:
            raise serializers.ValidationError({
                'company': f'Company calendar with ID {company_id} does not exist.'
            })
        
        # Remove both fields and use the company_id
        data.pop('company_id', None)
        data.pop('company', None)
        data['company_id'] = company_id
        
        return data

    def create(self, validated_data):
        company_id = validated_data.pop('company_id')
        company = CompanyCalendar.objects.get(id=company_id)  # We already validated this exists
        return ContentCalendar.objects.create(company=company, **validated_data)


class CompanyContentCalendarSerializer(serializers.ModelSerializer):
    content_calendars = ContentCalendarSerializer(many=True, read_only=True)
    handled_by = serializers.UUIDField(write_only=True, required=True)
    handled_by_id = serializers.SerializerMethodField(read_only=True)
    handled_by_name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CompanyCalendar
        fields = [
            'id',
            'client_name',
            'nature_of_business',
            'handled_by',
            'handled_by_id',
            'handled_by_name',
            'business_type',
            'responsible_person',
           
            'content_calendars',
            'created_at',
            'updated_at'
        ]

    def create(self, validated_data):
        handled_by = validated_data.pop('handled_by', None)
        instance = CompanyCalendar.objects.create(handled_by_id=handled_by, **validated_data)
        return instance

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        # Remove write_only handled_by from output
        rep.pop('handled_by', None)
        return rep

    def get_handled_by_id(self, obj):
        return str(obj.handled_by_id) if getattr(obj, 'handled_by_id', None) else None

    def get_handled_by_name(self, obj):
        handled_by = getattr(obj, 'handled_by', None)
        if handled_by and hasattr(handled_by, 'name'):
            return handled_by.name
        return None


class DailyReportSerializer(serializers.ModelSerializer):
    start_tasks = ListToTextField(required=False, allow_blank=True, allow_null=True)
    profile_name = serializers.SerializerMethodField()

    class Meta:
        model = DailyReport
        fields = [
            'id',
            'profiles',
            'profile_name',
            'date',
            'start_tasks',
            'job_order_no',
            'created_at'
        ]
        read_only_fields = ['id', 'created_at']

    def validate(self, attrs):
        start_tasks = attrs.get('start_tasks')
        job_order_no = attrs.get('job_order_no')

        # Normalize to lists for comparison
        def to_list(value):
            if value is None:
                return []
            if isinstance(value, list):
                return [str(v).strip() for v in value if str(v).strip()]
            if isinstance(value, str):
                return [v.strip() for v in value.split('\n') if v.strip()]
            return [str(value).strip()] if str(value).strip() else []

        tasks_list = to_list(start_tasks)
        jobs_list = to_list(job_order_no)

        if not tasks_list or not jobs_list:
            raise serializers.ValidationError({
                'start_tasks': 'Activities are required.',
                'job_order_no': 'Job Order No is required for each activity.'
            })

        if len(tasks_list) != len(jobs_list):
            raise serializers.ValidationError({
                'job_order_no': 'Job Order count must match activity count.'
            })

        return attrs

    def get_profile_name(self, obj):
        # Assuming 'profiles' is a FK or M2M to a Profile model with a 'name' field
        profiles = obj.profiles
        if hasattr(profiles, 'all'):
            # ManyToMany
            return [profile.name for profile in profiles.all()]
        elif hasattr(profiles, 'name'):
            # ForeignKey
            return profiles.name
        return None


class OfficeExpenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = OfficeExpense
        fields = ['id', 'date', 'expence', 'debit', 'credit', 'created_at']


class ActivitySerializer(serializers.ModelSerializer):
    assigned_to_name = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()
    
    class Meta:
        model = Activity
        fields = [
            'id',
            'title',
            'description',
            'status',
            'assigned_to',
            'assigned_to_name',
            'created_by',
            'created_by_name',
            'due_date',
            'completed_at',
            'created_at',
            'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def get_assigned_to_name(self, obj):
        if obj.assigned_to and hasattr(obj.assigned_to, 'name'):
            return obj.assigned_to.name
        return None

    def get_created_by_name(self, obj):
        if obj.created_by and hasattr(obj.created_by, 'name'):
            return obj.created_by.name
        return None