
from rest_framework import serializers
from organisations.models import *
from ussdbanking.models import MMServiceProvider
from datetime import datetime,timedelta
import pytz

class OrganisationTypeSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = OrganisationType
        fields = '__all__'

class OrganisationBranchSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    date_added = serializers.DateTimeField(read_only=True)
    added_by = serializers.IntegerField(read_only=True)
    branch_organisation = serializers.PrimaryKeyRelatedField(read_only=True, required=False)
    
    class Meta:
        model = OrganisationBranch
        fields = '__all__'

class OrganisationComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrganisationComponent
        fields = '__all__' 
        
class NullableIntegerField(serializers.IntegerField):
    def to_internal_value(self, data):
        if data in ("", None):
            return None
        return super().to_internal_value(data)

class OrganisationSerializer(serializers.ModelSerializer):
    # Read-only fields
    id = serializers.IntegerField(read_only=True)
    date_added = serializers.DateTimeField(read_only=True)
    organisation_added_by = serializers.IntegerField(read_only=True)

    # Nested serializers
    organisation_type = OrganisationTypeSerializer(read_only=True)
    organisation_type_id = serializers.PrimaryKeyRelatedField(
        queryset=OrganisationType.objects.all(), source='organisation_type', write_only=False, required=False
    )
    organisation_branches = OrganisationBranchSerializer(many=True, read_only=True)

    # SerializerMethodFields
    org_components_count = serializers.SerializerMethodField()
    unit_sms_cost = serializers.SerializerMethodField()
    use_old_mem_no = serializers.SerializerMethodField()
    mm_provider = serializers.SerializerMethodField()

    # Admin organisation info
    admin_organisation_name = serializers.CharField(required=False, read_only=True, source="admin_organisation.name")
    admin_organisation_id = serializers.CharField(required=False, read_only=True, source="admin_organisation.id")

    # Nullable fields
    mse_name = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    year_established = NullableIntegerField(required=False, allow_null=True)
    group_leader_name = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    certificate_of_incorporation = serializers.FileField(required=False, allow_null=True)
    bds_provider = serializers.CharField(required=False, allow_null=True, allow_blank=True)

    # CRB activation field
    is_crb_active = serializers.BooleanField(required=False, default=False)
    # Mobile app activation field
    is_mobile_app_active = serializers.BooleanField(required=False, default=False)

    def get_org_components_count(self, obj):
        return OrganisationComponent.objects.filter(
            component_org=obj,
            system_component__is_active=True,
            is_active=True
        ).count()

    def get_unit_sms_cost(self, obj):
        unit_sms_cost_obj = OrganisationSetting.objects.filter(
            org_setting=obj, setting_key='unit_sms_cost'
        ).first()
        return unit_sms_cost_obj.setting_value if unit_sms_cost_obj else 0
    
    # def validate_year_established(self, value):
    #     if value in ("", None):
    #         return None
    #     try:
    #         return int(value)
    #     except (ValueError, TypeError):
    #       raise serializers.ValidationError("A valid integer is required.")

    def get_mm_provider(self, obj):
        provider_id = ""
        provider_name = ""
        status = "inactive"
        account_number = ''

        mm_provider_obj = OrganisationSetting.objects.filter(org_setting=obj, setting_key='mm_provider').first()
        mm_status_obj = OrganisationSetting.objects.filter(org_setting=obj, setting_key='mm_status').first()
        mm_account_number = OrganisationSetting.objects.filter(org_setting=obj, setting_key='mm_provider_account_number').first()

        if mm_status_obj:
            status = mm_status_obj.setting_value
        if mm_provider_obj:
            provider_id = mm_provider_obj.setting_value
            provider = MMServiceProvider.objects.filter(id=provider_id).first()
            if provider:
                provider_name = provider.name
        if mm_account_number:
            account_number = mm_account_number.setting_value

        return {
            "provider_id": provider_id,
            "provider_name": provider_name,
            "status": status,
            "account_number": account_number
        }

    def get_use_old_mem_no(self, obj):
        use_old_mem_no_obj = OrganisationSetting.objects.filter(org_setting=obj, setting_key='use_old_mem_no').first()
        return use_old_mem_no_obj.setting_value if use_old_mem_no_obj else 'off'
    def update(self, instance, validated_data):
        from customers.models import Customer  # adjust import as needed

        old_is_trained = instance.is_trained
        new_is_trained = validated_data.get('is_trained', old_is_trained)

        instance = super().update(instance, validated_data)

        # Only run this logic for Finwise organisations
        # org_type_name = getattr(instance.organisation_type, 'org_type', '').strip().lower()

        # ✅ Only for Finwise-type orgs (org_type == "MSE" and admin_organisation == Finwise)
        if 'finwise' in (instance.admin_organisation.name or '').lower():
            # Only trigger when training status changes from False → True
            if not old_is_trained and new_is_trained:
                Customer.objects.filter(customer_branch__branch_organisation=instance).update(
                    is_trained=True,
                    training_date=instance.training_date or timezone.now().date()
                )

        return instance
    class Meta:
        model = Organisation
        fields = '__all__'

        
class SystemComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = SystemComponent
        fields = '__all__' 

class UserRoleSerializer(serializers.ModelSerializer):
    role_org      = serializers.CharField(required=False,read_only=True)
    role_added_by = serializers.CharField(required=False,read_only=True)
    components_count = serializers.SerializerMethodField()

    def get_components_count(self, obj):
        component_ids = []
        role_components = RoleComponent.objects.filter(user_role=obj,org_component__system_component__is_active=True,is_active=True)
        for role_component in role_components:
              component_ids.append(role_component.org_component.system_component.id)
        modules = OrganisationFeature.objects.filter(org_id =obj.role_org.id,component_id__in=component_ids,is_active = True,is_feature_active = True).all()
        return len(modules)

    class Meta:
        model = UserRole
        fields = '__all__' 

class RoleComponentSerializer(serializers.ModelSerializer):
    user_role      = serializers.CharField(required=False,read_only=True)
    role_component_added_by  = serializers.CharField(required=False,read_only=True)
    org_component  = serializers.CharField(required=False,read_only=True)
    org_component_id  = serializers.CharField(read_only=True, source="org_component.id")
    class Meta:
        model = RoleComponent
        fields = '__all__' 

class OrganisationSettingSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    date_added = serializers.DateTimeField(read_only=True)
    setting_added_by = serializers.CharField(read_only=True)
    org_setting = serializers.CharField(read_only=True)

    class Meta:
        model = OrganisationSetting
        fields = '__all__'

def get_license_details(subscription_date,organisation_name):
        eat_timezone = pytz.timezone("Africa/Nairobi")
        transaction_date=datetime.strptime(subscription_date.astimezone(eat_timezone).strftime('%Y-%m-%d'), '%Y-%m-%d')
        current_date=datetime.strptime(datetime.now().astimezone(eat_timezone).strftime('%Y-%m-%d'), '%Y-%m-%d')
        past_days = ((current_date - transaction_date).days)
        next_payment_date = subscription_date.astimezone(eat_timezone) + timedelta(days = past_days)
        return {
                "past_days":past_days,
                "organisation_name":organisation_name,
                "next_payment_date":next_payment_date
               }

class LicenseSettingSerializer(serializers.ModelSerializer):
    license_details = serializers.SerializerMethodField()

    class Meta:
        model = LicenseSettings
        fields = '__all__'

    def get_license_details(self, obj):
        subscription_date = obj.subcription_date
        organisation_name = obj.license_org.name
        return get_license_details(subscription_date, organisation_name)

class WorkingHoursSerializer(serializers.ModelSerializer):
    class Meta:
        model = WorkingHours
        fields = '__all__'

class StaffWorkingHoursSerializer(serializers.ModelSerializer):
    class Meta:
        model=StaffWorkingHours
        fields='__all__'


class VoucherConfigSerializer(serializers.ModelSerializer):
    class Meta:
        model=VoucherConfig
        fields='__all__'


class OrganisationLocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrganisationLocation
        fields = '__all__'
        read_only_fields = ('organisation', 'added_by', 'date_added')
