import pytz
import requests
from megawatt_agents.serializers import AgentProfileSerializer
from sales_and_marketing.models import CustomerProfile
from sales_and_marketing.serializers import CustomerOrderItemSerializer, CustomerOrderSerializer
from system_administration.serializers import UserSerializer
from system_administration.utils import check_if_system_administrator, create_notifications, generate_random_string, generateNextAgentNumber, send_email_signup, send_email_signup_agent
from warehouse_management.models import Product
from .models import *

from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from django.contrib.auth.models import User
from datetime import datetime, timedelta
import json
from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout


@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def create_agent(request):
    date_format = '%d/%m/%Y'
    active_user = request.user
    company_serial_number = request.data["serial_number"]
    agent_first_name = request.data["agent_first_name"]
    agent_last_name = request.data["agent_last_name"]
    email_address = request.data["email_address"]
    phone_number = request.data["phone_number"]
    agent_title = request.data["agent_title"]
    company_name = request.data["company_name"]
    agent_account_manager_id = request.data["agent_account_manager_id"]
    phone_number_exists = False
    contract_start_date = datetime.strptime(
        request.data["contract_start_date"], date_format).strftime("%Y-%m-%d") if len(request.data["contract_start_date"]) > 0 else None
    contract_end_date = datetime.strptime(
        request.data["contract_end_date"], date_format).strftime("%Y-%m-%d") if len(request.data["contract_end_date"]) > 0 else None
    banking_institution_name = request.data["banking_institution_name"]
    bank_account_name = request.data["bank_account_name"]
    bank_account_number = request.data["bank_account_number"]
    bank_branch_name = request.data["bank_branch_name"]
    bank_branch_code = request.data["bank_branch_code"]
    bank_swift_code = request.data["bank_swift_code"]
    agent_additional_info = request.data["agent_additional_info"]
    kra_pin = request.data["kra_pin"]
    certificate_of_registration_number = request.data["certificate_of_registration_number"]
    country_name = request.data["country_name"]
    identification_number = request.data["identification_number"]
    # agent_additional_info = request.data["agent_additional_info"]
    user = None
    try:
        staff_profile = StaffProfile.objects.get(user=active_user)
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        # if (staff_profile.company_department.department_name == "sales" or staff_profile.company_department.department_name == "marketing") and staff_profile.is_head_of_department == True and staff_profile.has_read_write_priviledges == True and company_profile:
        if ((staff_profile.company_department.department_name == "human_resource_management") and company_profile) or check_if_system_administrator(staff_profile):
            try:
                existing_agent = AgentProfile.objects.get(
                    phone_number=phone_number)
                if existing_agent is not None:
                    phone_number_exists = True
            except:
                pass
            if phone_number_exists != True:
                agent_number = generateNextAgentNumber()
                password = f'Megawatt@{agent_number}'
                serializers = UserSerializer(
                    data={'username': email_address, 'password': password})
                if serializers.is_valid():
                    user = serializers.save()
                    new_user = authenticate(
                        username=email_address, password=password)
                    # agent_number = generateNextAgentNumber()
                    agent_profile, created = AgentProfile.objects.get_or_create(
                        user=new_user, agent_number=agent_number, email_address=new_user.username, kra_pin=kra_pin, identification_number=identification_number, certificate_of_registration_number=certificate_of_registration_number, country_name=country_name, first_name=agent_first_name, last_name=agent_last_name, phone_number=phone_number, agent_title=agent_title, company_name=company_name, is_profile_set=True, contract_start_date=contract_start_date, contract_end_date=contract_end_date, banking_institution_name=banking_institution_name, bank_account_name=bank_account_name, bank_account_number=bank_account_number, bank_branch_name=bank_branch_name, bank_branch_code=bank_branch_code, bank_swift_code=bank_swift_code, agent_additional_info=agent_additional_info)
                    recipient_list = [f'{email_address}']
                    message = f"Dear {agent_profile.first_name}, \nYou have been successfully registered as an Agent on Megawatt Energies CRM Portal.\n\nYour login details is as shared below: -\nAgent number: {agent_profile.agent_number}\nUsername: {agent_profile.user.username}\nPassword: {password}\nYou can access the Megawatt CRM on various platform via the links below: \nMegawatt CRM Android Application : https://crm.megawattenergiesltd.com/app_download/app_latest.apk \nMegawatt CRM Web: https://crm.megawattenergiesltd.com/login \nOnce logged in , consider resetting your password to one that you can remember.\n\nWe’re excited to welcome you to the Megawatt Energies family!"
                    try:
                        pass
                        send_email_signup_agent(
                            request, message, recipient_list)
                    except:
                        pass
                    # create customer account manager
                    try:
                        agent_account_manager = StaffProfile.objects.get(
                            id=int(agent_account_manager_id))
                        account_management, created = AgentAccountManager.objects.get_or_create(
                            staff_profile=agent_account_manager, agent_profile=agent_profile)
                    except:
                        agent_account_manager = None
                        account_management, created = AgentAccountManager.objects.get_or_create(
                            staff_profile=agent_account_manager, agent_profile=agent_profile)
                    return Response({"message": "Agent account created successfully", }, status=200)
                else:
                    print(serializers.errors)
                    return Response({"message": "Unable to create agent account", }, status=406)
            else:
                # print(serializers.errors)
                return Response({"message": "An agent with a similar phone number already exists", }, status=406)
        else:
            return Response({"message": "You are unauthorized to perform this action", }, status=401)
    except Exception as e:
        if user is not None:
            user.delete()
        print(e)
        print(f"The serial causing error is {company_serial_number}")
        return Response({"message": "Error creating agent account", }, status=500)


@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def edit_agent(request):
    date_format = '%d/%m/%Y'
    active_user = request.user
    agent_id = request.data["agent_id"]
    company_serial_number = request.data["serial_number"]
    agent_first_name = request.data["agent_first_name"]
    agent_last_name = request.data["agent_last_name"]
    # email_address = request.data["email_address"]
    phone_number = request.data["phone_number"]
    agent_title = request.data["agent_title"]
    company_name = request.data["company_name"]
    agent_account_manager_id = request.data["agent_account_manager_id"]
    # phone_number_exists = False
    contract_start_date = datetime.strptime(
        request.data["contract_start_date"], date_format).strftime("%Y-%m-%d") if len(request.data["contract_start_date"]) > 0 else None
    contract_end_date = datetime.strptime(
        request.data["contract_end_date"], date_format).strftime("%Y-%m-%d") if len(request.data["contract_end_date"]) > 0 else None
    banking_institution_name = request.data["banking_institution_name"]
    bank_account_name = request.data["bank_account_name"]
    bank_account_number = request.data["bank_account_number"]
    bank_branch_name = request.data["bank_branch_name"]
    bank_branch_code = request.data["bank_branch_code"]
    bank_swift_code = request.data["bank_swift_code"]
    agent_additional_info = request.data["agent_additional_info"]
    try:
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(user=active_user)
        if ((staff_profile.company_department.department_name == "human_resource_management") and company_profile) or check_if_system_administrator(staff_profile):
            agent_profile = AgentProfile.objects.get(id=int(agent_id))
            agent_profile_serializer = AgentProfileSerializer(instance=agent_profile, data={
                'first_name': agent_first_name,
                'last_name': agent_last_name,
                'phone_number': phone_number,
                'agent_title': agent_title,
                'company_name': company_name,
                'contract_start_date': contract_start_date,
                'contract_end_date': contract_end_date,
                'banking_institution_name': banking_institution_name,
                'bank_account_name': bank_account_name,
                'bank_account_number': bank_account_number,
                'bank_branch_name': bank_branch_name,
                'bank_branch_code': bank_branch_code,
                'bank_swift_code': bank_swift_code,
                'agent_additional_info': agent_additional_info,
            })
            if agent_profile_serializer.is_valid():
                agent_profile_serializer.save()
                if len(agent_account_manager_id) > 0:
                    agent_account_manager = StaffProfile.objects.get(
                        id=int(agent_account_manager_id))
                    agent_profile.agent_profile_management.staff_profile = agent_account_manager
                    agent_profile.agent_profile_management.save()
                return Response({"message": "Agent profile edited successfully", }, status=200)
            else:
                return Response({"message": "Unable to edit agent profile", }, status=406)
        else:
            return Response({"message": "You are unauthorized to perform this action", }, status=401)
    except:
        return Response({"message": "Error editing agent profile", }, status=406)


@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def delete_agent(request):
    try:
        active_user = request.user
        agent_id = request.data["agent_id"]
        company_serial_number = request.data["serial_number"]
        active_user = request.user
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(user=active_user)
        if ((staff_profile.company_department.department_name == "human_resource_management") and company_profile) or check_if_system_administrator(staff_profile):
            agent_profile = AgentProfile.objects.get(id=int(agent_id))
            agent_profile.recycle_bin = True
            agent_profile.save()
            return Response({"message": "Agent profile delete successfully", }, status=200)
        else:
            return Response({"message": "You are unauthorized to perform this action", }, status=401)
    except:
        return Response({"message": "Error deleting agent profile, try again!", }, status=500)


@api_view(['POST'])
def get_all_agents_profile(request):

    payload = {}
    agent_profile_list = []
    target_timezone = pytz.timezone('Africa/Nairobi')
    date_format = '%d/%m/%Y, %H:%M'
    try:
        company_serial_number = request.data["serial_number"]
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        all_agents_profile = AgentProfile.objects.filter(
            recycle_bin=False, is_profile_active=True).order_by("-id")
        for agent in all_agents_profile:
            agent_map = {}
            agent_map["agent_id"] = str(agent.id)
            agent_map["agent_number"] = agent.agent_number
            agent_map["first_name"] = agent.first_name
            agent_map["last_name"] = agent.last_name
            agent_map["email_address"] = agent.email_address
            agent_map["country_name"] = agent.country_name
            agent_map["identification_number"] = agent.identification_number
            agent_map["phone_number"] = agent.phone_number
            agent_map["company_name"] = agent.company_name
            agent_map["kra_pin"] = agent.kra_pin
            agent_map["certificate_of_registration_number"] = agent.certificate_of_registration_number
            agent_map["agent_title"] = agent.agent_title
            agent_map["contract_start_date"] = agent.contract_start_date if agent.contract_start_date is not None else ""
            agent_map["contract_end_date"] = agent.contract_end_date if agent.contract_end_date is not None else ""
            agent_map["banking_institution_name"] = agent.banking_institution_name
            agent_map["bank_account_name"] = agent.bank_account_name
            agent_map["bank_account_number"] = agent.bank_account_number
            agent_map["bank_branch_name"] = agent.bank_branch_name
            agent_map["bank_branch_code"] = agent.bank_branch_code
            agent_map["bank_swift_code"] = agent.bank_swift_code
            agent_map["agent_additional_info"] = agent.agent_additional_info
            agent_map["is_profile_active"] = "true" if agent.is_profile_active == True else "false"
            agent_map["created_on"] = datetime.strftime(
                agent.created_on.astimezone(target_timezone), date_format) if agent.created_on is not None else ""
            agent_map["last_updated_on"] = datetime.strftime(
                agent.last_updated_on.astimezone(target_timezone), date_format) if agent.last_updated_on is not None else ""
            try:
                agent_account_manager = AgentAccountManager.objects.get(
                    agent_profile=agent)
                account_manager_map = {}
                account_manager_map["staff_id"] = str(
                    agent_account_manager.staff_profile.id)
                account_manager_map["staff_name"] = f'{agent_account_manager.staff_profile.first_name} {agent_account_manager.staff_profile.last_name}'
                agent_map["agent_account_manager"] = account_manager_map
            except:
                account_manager_map = {}
                account_manager_map["staff_id"] = ""
                account_manager_map["staff_name"] = ""
                agent_map["agent_account_manager"] = account_manager_map
            agent_profile_list.append(agent_map)
        payload["agent_profile_list"] = agent_profile_list
        return Response({"message": "true", "payload": payload}, status=200)
    except:
        payload["agent_profile_list"] = agent_profile_list
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(['POST'])
def get_staff_agents_profile(request):

    payload = {}
    agent_profile_list = []
    target_timezone = pytz.timezone('Africa/Nairobi')
    date_format = '%d/%m/%Y, %H:%M'
    try:
        company_serial_number = request.data["serial_number"]
        staff_id = request.data["staff_id"]
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(id=int(staff_id))
        all_agents_profile = staff_profile.staff_agent_accounts.all().order_by("-id")
        # AgentProfile.objects.filter(
        #     recycle_bin=False, is_profile_active=True).order_by("id")
        for agent in all_agents_profile:
            if agent.agent_profile.recycle_bin == False and agent.agent_profile.is_profile_active == True:
                agent_map = {}
                agent = agent.agent_profile
                agent_map["agent_id"] = str(agent.id)
                agent_map["agent_number"] = agent.agent_number
                agent_map["first_name"] = agent.first_name
                agent_map["last_name"] = agent.last_name
                agent_map["email_address"] = agent.email_address
                agent_map["country_name"] = agent.country_name
                agent_map["identification_number"] = agent.identification_number
                agent_map["phone_number"] = agent.phone_number
                agent_map["company_name"] = agent.company_name
                agent_map["kra_pin"] = agent.kra_pin
                agent_map["certificate_of_registration_number"] = agent.certificate_of_registration_number
                agent_map["agent_title"] = agent.agent_title
                agent_map["contract_start_date"] = agent.contract_start_date if agent.contract_start_date is not None else ""
                agent_map["contract_end_date"] = agent.contract_end_date if agent.contract_end_date is not None else ""
                agent_map["banking_institution_name"] = agent.banking_institution_name
                agent_map["bank_account_name"] = agent.bank_account_name
                agent_map["bank_account_number"] = agent.bank_account_number
                agent_map["bank_branch_name"] = agent.bank_branch_name
                agent_map["bank_branch_code"] = agent.bank_branch_code
                agent_map["bank_swift_code"] = agent.bank_swift_code
                agent_map["agent_additional_info"] = agent.agent_additional_info
                agent_map["is_profile_active"] = "true" if agent.is_profile_active == True else "false"
                agent_map["created_on"] = datetime.strftime(
                    agent.created_on.astimezone(target_timezone), date_format) if agent.created_on is not None else ""
                agent_map["last_updated_on"] = datetime.strftime(
                    agent.last_updated_on.astimezone(target_timezone), date_format) if agent.last_updated_on is not None else ""
                try:
                    agent_account_manager = AgentAccountManager.objects.get(
                        agent_profile=agent)
                    account_manager_map = {}
                    account_manager_map["staff_id"] = str(
                        agent_account_manager.staff_profile.id)
                    account_manager_map["staff_name"] = f'{agent_account_manager.staff_profile.first_name} {agent_account_manager.staff_profile.last_name}'
                    agent_map["agent_account_manager"] = account_manager_map
                except:
                    account_manager_map = {}
                    account_manager_map["staff_id"] = ""
                    account_manager_map["staff_name"] = ""
                    agent_map["agent_account_manager"] = account_manager_map
                agent_profile_list.append(agent_map)
        payload["agent_profile_list"] = agent_profile_list
        return Response({"message": "true", "payload": payload}, status=200)
    except:
        payload["agent_profile_list"] = agent_profile_list
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(['POST'])
def get_agent_customers(request):
    agent_customer_list = []
    payload = {}
    target_timezone = pytz.timezone('Africa/Nairobi')
    date_format = '%d/%m/%Y, %H:%M'
    try:
        agent_id = request.data["agent_id"]
        agent_profile = AgentProfile.objects.get(id=int(agent_id))
        agent_customer_accounts = agent_profile.agent_managing_customer_profile.filter(recycle_bin=False).order_by(
            "-id")
        for agent_customer in agent_customer_accounts:
            # if agent_customer.customer_profile.recycle_bin == False:

            customer_profile = agent_customer
            customer_documents = customer_profile.customer_documents.all().order_by("-id")
            kra_pin_certificate_path = ""
            certificate_of_registration_path = ""
            if customer_documents is not None:
                for customer_doc in customer_documents:
                    if customer_doc.document_type == "pin_certificate":
                        kra_pin_certificate_path = customer_doc.saved_document_path
                        break
                for customer_doc in customer_documents:
                    if customer_doc.document_type == "certificate_of_registration":
                        certificate_of_registration_path = customer_doc.saved_document_path
                        break
            customer_profile_map = {}
            customer_profile_map["customer_profile_id"] = str(
                customer_profile.id)
            customer_profile_map["customer_first_name"] = customer_profile.customer_first_name
            customer_profile_map["customer_last_name"] = customer_profile.customer_last_name
            customer_profile_map["email_address"] = customer_profile.email_address
            customer_profile_map["phone_number"] = customer_profile.phone_number
            customer_profile_map["customer_title"] = customer_profile.customer_title
            customer_profile_map["company_name"] = customer_profile.company_name
            customer_profile_map["customer_type"] = customer_profile.customer_type
            customer_profile_map["kra_pin"] = customer_profile.kra_pin
            customer_profile_map["certificate_of_registration_number"] = customer_profile.certificate_of_registration_number
            customer_profile_map["kra_pin_certificate_path"] = kra_pin_certificate_path
            customer_profile_map["certificate_of_registration_path"] = certificate_of_registration_path
            customer_profile_map["is_profile_set"] = "true" if customer_profile.is_profile_set == True else "false"
            customer_profile_map["created_on"] = datetime.strftime(
                customer_profile.created_on.astimezone(target_timezone), date_format) if customer_profile.created_on is not None else ""
            customer_profile_map["last_updated_on"] = datetime.strftime(
                customer_profile.last_updated_on.astimezone(target_timezone), date_format) if customer_profile.last_updated_on is not None else ""
            agent_customer_list.append(customer_profile_map)
        payload["agent_customer_list"] = agent_customer_list
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        payload["agent_customer_list"] = agent_customer_list
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(['POST'])
def get_agent_sale_history(request):
    agent_sale_history_list = []
    payload = {}
    try:
        agent_id = request.data["agent_id"]
        agent_profile = AgentProfile.objects.get(id=int(agent_id))
        agent_customer_profiles = agent_profile.agent_managing_customer_profile.filter(
            recycle_bin=False).order_by("-id")
        # print(len(agent_customer_profiles))
        for agent_customer in agent_customer_profiles:
            customer_sales = agent_customer.customer_order_history.filter(
                recycle_bin=False, customer_order_approved=True, agent_profile__isnull=False).order_by("-id")
            for sale in customer_sales:
                sale_map = {}
                sale_map["customer_order_id"] = str(sale.id)
                sale_map["customer_profile_id"] = str(
                    sale.customer_profile.id) if sale.customer_profile is not None else ""
                sale_map["agent_quotation_number"] = sale.customer_order_description
                sale_map["customer_order_total_gross_value"] = sale.customer_order_total_gross_value
                sale_map["customer_order_total_discount"] = sale.customer_order_total_discount
                sale_map["customer_order_total_net_value"] = sale.customer_order_total_net_value
                sale_map["customer_order_total_amount_paid"] = sale.customer_order_total_amount_paid
                creator_map = {}
                creator_map["staff_id"] = str(
                    sale.created_by.id) if sale.created_by is not None else ""
                creator_map["staff_name"] = f'{sale.created_by.first_name} {sale.created_by.last_name}' if sale.created_by is not None else ""
                creator_map["staff_position"] = sale.created_by.staff_position.position_title if sale.created_by.staff_position is not None else ""
                sale_map["created_by"] = creator_map
                creator_map = {}
                creator_map["staff_id"] = str(
                    sale.last_updated_by.id) if sale.last_updated_by is not None else ""
                creator_map["staff_name"] = f'{sale.last_updated_by.first_name} {sale.last_updated_by.last_name}' if sale.last_updated_by is not None else ""
                creator_map["staff_position"] = sale.last_updated_by.staff_position.position_title if sale.last_updated_by.staff_position is not None else ""
                sale_map["last_updated_by"] = creator_map
                customer_order_items = sale.customer_order_items.all().order_by("-id")
                product_items_sold = []
                for item in customer_order_items:
                    item_map = {}
                    item_map["customer_order_item_id"] = str(
                        item.id)
                    item_map["product_id"] = str(
                        item.product.id)
                    item_map["product_name"] = item.product.product_name
                    item_map["quantity"] = item.quantity
                    item_map["price_per_item"] = item.price_per_item
                    item_map["discount_per_item"] = item.discount_per_item
                    item_map["gross_subtotal"] = item.gross_subtotal
                    item_map["total_discount"] = item.total_discount
                    item_map["net_subtotal"] = item.net_subtotal
                    product_items_sold.append(item_map)
                sale_map["product_items_sold"] = product_items_sold
                agent_sale_history_list.append(sale_map)
        payload["agent_sale_history_list"] = agent_sale_history_list
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        payload["agent_sale_history_list"] = agent_sale_history_list
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(['POST'])
def get_staff_to_manage_agent(request):
    staff_profile_list = []
    payload = {}
    try:
        company_serial_number = request.data["serial_number"]
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        staff_profiles = StaffProfile.objects.filter(
            recycle_bin=False, is_profile_active=True, is_profile_set=True).order_by("-id")
        for staff in staff_profiles:
            staff_map = {}
            if staff.company_department.department_name == "sales" or staff.company_department.department_name == "marketing":
                staff_map["staff_id"] = str(staff.id)
                staff_map["staff_data"] = f"{staff.first_name} {staff.last_name} ({staff.staff_number})"
                staff_profile_list.append(staff_map)

        payload["staff_profile_list"] = staff_profile_list
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        payload["staff_profile_list"] = staff_profile_list
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def create_agent_customer(request):
    active_user = request.user
    company_serial_number = request.data["serial_number"]
    customer_first_name = request.data["customer_first_name"]
    customer_last_name = request.data["customer_last_name"]
    email_address = request.data["email_address"]
    phone_number = request.data["phone_number"]
    customer_title = request.data["customer_title"]
    company_name = request.data["company_name"]
    customer_type = request.data["customer_type"]
    customer_account_manager_id = request.data["customer_account_manager_id"]
    phone_number_exists = False
    try:
        staff_profile = StaffProfile.objects.get(user=active_user)
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        # if (staff_profile.company_department.department_name == "sales" or staff_profile.company_department.department_name == "marketing") and staff_profile.is_head_of_department == True and staff_profile.has_read_write_priviledges == True and company_profile:
        if ((staff_profile.company_department.department_name == "sales" or staff_profile.company_department.department_name == "marketing") and company_profile) or check_if_system_administrator(staff_profile):
            try:
                existing_cus = CustomerProfile.objects.get(
                    phone_number=phone_number)
                if existing_cus is not None:
                    phone_number_exists = True
            except:
                pass
            if phone_number_exists != True:
                password = generate_random_string(6)
                serializers = UserSerializer(
                    data={'username': email_address, 'password': password})
                if serializers.is_valid():
                    user = serializers.save()
                    new_user = authenticate(
                        username=email_address, password=password)
                    customer_profile, created = CustomerProfile.objects.get_or_create(
                        user=new_user, email_address=new_user.username, company_profile=company_profile, customer_first_name=customer_first_name, customer_last_name=customer_last_name, phone_number=phone_number, customer_title=customer_title, company_name=company_name, customer_type=customer_type, is_profile_set=True)
                    recipient_list = [f'{email_address}']
                    message = f"You have been successfully registered on Megawatt Energies Customer Platform. We’re excited to welcome you to the Megawatt Energies family!"
                    try:
                        pass
                        send_email_signup(request, message, recipient_list)
                    except:
                        pass
                    # create customer account manager
                    try:
                        customer_account_manager = AgentProfile.objects.get(
                            id=int(customer_account_manager_id))
                        customer_profile.agent = customer_account_manager
                        customer_profile.save()
                        return Response({"message": "Customer account created successfully", }, status=200)
                    except:
                        customer_profile.delete()
                        new_user.delete()
                        return Response({"message": "Error creating customer account", }, status=500)
                else:
                    # print(serializers.errors)
                    return Response({"message": "Unable to create customer account", }, status=406)
            else:
                # print(serializers.errors)
                return Response({"message": "A customer with a similar phone number already exists", }, status=406)
        else:
            return Response({"message": "You are unauthorized to perform this action", }, status=401)
    except:  # Exception as e:
        # print(e)
        return Response({"message": "Error creating customer account", }, status=500)


# @api_view(['POST'])
# @authentication_classes([TokenAuthentication])
# @permission_classes([IsAuthenticated])
# def fetch_agent_quotation(request):
#     active_user = request.user
#     try:
#         agent_quotation_number = request.data["agent_quotation_number"]
#         quotation_url = f"https://crm.megawattenergiesltd.com/api/agent-quotes/share?agent_quotation_number={agent_quotation_number}"
#         response = requests.post(quotation_url)
#         quotation = {}
#         if response.status_code == 200:
#             quotation = response.json()
#             print(quotation)
#             return Response({}, status=200)
#         else:
#             print(f"failing: {response.status_code}")
#             return Response({}, status=500)
#     except Exception as e:
#         print(e)
#         return Response({}, status=500)

@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def create_agent_customer_order(request):
    active_user = request.user
    try:
        company_serial_number = request.data["serial_number"]
        customer_id = request.data["customer_id"]
        agent_id = request.data["agent_id"]
        customer_order_type = request.data["customer_order_type"]
        customer_order_description = request.data["customer_order_description"]
        customer_order_total_gross_value = request.data["customer_order_total_gross_value"]
        customer_order_total_discount = request.data["customer_order_total_discount"]
        customer_order_total_net_value = request.data["customer_order_total_net_value"]
        customer_order_approved = request.data["customer_order_approved"]
        # sales_person_id = request.data["sales_person_id"]
        customer_order_items_list = request.data.get(
            'customer_order_items_list', [])
        customer_order_items_list = json.loads(
            customer_order_items_list)
        staff_profile = StaffProfile.objects.get(user=active_user)
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        today = datetime.now()
        tomorrow = today + timedelta(days=1)
        if ((staff_profile.company_department.department_name == "sales" or staff_profile.company_department.department_name == "marketing") and company_profile) or check_if_system_administrator(staff_profile):
            company_branch = staff_profile.company_branch
            customer_profile = None
            sales_person = None
            try:
                if len(customer_id) > 0:
                    customer_profile = CustomerProfile.objects.get(
                        id=int(customer_id))
            except:
                customer_profile = None
            sales_person = StaffProfile.objects.get(user=active_user)
            # try:
            #     if len(sales_person_id) > 0:
            #         sales_person = StaffProfile.objects.get(
            #             id=int(sales_person_id))
            # except:
            #     sales_person = None
            customer_order_serializer = CustomerOrderSerializer(
                data={'company_branch': company_branch.id, 'customer_profile': customer_profile.id, 'agent_profile': int(agent_id), 'customer_order_type': customer_order_type, 'customer_order_description': customer_order_description, 'customer_order_total_gross_value': customer_order_total_gross_value, 'customer_order_total_discount': customer_order_total_discount, 'customer_order_total_net_value': customer_order_total_net_value, 'customer_order_approved': customer_order_approved, 'expected_delivery_date': tomorrow.date(), 'sales_person': sales_person.id, 'created_by': staff_profile.id, 'last_updated_by': staff_profile.id})
            if customer_order_serializer.is_valid():
                new_order = customer_order_serializer.save()
                for customer_order_item in customer_order_items_list:
                    product_name = customer_order_item["product_name"]
                    product_sku = customer_order_item["product_sku"]
                    product_instance = None
                    try:
                        product_instance = Product.objects.get(
                            product_name=product_name)
                    except:
                        product_instance = Product.objects.get(
                            stock_keeping_unit=product_sku)
                    if product_instance is not None:
                        quantity = customer_order_item["quantity"]
                        price_per_item = customer_order_item["price_per_item"]
                        discount_per_item = customer_order_item["discount_per_item"]
                        gross_subtotal = customer_order_item["gross_subtotal"]
                        total_discount = customer_order_item["total_discount"]
                        net_subtotal = customer_order_item["net_subtotal"]
                        order_item_serializer = CustomerOrderItemSerializer(data={'customer_order': new_order.id, 'product': product_instance.id, 'quantity': quantity, 'price_per_item': price_per_item,
                                                                            'discount_per_item': discount_per_item, 'gross_subtotal': gross_subtotal, 'total_discount': total_discount, 'net_subtotal': net_subtotal})
                        if order_item_serializer.is_valid():
                            order_item_serializer.save()
                    else:
                        print("here is the problem!")
                        new_order.delete()
                        return Response({"message": f"Unable to create customer order because {product_name} is unavalable!", }, status=406)
                # notify finance department
                try:
                    list_of_staff_ids = []
                    # get finance department staff
                    finance_dept = CompanyDepartment.objects.get(
                        department_name="finance_and_accounting")
                    all_finance_staff = StaffProfile.objects.filter(
                        company_department=finance_dept)
                    for finance_staff in all_finance_staff:
                        list_of_staff_ids.append(
                            finance_staff.id)
                    notification_title = f"Agent Order {new_order.customer_order_number}"
                    notification_body = f"A new agent order of number {new_order.customer_order_number} has been created. Approval by finance department is required."
                    create_notifications(notification_title,
                                         notification_body, list_of_staff_ids)
                except:
                    pass
                return Response({"message": f"Agent order {new_order.customer_order_number} created successfully", }, status=200)
            else:
                print(customer_order_serializer.errors)
                return Response({"message": "Error creating agent order", }, status=406)
        else:
            return Response({"message": "You are unauthorized to perform this action", }, status=401)
    except:
        return Response({"message": "Error creating agent order", }, status=500)


@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def recreate_agent_account(request):
    """Repair or recreate login for an existing agent profile after partial failures."""
    active_user = request.user
    try:
        agent_id = request.data["agent_id"]
        company_serial_number = request.data["serial_number"]
        staff_profile = StaffProfile.objects.get(user=active_user)
        company_profile = CompanyProfile.objects.get(
            company_serial_number=company_serial_number)
        if not (((staff_profile.company_department.department_name == "human_resource_management") and company_profile)
                or check_if_system_administrator(staff_profile)):
            return Response({"message": "You are unauthorized to perform this action"}, status=401)

        agent = AgentProfile.objects.get(id=int(agent_id))
        email_address = agent.email_address or request.data.get("email_address", "")
        if not email_address:
            return Response({"message": "Agent email is required to recreate account"}, status=400)

        password = f'Megawatt@{agent.agent_number}'
        if agent.user:
            agent.user.username = email_address
            agent.user.set_password(password)
            agent.user.save()
        else:
            serializers = UserSerializer(data={'username': email_address, 'password': password})
            if not serializers.is_valid():
                return Response({"message": "Unable to recreate agent login"}, status=406)
            user = serializers.save()
            agent.user = user
            agent.save()

        recipient_list = [email_address]
        message = (
            f"Dear {agent.first_name},\nYour Megawatt agent login has been recreated.\n\n"
            f"Agent number: {agent.agent_number}\nUsername: {email_address}\nPassword: {password}\n"
        )
        try:
            send_email_signup_agent(request, message, recipient_list)
        except Exception:
            pass
        return Response({"message": "Agent account recreated successfully"}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "Error recreating agent account"}, status=500)
