import pandas as pd
from django.db.models import Q
from payrollservice.data.response.paycomponentsegmentmappingresponse import PaycomponentsegmentmappingResponse
from payrollservice.models import PaycomponentSegmentmapping
from payrollservice.service.payrollmastersservice import SegmentMasterService, PayrollComponentService
from payrollservice.util.payrollutil import Activestatus, category_val
from utilityservice.data.response.nwisefinlist import NWisefinList
from utilityservice.data.response.nwisefinpaginator import NWisefinPaginator
from utilityservice.service.applicationconstants import ApplicationNamespace
from utilityservice.service.threadlocal import NWisefinThread
from utilityservice.data.response.nwisefinerror import NWisefinError
from utilityservice.data.response.nwisefinerrorconstants import ErrorDescription, ErrorMessage
from utilityservice.data.response.nwisefinsuccess import SuccessStatus,SuccessMessage,NWisefinSuccess



class PayrollSegementMappingService(NWisefinThread):
    def __init__(self, scope):
        super().__init__(scope)
        self._set_namespace(ApplicationNamespace.PAYROLL_SERVICE)

    def create_paycompseg_mapping(self, data_obj, user_id):
        success_obj = NWisefinSuccess()
        check_id = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(paycomponent_id=data_obj.get_paycomponent_id(),segment_id=data_obj.get_segment_id(),status=Activestatus.active)
        if not check_id:
            if not data_obj.get_id() is None:
                obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(id=data_obj.get_id()).update(paycomponent_id=data_obj.get_paycomponent_id(),
                                                                                                                            segment_id=data_obj.get_segment_id(),
                                                                                                                            created_by=user_id)

                obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).get(id=data_obj.get_id())
                success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
                success_obj.set_status(SuccessStatus.SUCCESS)
            else:
                obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).create(paycomponent_id=data_obj.get_paycomponent_id(),
                                                                                                  segment_id=data_obj.get_segment_id(),
                                                                                                  created_by=user_id,
                                                                                                  entity_id=self._entity_id())
                success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
                success_obj.set_status(SuccessStatus.SUCCESS)
        else:
            success_obj.set_message('segment is already mapped')
        return success_obj

    def paycompsegmapping_summary(self, vys_page,request):
        try:
            seg_name = request.GET.get('name')
            condition = Q(status=Activestatus.active, entity_id=self._entity_id())
            if seg_name != None and seg_name != '':
                seg_id = SegmentMasterService(self._scope()).get_segment_name_ids(seg_name)
                condition &= Q(segment_id__in=seg_id)
            paysegmap_obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(condition)[vys_page.get_offset():vys_page.get_query_limit()]
            # paycomponent_obj = [i.paycomponent_id for i in paysegmap_obj]
            # paycomponent_data = PayrollComponentService(self._scope()).get_multiple_payroll_component(paycomponent_obj)
            segment_obj = [i.segment_id for i in paysegmap_obj]
            segment_data = SegmentMasterService(self._scope()).get_multiple_segment_data(segment_obj)
            list_data = NWisefinList()
            for i in paysegmap_obj:
                data_resp = PaycomponentsegmentmappingResponse()
                data_resp.set_id(i.id)
                data_resp.set_paycomponent_id(i.paycomponent.id)
                data_resp.paycomponent_percentage = str(i.paycomponent.percentage)
                data_resp.paycomponent_name = i.paycomponent.name
                data_resp.set_segment_data(i.segment.id, segment_data)
                list_data.append(data_resp)
            v_page = NWisefinPaginator(paysegmap_obj, vys_page.get_index(), 10)
            list_data.set_pagination(v_page)
            return list_data
        except Exception as excep:
            obj = NWisefinError()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj


    def get_paysegment_data(self, payseg_id):
        try:
            obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).get(status=Activestatus.active,id=payseg_id)
            data_res=PaycomponentsegmentmappingResponse()
            data_res.set_id(obj.id)
            data_res.set_segment_id(obj.segment.id)
            data_res.segment_name = obj.segment.name
            data_res.paycomponent_id = obj.paycomponent.id
            data_res.set_paycomponent_id(obj.paycomponent.name)
            data_res.paycomponent_percentage = str(obj.paycomponent.percentage)
            return data_res
        except Exception as excep:
            obj = NWisefinError()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj


    def inactivate_paysegemaping(self, payseg_id):
        obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(id=payseg_id).update(status=Activestatus.inactive)
        if obj!= 0:
            success = NWisefinSuccess()
            success.set_status(SuccessStatus.SUCCESS)
            success.set_message(SuccessMessage.DELETE_MESSAGE)
            return success
        else:
            error = NWisefinError()
            error.set_code(ErrorMessage.INVALID_DATA)
            error.set_description(ErrorDescription.INVALID_DATA)
            return error

    def get_segment_and_paycomponent_id(self,map_id):
        obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active,segment_id=map_id)
        arr = []
        for i in obj:
            data_resp = PaycomponentsegmentmappingResponse()
            data_resp.set_segment_id(i.segment.id)
            data_resp.segment_percentage = i.segment.percentage
            data_resp.set_paycomponent_id(i.paycomponent.id)
            arr.append(data_resp)
        return arr

    def get_segment_data(self,segment_id):
        obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(segment_id__in=segment_id,
                                                                                          status=Activestatus.active,
                                                                                          entity_id=self._entity_id())
        arr = []
        for i in obj:
            data_resp = PaycomponentsegmentmappingResponse()
            data_resp.set_paycomponent_id(i.paycomponent.id)
            data_resp.paycomponent_name = i.paycomponent.name
            data_resp.paycomponent_percentage =str(i.paycomponent.percentage)
            data_resp.segment_id = i.segment.id
            data_resp.segment_name = i.segment.name
            data_resp.segment_percentage = str(i.segment.percentage)
            data_resp.component_type = i.segment.component_type.name
            data_resp.component_category_type = category_val(i.segment.component_type.category)['category']
            arr.append(data_resp)
        return arr

    def strcut_uploadteam_segmentdetails(self):
        obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active)
        obj_df = pd.DataFrame(obj.values('segment__name', 'segment__percentage', 'paycomponent__name'))
        data_df1 = obj_df.rename(columns={'segment__name': 'segment', 'segment__percentage': 'segment_percentage', 'paycomponent__name': 'paycomponent'})
        return data_df1


    def segmentmapping_upload(self,paycomsegment_mapping_data, user_id):
        try:
            success_obj = NWisefinSuccess()
            paycomponent_id = PayrollComponentService(self._scope()).get_payrollcomponent_val(paycomsegment_mapping_data['PAYCOMPONENT'])
            segment_id = SegmentMasterService(self._scope()).get_segment_name(paycomsegment_mapping_data['SEGMENT'])
            obj = PaycomponentSegmentmapping.objects.using(self._current_app_schema()).create(
                                                                        paycomponent_id=paycomponent_id,
                                                                        segment_id=segment_id,
                                                                        created_by=user_id,
                                                                        entity_id=self._entity_id())
            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
            success_obj.set_status(SuccessStatus.SUCCESS)
            return success_obj
        except Exception as excep:
            obj = NWisefinError()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj