import json
from datetime import datetime
import pandas as pd
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from payrollservice.data.request.empmonthlypaydetailsrequest import Employeemonthlypay_detailsRequest
from payrollservice.data.request.empmonthlypayinforequest import Employeemonthly_payinfoRequest
from payrollservice.service.empmonthlypaydetailsservice import Employeemonthlypay_detailsService
from payrollservice.service.empmonthlypayinfoservice import EmployeemonthlypayService
from utilityservice.data.response.nwisefinerror import NWisefinError
from utilityservice.data.response.nwisefinlist import NWisefinList
from utilityservice.data.response.nwisefinpage import NWisefinPage
# from utilityservice.service.nwisefinauthenticate import NWisefinAuthentication
from common_middleware.request_middleware import NWisefinAuthentication
from utilityservice.service.nwisefinpermission import NWisefinPermission

# Employeemonthly_payinfo,Employeemonthlypay_details
@csrf_exempt
@api_view(['POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated,NWisefinPermission])
def create_employeemonthly(request):
    scope = request.scope
    if request.method == 'POST':
        data_json = json.loads(request.body)
        employee_request = Employeemonthly_payinfoRequest(data_json)
        user_id = request.employee_id
        empmonth_service = EmployeemonthlypayService(scope)
        empmonth_detail = Employeemonthlypay_detailsService(scope)
        detail_arr = data_json.get("Employeemonthlypay_details_data")
        resp_obj = empmonth_service.create_employeemonth_payinfo(request, employee_request, user_id)
        data = resp_obj.id
        gross_pay = resp_obj.gross_pay
        for emp_detail in detail_arr:
            detail_obj = Employeemonthlypay_detailsRequest(emp_detail)
            data_obj = empmonth_detail.create_employeemonthly_detail(request, detail_obj, user_id,data, gross_pay)
        response = HttpResponse(resp_obj.get(), content_type="application/json")
        return response



#EMPLOYEEMONTHLY_PAY AND EMPLOYEEMONTHLY_DETAILS SUMMARY
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def employee_monthly_summary(request):
    scope = request.scope
    if request.method == 'GET':
        emp_id = request.GET.get('employee_id')
        payroll_serv = EmployeemonthlypayService(scope).employeemonth_pay_level_get(emp_id)
        arr = NWisefinList()
        if len(payroll_serv) > 0:
            employeemonth_pay = EmployeemonthlypayService(scope).employeemonthly_pay_get(payroll_serv[0].id)
            employeemonthpay_detail = Employeemonthlypay_detailsService(scope).employeemonthlypay_detail_get(payroll_serv[0].id)
            employeemonth_pay.Employeemonthlypay_details_data = employeemonthpay_detail
            arr.append(employeemonth_pay)
            response = HttpResponse(arr.get(), content_type='application/json')
            return response
        else:
            arr = NWisefinList()
            return HttpResponse(arr.get(), content_type='application/json')



@csrf_exempt
@api_view(['GET', 'DELETE'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def employeemonthlypay_detail_inactive(request, paymonth_id):
    scope = request.scope
    if request.method == 'GET':
        arr = NWisefinList()
        employee_pay = EmployeemonthlypayService(scope).employeemonthly_pay_get(paymonth_id)
        employee_details = Employeemonthlypay_detailsService(scope).employeemonthlypay_detail_get(employee_pay.id)
        employee_pay.Employeemonthlypay_details_data = employee_details
        arr.append(employee_pay)
        response = HttpResponse(arr.get(), content_type='application/json')
        return response
    elif request.method == 'DELETE':
        action = request.GET.get('action', None)
        if action == '0':
            user_id = request.employee_id
            payroll_serv = EmployeemonthlypayService(scope).employeemonthly_pay_inactive(paymonth_id, user_id)
            return HttpResponse(payroll_serv.get(),content_type='application/json')
        elif action == '1':
            user_id = request.employee_id
            payroll_serv = Employeemonthlypay_detailsService(scope).employeemonthly_detail_inactive(paymonth_id, user_id)
            return HttpResponse(payroll_serv.get(), content_type='application/json')


# Get Employeemonthly_payinfo,Employeemonthlypay_details
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def employeemonthpay_fetch(request):
    scope = request.scope
    action = request.GET.get('action')
    if request.method == 'GET':
        if action in ('1','0'):
            if action == '0':
                empmonth_service = EmployeemonthlypayService(scope)
                employee_id = request.GET.get('employee_id')
                month = request.GET.get('month')
                year = request.GET.get('year')
                info_id = request.GET.get('info_id')
                resp = empmonth_service.employeemonthpay_fetch(request, employee_id, month,year,info_id)
                response = HttpResponse(resp.get(), content_type="application/json")
                return response
            elif action == '1':
                empmonth_service = EmployeemonthlypayService(scope)
                employee_id = request.GET.get('employee_id')
                month = request.GET.get('month')
                year = request.GET.get('year')
                info_id = request.GET.get('info_id')
                resp = empmonth_service.employeemonthpay_fetch(request, employee_id, month, year, info_id)
                data = resp.get()
                _json_data = json.loads(data)
                payroll_serv = empmonth_service.common_pdf_function(_json_data)
                return payroll_serv
        else:
            error_obj = NWisefinError()
            error_obj.set_message('invalid inputs')
            response = HttpResponse(error_obj.get(), "application/json")
            return response
# segment based Get Employeemonthly_payinfo,Employeemonthlypay_details
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def segment_employeemonthpay_fetch(request):
    scope = request.scope
    if request.method == 'GET':
        empmonth_service = EmployeemonthlypayService(scope)
        employee_id = request.GET.get('employee_id')
        month = request.GET.get('month')
        year = request.GET.get('year')
        info_id = request.GET.get('info_id')
        resp = empmonth_service.segment_employeemonthpay_fetch(request, employee_id, month,year,info_id)
        response = HttpResponse(resp.get(), content_type="application/json")
        return response


 # summary Employeemonthly_payinfo,Employeemonthlypay_details,Employeemonthlypay_deductions
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def employeemonthpay_summary(request):
    scope = request.scope
    if request.method == 'GET':
        action = request.GET.get('action', None)
        if action in ('1','0'):
            if action == '0':
                page = request.GET.get('page', 1)
                page = int(page)
                vys_page = NWisefinPage(page, 10)
                user_id = request.employee_id
                empmonth_service = EmployeemonthlypayService(scope)
                resp = empmonth_service.employeemonthpay_summary(request, vys_page,user_id)
                response = HttpResponse(resp.get(), content_type="application/json")
                return response
            elif action == '1':
                empmonth_service = EmployeemonthlypayService(scope)
                user_id = request.employee_id
                resp = empmonth_service.employeemonthpay_excel(request,user_id)
                data = resp.get()
                datatodf = json.loads(data)
                payroll_df = datatodf.get('data')
                payroll_data = pd.DataFrame(payroll_df)
                df1 = payroll_data.reset_index()
                df = df1.rename(columns={"index": "S.No"})
                df['S.No'] = df.index + 1
                if df.empty:
                    finaldf = ['S.No', 'EmployeeCode','EmployeeName', 'Accountnumber', 'Month','Paid Days', 'Net Pay','remarks','paid_date', 'Bank', 'BankBranch', 'ifsccode']#'NetAmount','TakeHome']
                    df = pd.DataFrame(columns=finaldf)
                else:
                    df = df[['S.No', 'EmployeeCode','EmployeeName', 'accountnumber', 'Month', 'paid_days','Net_Pay','remarks','paid_date', 'Bank', 'BankBranch', 'ifsccode']]
                    df.columns = ['S.No', 'EmployeeCode','EmployeeName', 'Accountnumber', 'Month','Paid Days', 'Net Pay','remarks','paid_date', 'Bank', 'BankBranch', 'ifsccode']# 'NetAmount', 'TakeHome']
                excel = 'application/vnd.ms-excel'
                response = HttpResponse(content_type=excel)
                filename = 'PayRoll_Report' + str(datetime.now())
                response['Content-Disposition'] = 'attachment; filename="' + filename + '.xlsx"'
                writer = pd.ExcelWriter(response, engine='xlsxwriter')
                df.to_excel(writer, index=False)
                writer.close()
                return HttpResponse(response)
        else:
            error_obj = NWisefinError()
            error_obj.set_message('invalid inputs')
            response = HttpResponse(error_obj.get(), "application/json")
            return response

# details_manual_run
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def details_manual_run(request):
    scope = request.scope
    if request.method == 'GET':
        resp = EmployeemonthlypayService(scope).details_manual_run()
        response = HttpResponse(resp.get(), content_type='application/json')
        return response


@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payroll_manual_run(request):
    scope = request.scope
    if request.method == 'GET':
        resp = EmployeemonthlypayService(scope).payroll_manual_run(request)
        response = HttpResponse(resp.get(), content_type='application/json')
        return response


@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def monthly_deduction_calculation(request):
    scope = request.scope
    if request.method == 'GET':
        employee_id = request.GET.get('employee_id')
        paycomponent_id = request.GET.get('paycomponent_id')
        month = request.GET.get('month')
        year = request.GET.get('year')
        payroll_serv = EmployeemonthlypayService(scope).monthly_deduction_calculation(employee_id, paycomponent_id,month,year)
        response = HttpResponse(payroll_serv, content_type='application/json')
        return response


@csrf_exempt
@api_view(['POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def create_month_details_create(request):
    scope = request.scope
    empmonth_service = EmployeemonthlypayService(scope)
    if request.method == 'POST':
        data_json = json.loads(request.body)
        user_id = request.employee_id
        employee = request.GET.get('employee')
        month = request.GET.get('month')
        empmonth_request = Employeemonthlypay_detailsRequest(data_json)
        data_obj = empmonth_service.create_month_details_create(employee,month,user_id,empmonth_request)
        response = HttpResponse(data_obj.get(), content_type="application/json")
        return response


@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def emp_manual_run(request):
    scope = request.scope
    if request.method == 'GET':
        resp = EmployeemonthlypayService(scope).emp_manual_run()
        response = HttpResponse(resp.get(), content_type='application/json')
        return response


@csrf_exempt
@api_view(['POST','GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def monthlyinfo_update_getids(request):
    scope = request.scope
    if request.method == 'POST':
        data_json = json.loads(request.body)
        user_id =request.employee_id
        addition_serv = EmployeemonthlypayService(scope).pay_status_update(user_id,data_json)
        return HttpResponse(addition_serv.get(), content_type='application/json')
    elif request.method == 'GET':
        month = request.GET.get('month')
        year = request.GET.get('year')
        addition_serv = EmployeemonthlypayService(scope).get_monthlyinfo_id(month,year)
        return HttpResponse(addition_serv, content_type='application/json')


@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def approving_level_get(request):
    scope = request.scope
    if request.method == 'GET':
        ref_id = request.GET.get('ref_id')
        payroll_serv = EmployeemonthlypayService(scope).approving_level_get(ref_id)
        response = HttpResponse(payroll_serv.get(), content_type='application/json')
        return response


# cc_bs_based_payrollget
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payapproved_ccbs_payrollget(request):
    scope = request.scope
    if request.method == 'GET':
        month = request.GET.get('month')
        year = request.GET.get('year')
        payroll_serv = EmployeemonthlypayService(scope).payapproved_ccbs_payrollget(month,year)
        response = HttpResponse(payroll_serv.get(), content_type='application/json')
        return response

# approvel_bank_info_template Download
@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def approvel_bank_template_download(request):
    scope = request.scope
    if request.method == 'GET':
        month = request.GET.get('month')
        year = request.GET.get('year')
        excel = request.GET.get('excel', 0)
        page = request.GET.get('page', 1)
        page = int(page)
        vys_page = NWisefinPage(page, 10)
        payroll_serv = EmployeemonthlypayService(scope).approvel_bank_template_download(month,year,vys_page)
        if excel:
            data = payroll_serv.get()
            datatodf = json.loads(data)
            payroll_df = datatodf.get('data')
            payroll_data = pd.DataFrame(payroll_df)
            data_df1 = payroll_data.rename(columns={'EmployeeCode':'Employee Code','EmployeeName':'Employee Name','payroll_date':'AccuralMonth/year','ref_id':'Approval Id','accountnumber':'Bank A/C no','Bank':'Bank_name','BankBranch':'Branch name','ifsccode':'IFSCCODE','Payable_TK_home_Bonus':'Payable- TK home with Bonus','Sum_of_Paid':'Sum of Paid','Balance_payable':'Balance payable'})
            extra_data = ['Bank paid','A/c no','Bank name','IFSC','Date of payment','Reason']
            extra_df = pd.DataFrame(columns=extra_data)
            bank_df= pd.concat([data_df1 , extra_df], ignore_index=True)
            df1 = bank_df.reset_index()
            df = df1.rename(columns={"index": "S.No"})
            df['S.No'] = df.index + 1
            if df.empty:
                finaldf = ['S.NO','Employee Code','Employee Name','AccuralMonth/year','Approval Id','Bank A/C no','Bank name','Branch name','IFSC','Payable- TK home with Bonus','Sum of Paid','Balance payable','Bank paid','A/c no','Bank name','IFSC','Date of payment','Reason']
                df = pd.DataFrame(columns=finaldf)
            else:
                df = df[['S.No','Approval_date','Employee Code','Employee Name','AccuralMonth/year','Approval Id','Bank A/C no','Bank_name','Branch name','IFSCCODE','Payable- TK home with Bonus','Sum of Paid','Balance payable','Bank paid','A/c no','Bank name','IFSC','Date of payment','Reason']]
            excel = 'application/vnd.ms-excel'
            response = HttpResponse(content_type=excel)
            filename = 'Bank upload' + str(datetime.now())
            response['Content-Disposition'] = f'attachment; filename="{str(filename) + ".xlsx"}"'
            writer = pd.ExcelWriter(response, engine='xlsxwriter')
            df.to_excel(writer, index=False)
            worksheet = writer.sheets['Sheet1']
            workbook = writer.book
            header_format = workbook.add_format({'bold': True, 'size': 11, 'align': 'center', 'fg_color': '21CBE5'})
            worksheet.merge_range("N2:S2", 'Blank to be filled and uploaded', header_format)
            writer.close()
            return HttpResponse(response)
        else:
            response = HttpResponse(payroll_serv.get(), content_type='application/json')
            return response


@csrf_exempt
@api_view(['GET','POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payroll_test_upload(request):
    scope = request.scope
    if request.method == 'POST':
        user_id = request.employee_id
        files = request.FILES.get('file')
        check_extension = files.name.split(".")[1]
        if check_extension == "xlsx":
            file_read = pd.read_excel(files)
        else:
            file_read = pd.read_csv(files)
        payroll_serv = EmployeemonthlypayService(scope).payroll_test_upload(file_read,user_id)
        response = HttpResponse(payroll_serv.get(), "application/json")
        return response
    elif request.method == 'GET':
        page = request.GET.get('page', 1)
        employee = request.GET.get('employee')
        month = request.GET.get('month')
        year = request.GET.get('year')
        page = int(page)
        vys_page = NWisefinPage(page, 10)
        serv = EmployeemonthlypayService(scope).test_upload_summary(employee, month,year, vys_page)
        response = HttpResponse(serv.get(), content_type="application/json")
        return response

@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payroll_test_present_count(request):
    scope=request.scope
    serv=EmployeemonthlypayService(scope)
    resp=serv.payroll_test_present_count(request)
    response = HttpResponse(resp.get(), content_type="application/json")
    return response

@csrf_exempt
@api_view(['POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payroll_test_attendance_summary(request):
    if request.method == 'POST':
        scope = request.scope
        body_data=json.loads(request.body)
        serv = EmployeemonthlypayService(scope)
        resp_data = serv.payroll_test_attendance_summary(body_data)
        response = HttpResponse(resp_data.get(), content_type="application/json")
        return response

@csrf_exempt
@api_view(['POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def payroll_test_template(request):
    if request.method == 'POST':
        payroll_test_template = ['Employee Code','Month','Year','Present Count','Leave Count','Duration','Paid Days']
        final_df = pd.DataFrame(columns=payroll_test_template)
        excel = 'application/vnd.ms-excel'
        format = HttpResponse(content_type=excel)
        writer = pd.ExcelWriter(format, engine='xlsxwriter')
        final_df.to_excel(writer, index=False)
        writer.close()
        filename = 'PAYROLL TEST TEMPLATE'
        format['Content-Disposition'] = 'attachment; filename="' + filename + '.xlsx"'
        return format


@csrf_exempt
@api_view(['POST'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def update_payroll_paidstatus(request):
    scope = request.scope
    user_id = request.user.id
    if request.method == 'POST':
        files = request.FILES.get('file')
        check_extension = files.name.split(".")[1]
        if check_extension == "xlsx" or "XLSX":
            approve_status = pd.read_excel(files)
        else:
            approve_status = pd.read_csv(files)
        payroll_serv = EmployeemonthlypayService(scope).update_payroll_paidstatus(approve_status,user_id)
        response = HttpResponse(payroll_serv.get(), "application/json")
        return response


@csrf_exempt
@api_view(['GET'])
@authentication_classes([NWisefinAuthentication])
@permission_classes([IsAuthenticated, NWisefinPermission])
def schedular_payrollmanualrun(request):
    scope = request.scope
    if request.method == 'GET':
        payroll_service = EmployeemonthlypayService(scope)
        is_manual = payroll_service.payrollshedular_check()
        if is_manual > 0:
            response = HttpResponse(json.dumps({"message": 'Payroll Manual Run Initiated Already Try Later'}), content_type="application/json")
        else:
            payroll_service.payroll_schedularmanual(request)
            response = HttpResponse(json.dumps({"message":'Payroll Manual Run Started'}), content_type="application/json")
        return response
