"""
Organization Serializers - API serialization for organizational units.
"""
from rest_framework import serializers

from .models import (
    OrganizationalUnit, OrganizationalUnitType,
    UserOrganizationalUnit, Company, BusinessPartner,
)


class OrganizationalUnitSerializer(serializers.ModelSerializer):
    """Serializer for OrganizationalUnit model."""
    
    type_display = serializers.CharField(source='get_unit_type_display', read_only=True)
    children_count = serializers.SerializerMethodField()
    full_path = serializers.SerializerMethodField()
    
    class Meta:
        model = OrganizationalUnit
        fields = [
            'id',
            'name',
            'code',
            'unit_type',
            'type_display',
            'parent',
            'path',
            'level',
            'full_path',
            'description',
            'is_active',
            'metadata',
            'children_count',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['path', 'level', 'created_at', 'updated_at']
    
    def get_children_count(self, obj):
        """Get count of direct children."""
        return obj.children.count()
    
    def get_full_path(self, obj):
        """Get full path from root to this unit."""
        return obj.full_path_names


class OrganizationalUnitTreeSerializer(serializers.ModelSerializer):
    """Serializer for OrganizationalUnit with nested children."""
    
    type_display = serializers.CharField(source='get_unit_type_display', read_only=True)
    children = serializers.SerializerMethodField()
    
    class Meta:
        model = OrganizationalUnit
        fields = [
            'id',
            'name',
            'code',
            'unit_type',
            'type_display',
            'is_active',
            'children',
        ]
    
    def get_children(self, obj):
        """Recursively serialize children."""
        children = obj.children.filter(is_active=True).order_by('name')
        return OrganizationalUnitTreeSerializer(children, many=True).data


class OrganizationalUnitCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating OrganizationalUnit."""
    
    class Meta:
        model = OrganizationalUnit
        fields = [
            'name',
            'code',
            'unit_type',
            'parent',
            'description',
            'is_active',
            'metadata',
        ]
    
    def validate_parent(self, value):
        """Validate parent exists and prevent circular references."""
        if value:
            # Check that parent is not a descendant of this unit (for updates)
            instance = getattr(self, 'instance', None)
            if instance and value.path and str(instance.id) in value.path.split('/'):
                raise serializers.ValidationError(
                    "Cannot set a descendant as parent (circular reference)."
                )
        return value
    
    def validate(self, data):
        """Additional validation."""
        parent = data.get('parent')
        unit_type = data.get('unit_type')
        
        # Type hierarchy validation
        type_hierarchy = {
            OrganizationalUnitType.COMPANY: [],  # Can be root only
            OrganizationalUnitType.BRANCH: [OrganizationalUnitType.COMPANY],
            OrganizationalUnitType.DIVISION: [
                OrganizationalUnitType.COMPANY,
                OrganizationalUnitType.BRANCH,
            ],
            OrganizationalUnitType.DEPARTMENT: [
                OrganizationalUnitType.COMPANY,
                OrganizationalUnitType.BRANCH,
                OrganizationalUnitType.DIVISION,
                OrganizationalUnitType.DEPARTMENT,
            ],
            OrganizationalUnitType.TEAM: [
                OrganizationalUnitType.DEPARTMENT,
                OrganizationalUnitType.TEAM,
            ],
            OrganizationalUnitType.COST_CENTER: [
                OrganizationalUnitType.COMPANY,
                OrganizationalUnitType.BRANCH,
                OrganizationalUnitType.DEPARTMENT,
            ],
            OrganizationalUnitType.PROJECT: [
                OrganizationalUnitType.COMPANY,
                OrganizationalUnitType.BRANCH,
                OrganizationalUnitType.DEPARTMENT,
            ],
            OrganizationalUnitType.CUSTOM: None,  # Can be anywhere
        }
        
        allowed_parents = type_hierarchy.get(unit_type)
        
        if allowed_parents is not None and len(allowed_parents) == 0:
            # Must be root
            if parent:
                raise serializers.ValidationError({
                    'parent': f'{unit_type} must be a root unit (no parent).'
                })
        elif allowed_parents is not None and parent:
            if parent.unit_type not in allowed_parents:
                raise serializers.ValidationError({
                    'parent': f'{unit_type} cannot be under {parent.unit_type}.'
                })
        
        return data


class UserOrganizationalUnitSerializer(serializers.ModelSerializer):
    """Serializer for UserOrganizationalUnit."""
    
    org_unit_name = serializers.CharField(source='organizational_unit.name', read_only=True)
    user_email = serializers.CharField(source='user.email', read_only=True)
    
    class Meta:
        model = UserOrganizationalUnit
        fields = [
            'id',
            'user',
            'user_email',
            'organizational_unit',
            'org_unit_name',
            'is_primary',
            'is_manager',
            'include_descendants',
            'start_date',
            'end_date',
            'created_at',
        ]
        read_only_fields = ['created_at']


class OrganizationalUnitAssignmentSerializer(serializers.Serializer):
    """Serializer for assigning users to organizational units."""
    
    user_id = serializers.UUIDField()
    organizational_unit_id = serializers.IntegerField()
    is_primary = serializers.BooleanField(required=False, default=False)
    is_manager = serializers.BooleanField(required=False, default=False)
    start_date = serializers.DateField(required=False, allow_null=True)
    end_date = serializers.DateField(required=False, allow_null=True)
    
    def validate(self, data):
        """Validate assignment data."""
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        
        if start_date and end_date and start_date > end_date:
            raise serializers.ValidationError({
                'end_date': 'End date must be after start date.'
            })
        
        return data


class OrganizationalUnitBulkAssignmentSerializer(serializers.Serializer):
    """Serializer for bulk user assignment to an organizational unit."""
    
    organizational_unit_id = serializers.IntegerField()
    user_ids = serializers.ListField(
        child=serializers.UUIDField(),
        min_length=1
    )
    is_manager = serializers.BooleanField(required=False, default=False)


# ─── Company Serializers ──────────────────────────────────────────────────


class CompanySerializer(serializers.ModelSerializer):
    """Serializer for Company."""

    org_unit_name = serializers.CharField(
        source="org_unit.name", read_only=True, default=None
    )
    parent_company_name = serializers.CharField(
        source="parent_company.name", read_only=True, default=None
    )
    base_currency_code = serializers.CharField(
        source="base_currency.code", read_only=True, default=None
    )

    class Meta:
        model = Company
        fields = [
            "id", "name", "name_en", "code",
            "registration_number", "national_id", "economic_code",
            "org_unit", "org_unit_name",
            "parent_company", "parent_company_name",
            "base_currency", "base_currency_code",
            "address", "city", "province", "country",
            "postal_code", "phone", "fax", "email", "website",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["created_at", "updated_at"]


class CompanyCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = [
            "name", "name_en", "code",
            "registration_number", "national_id", "economic_code",
            "org_unit", "parent_company", "base_currency",
            "address", "city", "province", "country",
            "postal_code", "phone", "fax", "email", "website",
            "is_active", "metadata",
        ]


# ─── Business Partner Serializers ─────────────────────────────────────────


class BusinessPartnerSerializer(serializers.ModelSerializer):
    """Serializer for BusinessPartner."""

    company_name = serializers.CharField(
        source="company.name", read_only=True, default=None
    )
    currency_code = serializers.CharField(
        source="currency.code", read_only=True, default=None
    )
    partner_type_display = serializers.CharField(
        source="get_partner_type_display", read_only=True
    )

    class Meta:
        model = BusinessPartner
        fields = [
            "id", "code", "name", "name_en",
            "partner_type", "partner_type_display",
            "national_id", "economic_code", "tax_id",
            "company", "company_name",
            "contact_person", "phone", "mobile", "fax", "email", "website",
            "address", "city", "province", "country", "postal_code",
            "payment_terms_days", "credit_limit",
            "currency", "currency_code",
            "bank_name", "bank_account", "sheba",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["created_at", "updated_at"]


class BusinessPartnerCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = BusinessPartner
        fields = [
            "code", "name", "name_en", "partner_type",
            "national_id", "economic_code", "tax_id",
            "company",
            "contact_person", "phone", "mobile", "fax", "email", "website",
            "address", "city", "province", "country", "postal_code",
            "payment_terms_days", "credit_limit", "currency",
            "bank_name", "bank_account", "sheba",
            "is_active", "metadata",
        ]
