import datetime
import json

from rest_framework import serializers as serializer

from crm.crm_customer.models import CrmCustomer

from crm.crm_customer.serializers import CustomerInfoSerializer

from console.contract.models import Contract

from crm.plan.models import CustomerOperationRecord

from crm.crm_customer.models import CustomerClue

from common.accounts.models import Users

from crm.plan.models import (SignIn, VisitRecord, TaskApprovalRecord,
                             CrmTask, Plan, PlanCode)

from console.customer.models import Contact

from common.accounts.models import Tags

from crm.plan.services import send_message

from crm.plan.models import Message, UserMessage

from console.electricityuser.models import ElectricityUser


class CreatePlanSerialzier(serializer.Serializer):
    customer_id = serializer.ListField(child=serializer.IntegerField(required=True, allow_null=False),
                                       help_text="客户id")
    name = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    type = serializer.CharField(required=False, allow_null=True, allow_blank=True)
    plan_code = serializer.ListField(child=serializer.DictField(required=True, allow_empty=False, allow_null=False),
                                     required=True,
                                     allow_empty=False, allow_null=False)

    def create(self, validated_data):
        request = self.context.get("request")
        customers = CrmCustomer.objects.filter(id__in=validated_data.get("customer_id"))
        instan = None
        for customer in customers:
            plan = Plan.objects.filter(customer=customer, type=validated_data.get("type")).exclude(
                status="completed").first()
            if plan:
                instan = plan
                continue
            plan = Plan.objects.create(
                customer=customer,
                name=validated_data.get("name"),
                type=validated_data.get("type"),
                status="pending",
                creater=request.data.get("user")
            )
            plan_code = []
            for item in validated_data.get("plan_code"):
                plan_code.append(PlanCode(
                    plan=plan,
                    code_id=item.get("id"),
                    index=item.get("index"),
                    duration=item.get("duration"),
                    file=item.get("file"),
                    status="pending"
                ))
            PlanCode.objects.bulk_create(plan_code)
            # 同步创建处理记录
            CustomerOperationRecord.objects.create(
                customer=customer,
                plan=plan,
                content="{}制定计划：{}（{}）".format(request.user.username, plan.name, plan.type),
                account=request.user
            )
            instan = plan

        return instan

    def update(self, instance, validated_data):
        instance.name = validated_data.get("name")
        instance.type = validated_data.get("type")

        for item in validated_data.get("plan_code"):
            code_id = item.pop("id")
            PlanCode.objects.filter(plan=instance, code_id=code_id).update(**item)
        instance.save()
        return instance


class PlanInfoSerializer(serializer.ModelSerializer):
    plan_code = serializer.SerializerMethodField()
    customer = serializer.SerializerMethodField()
    contract = serializer.SerializerMethodField()
    # recent_code = serializer.SerializerMethodField()
    creater = serializer.SerializerMethodField()
    saler = serializer.SerializerMethodField()
    intention = serializer.SerializerMethodField()

    def get_intention(self, obj):
        return obj.customer.intention if obj.customer else None

    def get_saler(self, obj):
        return {
            "id": obj.customer.salesman.id,
            "nickname": obj.customer.salesman.nickname
        } if obj.customer and obj.customer.salesman else None

    def get_creater(self, obj):
        return {
            "id": obj.creater.id,
            "nickname": obj.creater.nickname
        } if obj.creater else None

    def get_plan_code(self, obj):
        plan_code = PlanCode.objects.filter(plan=obj)
        return PLanCodeInfoSerializer(plan_code, many=True).data

    def get_customer(self, obj):
        return CustomerInfoSerializer(obj.customer).data

    def get_contract(self, obj):
        contracts = Contract.objects.filter(customer=obj.customer.customer)
        return [{"id": item.id, "code": item.code} for item in contracts]

    # def get_recent_code(self, obj):
    #     code = Code.objects.filter(id=obj.recent_code).first()
    #     return code.name if code else None

    class Meta:
        model = Plan
        fields = ("id", "name", "type", "status", "plan_code", "recent_code",
                  "customer", "contract", "start_time", "end_time", "creater",
                  "saler", "intention")


class PLanCodeInfoSerializer(serializer.ModelSerializer):
    name = serializer.SerializerMethodField()

    def get_name(self, obj):
        return obj.code.name if obj.code else None

    class Meta:
        model = PlanCode
        fields = ("id", "name", "index", "duration", "file", "status", "code_id")


class CreateCustomerClueSerializer(serializer.ModelSerializer):
    name = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    level = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    type = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    service_staff_id = serializer.IntegerField(required=False, allow_null=True)
    last_service_staff_id = serializer.IntegerField(required=False, allow_null=True)
    address = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    adcode = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    city_code = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    district = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    longitude = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    latitude = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    legal_person = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    legal_person_phone = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    tax_num = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    bank_account_name = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    bank_name = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    postcode = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    scale = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    nature = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    industry = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    asset = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    covered_area = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    logo = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    file = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    parent_enterprise_id = serializer.IntegerField(required=False, allow_null=True)
    contact = serializer.ListField(required=False,
                                   child=serializer.DictField(required=False, allow_empty=True, allow_null=True))
    power_data = serializer.ListField(required=False,
                                      child=serializer.DictField(required=False, allow_empty=True, allow_null=True))
    power_number = serializer.FloatField(required=False, allow_null=True)
    circuit_diagram = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    panorama = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    gate_image = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    electricity_bill = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    customer_id = serializer.IntegerField(required=False, allow_null=True)
    plan_id = serializer.IntegerField(required=False, allow_null=True)

    def create(self, validated_data):
        validated_data["contact"] = json.dumps(validated_data.get("contact")) if validated_data.get("contact") else None
        validated_data["power_data"] = json.dumps(validated_data.get("power_data")) if validated_data.get(
            "power_data") else None
        validated_data["status"] = "pending_approval"
        instance = CustomerClue.objects.create(**validated_data)
        return instance


class CreateTaskSerializer(serializer.Serializer):
    type = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    code_id = serializer.IntegerField(required=False, allow_null=True)
    remark = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    customer_id = serializer.IntegerField(required=False, allow_null=True)
    plan_id = serializer.IntegerField(required=False, allow_null=True)
    intention = serializer.BooleanField(required=False, allow_null=True)
    urgent = serializer.BooleanField(required=False, allow_null=True)
    file = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    contact = serializer.ListField(child=serializer.DictField(allow_null=True, allow_empty=True, required=False),
                                   required=False, allow_empty=True, allow_null=True)
    amount = serializer.FloatField(required=False, allow_null=True)
    ele_user = serializer.ListField(required=False, allow_null=True)
    contract_id = serializer.CharField(required=False, allow_null=True, allow_blank=True)

    def validate(self, attrs):
        instance = CrmTask.objects.filter(plan_id=attrs.get("plan_id"),
                                          code_id=attrs.get("code_id")).first()
        if instance and instance.approval_status == "pass":
            return serializer.ValidationError("该节点已有任务，且任务已审批通过")
        return attrs

    def create(self, validated_data):
        request = self.context.get("request")
        user = Users.objects.filter(account=request.user).first()
        validated_data["submitter"] = user
        validated_data["status"] = "pending_approval"
        validated_data["contact"] = json.dumps(validated_data.get("contact"), ensure_ascii=True) if validated_data.get(
            "contact") else None
        validated_data["ele_user"] = json.dumps(validated_data.get("ele_user"),
                                                ensure_ascii=True) if validated_data.get(
            "ele_user") else None
        instance = CrmTask.objects.filter(plan_id=validated_data.get("plan_id"),
                                          code_id=validated_data.get("code_id"))
        # 任务不存在，创建一个任务
        if not instance.first():
            instance = CrmTask.objects.create(**validated_data)
            plan_code = PlanCode.objects.filter(plan=instance.plan).order_by("index")
            # 第一个节点，计划开始
            if instance.code == plan_code[0].code:
                instance.plan.start_time = datetime.datetime.now() if not instance.plan.start_time else instance.plan.start_time
                instance.plan.save()
            # 创建拜访记录
            VisitRecord.objects.create(
                customer_id=validated_data.get("customer_id"),
                user=user,
                content="信息补充，新增客户联系人" if validated_data.get("code_id") == 1 else "上传方案"
                if validated_data.get("code_id") == 2 else "上传合同",
                visit_time=datetime.datetime.now()
            )
            # 创建消息
            send_message(**{
                "type": 1,
                "title": "客户跟进",
                "content": "您有一个任务需要审批",
                "customer_id": validated_data.get("customer_id"),
                "plan_id": validated_data.get("plan_id"),
                "task_id": instance.id,
                "user": user
            })
        # 任务已存在，且未审批
        elif instance.first() and not instance.first().approval_status:
            instance.update(**validated_data)
            instance = instance.first()
        # 任务已存在，且审批未通过，再次提交审核
        else:
            validated_data["status"] = "pending_approval"
            instance.update(**validated_data)
            instance = instance.first()
        return instance

    def update(self, instance, validated_data):
        instance.status = "pending_approval"
        instance.contact = json.dumps(validated_data.get("contact")) if validated_data.get("contact") else None
        instance.contact = json.dumps(validated_data.get("ele_user")) if validated_data.get("ele_user") else None
        instance.file = validated_data.get("file")
        instance.remark = validated_data.get("remark")
        instance.amount = validated_data.get("amount")
        instance.contract_id = validated_data.get("contract_id")
        instance.save()
        return instance


class TaskSerializer(serializer.ModelSerializer):
    code = serializer.SerializerMethodField()
    customer = serializer.SerializerMethodField()
    plan = serializer.SerializerMethodField()
    submitter = serializer.SerializerMethodField()
    contact = serializer.SerializerMethodField()

    ele_user = serializer.SerializerMethodField()
    contract = serializer.SerializerMethodField()

    def get_contract(self, obj):
        contract = Contract.objects.filter(id=obj.contract_id).first()
        return {
            "id": contract.id,
            "code": contract.code
        } if contract else None

    def get_ele_user(self, obj):
        return json.loads(obj.ele_user) if obj.ele_user else None

    def get_contact(self, obj):
        return json.loads(obj.contact) if obj.contact else None

    def get_code(self, obj):
        return {
            "id": obj.code.id,
            "name": obj.code.name
        } if obj.code else None

    def get_customer(self, obj):
        return {
            "id": obj.customer.id,
            "customer_id": obj.customer.customer.id,
            "type": obj.customer.type,
            "name": obj.customer.customer.name
        } if obj.customer else None

    def get_plan(self, obj):
        return {
            "id": obj.plan.id,
            "name": obj.plan.name
        } if obj.plan else None

    def get_submitter(self, obj):
        return {
            "id": obj.submitter.id,
            "name": obj.submitter.nickname,
            "phone": obj.submitter.phone
        }

    class Meta:
        model = CrmTask
        fields = ("id", "type", "code", "status", "remark", "customer", "plan",
                  "intention", "urgent", "submitter", "file", "contact", "approval_status",
                  "amount", "created_time", "finish_time", "ele_user", "contract")


class TaskApproveSerializer(serializer.Serializer):
    result = serializer.BooleanField(required=True, allow_null=False)
    reason = serializer.CharField(required=False, allow_blank=True, allow_null=True)

    def update(self, instance, validated_data):
        user = Users.objects.filter(account=self.context.get("request").user).first()
        instance.approval_status = "pass" if validated_data.get("result") else "refuse"
        instance.status = "completed" if validated_data.get("result") else "pending"
        instance.save()
        instance.customer.intention = instance.intention if validated_data.get(
            "result") else instance.customer.intention
        instance.customer.save()
        # 同步创建任务审批记录
        TaskApprovalRecord.objects.create(
            task=instance,
            result="pass" if validated_data.get("result") else "refuse",
            remark=validated_data.get("reason"),
            reviewer=user
        )
        plan_code = PlanCode.objects.filter(plan=instance.plan).order_by("-index")
        # 如果是最后一步审批通过，计划完成
        if validated_data.get("result") and plan_code[0] == instance.code:
            instance.plan.status = "completed"
            instance.plan.contract_id = instance.contract_id
            instance.plan.save()
            instance.customer.is_sign = True
            instance.customer.save()
        # 信息补充阶段，且审批通过，添加客户联系人
        if instance.code.id == 1 and validated_data.get("result"):
            contact = json.loads(instance.contact) if instance.contact else []
            ele_user = json.loads(instance.ele_user) if instance.ele_user else []

            for item in contact:
                contact = Contact.objects.create(
                    customer=instance.customer.customer,
                    name=item.get("name"),
                    phone=item.get("phone")
                )
                contact.tags.set(Tags.objects.filter(name__contains=item.get("role")))
            for item in ele_user:
                if item.get("number"):
                    ElectricityUser.objects.create(
                        number=item.get("number"),
                        customer=instance.customer.customer,
                        ad_code=item.get("adcode"),
                        city_code=item.get("city_code"),
                        district=item.get("district"),
                        transformer_capacity=item.get("transformer_capacity"),
                        real_capacity=item.get("real_capacity"),
                        voltage_level=item.get("voltage_level"),
                        trusteeship_num=item.get("trusteeship_num"),
                        ep_factor=item.get("ep_factor"),
                        longitude=item.get("longitude"),
                        latitude=item.get("latitude"),
                    )

            return instance
        return instance


class SignInSerializer(serializer.Serializer):
    customer_id = serializer.IntegerField(required=False, allow_null=True)
    address = serializer.CharField(required=False, allow_null=True, allow_blank=True)
    file = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    remark = serializer.CharField(required=False, allow_null=True, allow_blank=True)

    def create(self, validated_data):
        user = self.context.get("user")
        validated_data["user"] = user
        validated_data["time"] = datetime.datetime.now()
        instance = SignIn.objects.create(**validated_data)
        return instance


class SignInListSerializer(serializer.ModelSerializer):
    user = serializer.SerializerMethodField()
    customer = serializer.SerializerMethodField()

    def get_user(self, obj):
        return {
            "id": obj.user.id,
            "nickname": obj.user.nickname
        } if obj.user else None

    def get_customer(self, obj):
        return {
            "id": obj.customer.customer.id,
            "crm_customer_id": obj.customer.id,
            "name": obj.customer.customer.name
        } if obj.customer else None

    class Meta:
        model = SignIn
        fields = ("id", "user", "file", "address", "customer", "time", "remark")


class MessageSerialzier(serializer.Serializer):
    customer_id = serializer.IntegerField(required=True, allow_null=False)
    user_id = serializer.ListField(child=serializer.IntegerField(required=True, allow_null=False))
    title = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    type = serializer.CharField(required=False, allow_blank=True, allow_null=True)
    send_type = serializer.ListField(child=serializer.IntegerField(required=False, allow_null=True))
    content = serializer.CharField(required=False, allow_null=True, allow_blank=True)

    def create(self, validated_data):
        request = self.context.get("request")
        instance = Message.objects.create(
            title=validated_data.get("title"),
            content=validated_data.get("content"),
            type=validated_data.get("type"),
            customer_id=validated_data.get("customer_id"),
            creater=request.data.get("user")
        )
        obj_list = []
        for i in validated_data.get("user_id"):
            obj_list.append(UserMessage(message=instance,
                                        user_id=i))
        UserMessage.objects.bulk_create(obj_list)
        return instance
