
from django.utils import timezone

import pandas as pd

# from masterservice.models import Grade
from payrollservice.data.response.payrollmastermappingresponse import PayrollmastersmappingResponse
from payrollservice.models import Payrollmastersmapping, Segment, PayrollComponent
from payrollservice.service.payrollmastersservice import PayrollComponentService, SegmentMasterService
from payrollservice.service.payrolltemplateservice import PayrollTemplateService
from payrollservice.util.payrollutil import Activestatus
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
from django.db.models import Q
from utilityservice.data.response.nwisefinlist import NWisefinList
from utilityservice.data.response.nwisefinpaginator import NWisefinPaginator
from hrmsmasterapiservice.hrmsmasterapi.masteranduserserviceapi import HrmsApiService


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

    def create_payrollmastermapping(self,data_obj,user_id):
        success_obj = NWisefinSuccess()
        if not data_obj.get_id() is None:
            obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(id=data_obj.get_id()).update(template=data_obj.get_template_id(),
                                                                                                                      segment=data_obj.get_segment_id(),
                                                                                                                      paycomponent=data_obj.get_paycomponent_id(),
                                                                                                                      percentage=data_obj.get_percentage(),
                                                                                                                      amount=data_obj.get_amount(),
                                                                                                                      updated_by=user_id,
                                                                                                                      updated_date=timezone.now())
            obj = Payrollmastersmapping.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 = Payrollmastersmapping.objects.using(self._current_app_schema()).create(template_id=data_obj.get_template_id(),
                                                                                          segment=data_obj.get_segment_id(),
                                                                                          paycomponent=data_obj.get_paycomponent_id(),
                                                                                          percentage=data_obj.get_percentage(),
                                                                                          amount=data_obj.get_amount(),
                                                                                          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

    def payrollmastermapping_summary(self, vys_page):
        condition = Q(status=Activestatus.active)
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(condition)[vys_page.get_offset():vys_page.get_query_limit()]
        paycomponent_id = [i.paycomponent for i in obj]
        segment_id = [i.segment for i in obj]
        template_id = [i.template_id for i in obj]
        paycomponent_data = PayrollComponentService(self._scope()).get_multiple_payroll_component(paycomponent_id)
        segment_data = SegmentMasterService(self._scope()).get_multiple_segment_data(segment_id)
        template_data = PayrollTemplateService(self._scope()).get_multiple_template_data(template_id)
        list_data = NWisefinList()
        for i in obj:
            data_resp = PayrollmastersmappingResponse()
            data_resp.set_id(i.id)
            # data_resp.set_segment_id(i.segment)
            data_resp.set_segment_data(i.segment, segment_data)
            data_resp.set_percentage(i.percentage)
            # data_resp.set_template_id(i.template.id)
            data_resp.set_template_data(i.template_id, template_data)
            data_resp.set_amount(i.amount)
            data_resp.set_paycomponent_data(i.paycomponent, paycomponent_data)
            list_data.append(data_resp)
        v_page = NWisefinPaginator(obj, vys_page.get_index(), 10)
        list_data.set_pagination(v_page)
        return list_data

    def get_payrollmastermapping_data(self, paymastermapping_id):
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).get(status=Activestatus.active, id=paymastermapping_id)
        data_resp = PayrollmastersmappingResponse()
        data_resp.set_id(obj.id)
        data_resp.set_amount(obj.amount)
        data_resp.set_template_id(obj.template.id)
        data_resp.set_percentage(obj.percentage)
        data_resp.set_paycompoent_id(obj.paycomponent)
        return data_resp

    def inactive_payrollmastermapping(self, paymastermapping_id):
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(id=paymastermapping_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 auto_create_mastermapping(self, template_id, segment_id,paycomponent,segment_percentage,user_id):
        resp = NWisefinSuccess()
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                                      template_id=template_id,
                                                                                      segment=segment_id,
                                                                                      paycomponent=paycomponent)
        if len(obj) != 0:
            for i in obj:
                id_data = i.id
                if id_data is not None:
                    flag_data = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(
                        id=id_data).update(
                        template_id=template_id,
                        segment=segment_id,
                        paycomponent=paycomponent,
                        percentage=segment_percentage,
                        amount='0.0',
                        updated_by=user_id,
                        updated_date=timezone.now())

                    flag_data = Payrollmastersmapping.objects.using(self._current_app_schema()).get(id=id_data)
                    resp = SuccessMessage.UPDATE_MESSAGE
        else:
            obj = Payrollmastersmapping.objects.using(self._current_app_schema()).create(template_id=template_id,
                                                                                     segment=segment_id,
                                                                                     paycomponent=paycomponent,
                                                                                     percentage=segment_percentage,
                                                                                     amount='0.0',
                                                                                     created_by=user_id,
                                                                                     entity_id=self._entity_id())
            message = SuccessMessage.CREATE_MESSAGE
            resp.set_status(SuccessStatus.SUCCESS)
            resp.set_message(message)
            resp.map_id = obj.id
        return resp


    def get_segment_based_paycom(self, paycomponent_id):
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active, paycomponent=paycomponent_id)
        if len(obj) > 0:
            arr = obj.values('segment')
        else:
            arr = []
        return arr

    def get_template_based_segment(self):
        template_data = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active)
        template_df = pd.DataFrame(template_data.values('template__name','template__grade','segment','paycomponent'))
        grade_id = [i.template.grade for i in template_data]
        segment_id = [i.segment for i in template_data]
        # grade_data = Grade.objects.using(self._current_app_schema()).filter(status=Activestatus.active,id__in=grade_id)
        # garde_df = pd.DataFrame(grade_data.values('id','name'))
        garde_df = HrmsApiService(self._scope()).get_grade_dataframe({'status':Activestatus.active,'id':grade_id})
        final_df3 = template_df.merge(garde_df, left_on='template__grade', right_on='id', how='inner')
        segment_data = Segment.objects.using(self._current_app_schema()).filter(status=Activestatus.active,id__in=segment_id)
        segment_df = pd.DataFrame(segment_data.values('id','name'))
        paycom_id = [i.paycomponent for i in template_data]
        paycom_data = PayrollComponent.objects.using(self._current_app_schema()).filter(status=Activestatus.active,id__in=paycom_id)
        paycom_df = pd.DataFrame(paycom_data.values('id','name'))
        final_df1 = final_df3.merge(segment_df, left_on='segment', right_on='id', how='inner')
        final_df2 = final_df1.merge(paycom_df, left_on='paycomponent', right_on='id', how='inner')
        final_df = final_df2.drop(columns=['template__grade','segment','paycomponent','id_x','id_y','id'])
        data_df = final_df.rename(columns={'template__name': 'template', 'name_x': 'grade','name_y': 'segment','name':'paycomponent'})
        return data_df


    def inactive_payrollmastermapp(self,template_id,segment_id):
        obj = Payrollmastersmapping.objects.using(self._current_app_schema()).filter(status=Activestatus.active,template_id=template_id,
                                                                                     segment=segment_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


