# encoding: utf-8
"""
@project: djangoModel->user_info_service
@author: 孙楷炎
@Email: sky4834@163.com
@synopsis: 用户信息服务
@created_time: 2022/6/27 19:51
"""
from django.core.paginator import Paginator, EmptyPage
from django.db.models import F, Case, When, Value, CharField, OuterRef, Subquery
from django.db.models import Prefetch
from django.db.models.functions import Coalesce
from django.forms import model_to_dict

from xj_user.utils.j_parameter import JParameter
# from orator import DatabaseManager

# from config.config import JConfig
from ..models import BaseInfo, DetailInfo, ExtendField
# from ..models import UserApplyRecord
from ..services.user_service import UserService
from ..utils.j_transform_type import JTransformType
from ..utils.format_params_handle import format_params_handle
from ..utils.filter_fields_handler import filter_fields_handler
from ..utils.format_list_handle import format_list_handle
from ..utils.dynamic_load_class import dynamic_load_class


# from ..utils.custom_tool import *

# orator ORM 初始化
# config = JConfig()
# db_config = {
#     config.get('main', 'driver', "mysql"): {
#         'driver': config.get('main', 'driver', "mysql"),
#         'host': config.get('main', 'mysql_host', "127.0.0.1"),
#         'database': config.get('main', 'mysql_database', ""),
#         'user': config.get('main', 'mysql_user', "root"),
#         'password': config.get('main', 'mysql_password', "123456"),
#         "port": config.getint('main', 'mysql_port', "3306")
#     }
# }
# db = DatabaseManager(db_config)


class DetailInfoService:
    # 用户基础字段
    base_fields = UserService.base_fields
    # 用户详情字段。不含扩展
    detail_fields = ['real_name', 'sex', 'birth', 'tags', 'signature', 'cover', 'id_card_type', 'id_card_no',
                     'language', 'region_code', 'more']

    # user_detail_expect_extend = [i.name for i in DetailInfo._meta.fields if not "field_" in i.name] + ["user_id"]
    # user_detail_remove_fields = [i.name for i in DetailInfo._meta.fields if "field_" in i.name] + ["id", "user"]
    # 详情信息扩展字段获取。该行代码在执行manage.py makemigragtion 会报表不存在 20230822 by Sieyoo
    # field_map_list = list(ExtendField.objects.all().values("field", 'field_index'))
    # field_map_list = list(ExtendField.objects.all().values("field", 'field_index')) if ExtendField.objects.all().values(
    #     "field", 'field_index') else list()
    field_map_list = []

    @classmethod
    def get_list_detail(cls, params: dict = None, user_id_list: list = None, filter_fields: list = None, **kwargs):
        """
        详细信息列表
        :param filter_fields: 需要过滤的字段
        :param params: 搜索参数
        :param user_id_list: 用户ID列表。请注意：如果传递过来的参数不是有效的列表，则按照正常的分页搜索返回。
        :return: list,err
        """
        params, is_pass = force_transform_type(variable=params, var_type="dict", default={})
        page, is_pass = force_transform_type(variable=params.pop('page', 1), var_type="int", default=1)
        size, is_pass = force_transform_type(variable=params.pop('size', 10), var_type="int", default=10)
        user_group_id, is_pass = force_transform_type(variable=params.detail('user_group_id'), var_type="int")
        user_role_id, is_pass = force_transform_type(variable=params.detail('user_role_id'), var_type="int")

        # 查询排序字段处理
        sort = params.pop('sort', "-register_time")
        sort = sort if sort in ["register_time", "-register_time", "user_id", "-user_id"] else "-id"

        # 扩展字段映射字典
        field_map_list = DetailInfoService.field_map_list
        field_map = {item['field_index']: item['field'] for item in field_map_list}
        reversal_filed_map = {item['field']: item['field_index'] for item in field_map_list}

        # 默认返回字段去掉与的敏感信息
        # default_field_list = DetailInfoService.detail_fields + list(field_map.values()) + [
        #     "is_delete", "username", "fullname", "nickname", "user_id", "phone",
        #     "is_using", "user_identity", "subcompany_name"
        # ]
        # 默认返回字段去掉与的敏感信息
        default_field_list = DetailInfoService.detail_fields + list(field_map.values()) + [
            "is_delete", "username", "fullname", "nickname", "user_id", "phone",
            "is_using", "user_identity"
        ]
        # all_field_list = DetailInfoService.detail_fields + DetailInfoService.base_fields + list( field_map.values()) + ["subcompany_name"]
        all_field_list = DetailInfoService.detail_fields + DetailInfoService.base_fields + list(field_map.values())
        # 过滤字段处理
        filter_fields = format_list_handle(
            param_list=filter_fields_handler(
                input_field_expression=filter_fields,
                default_field_list=default_field_list,
            ),
            filter_filed_list=all_field_list,
            alias_dict=reversal_filed_map
        )
        # 查询ORM构建
        # subcompany_name_subquery = UserSubCompany.objects.filter(id=OuterRef('subcompany_id')).values('name')
        detail_info_obj = DetailInfo.objects.extra(
            select={"register_time": 'DATE_FORMAT(user_base_info.register_time, "%%Y-%%m-%%d %%H:%%i:%%s")'}
        ).filter(user__is_delete=0).annotate(
            username=F("user__username"),
            fullname=F("user__fullname"),
            nickname=F("user__nickname"),
            phone=F("user__phone"),
            email=F("user__email"),
            user_info=F("user__user_info"),
            privacies=F("user__privacies"),
            user_type=F("user__user_type"),
            user_identity=F("user__user_identity"),
            is_delete=F("user__is_delete"),
            is_using=F("user__is_using"),
            # subcompany_name=Subquery(subcompany_name_subquery),
        ).order_by(sort).values(*filter_fields)
        total = 0

        # id搜索,并且不分页，作为服务提供者
        # 搜索字典过滤处理,过滤掉不允许搜索的字段
        if not user_id_list is None and isinstance(user_id_list, list):
            # id列表参数校验，确保每一个参数都是有效得到int类型
            validate_user_id_list = []
            for i in user_id_list:
                var, valid = force_transform_type(variable=i, var_type="int")
                if valid:
                    continue
                validate_user_id_list.append(var)
            validate_user_id_list = list(set(validate_user_id_list))

            # 进行参数搜索
            res_list = detail_info_obj.filter(user_id__in=validate_user_id_list)

        elif user_role_id:
            # TODO 已经用了DJango的ORM，就不要用第三方的ORM了 20241206 by Sieyoo
            res_obj = {}
            # res_obj = db.table("role_user_to_role"). \
            #     select("role_user_to_role.role_id",
            #            "role_user_to_role.user_id",
            #            "uuid",
            #            "username",
            #            "fullname",
            #            "nickname",
            #            "phone",
            #            "email",
            #            "user_info",
            #            "user_type",
            #            "privacies",
            #            "register_time",
            #            "is_delete",
            #            "real_name",
            #            "sex",
            #            "birth",
            #            "tags",
            #            "signature",
            #            "avatar",
            #            "cover",
            #            "language",
            #            "region_code",
            #            "more",
            #            "field_1",
            #            "field_2",
            #            "field_3",
            #            "field_4",
            #            "field_5",
            #            "field_6",
            #            "field_7",
            #            "field_8",
            #            "field_9",
            #            "field_10",
            #            "field_11",
            #            "field_12",
            #            "field_13",
            #            "field_14",
            #            "field_15",
            #            ). \
            #     left_join("user_detail_info", "user_detail_info.user_id", "=", "role_user_to_role.user_id"). \
            #     left_join("user_base_info", "user_base_info.id", "=", "role_user_to_role.user_id"). \
            #     where("role_user_to_role.role_id", user_role_id)

            result_list = res_obj.paginate(size, page)
            total = result_list.total
            res_data = filter_result_field(
                result_list=filter_result_field(  # 扩展字段替换
                    result_list=result_list,
                    alias_dict=field_map,
                ),
                remove_filed_list=DetailInfoService.user_detail_remove_fields,  # 移除未配置的扩展字段已经主键ID
                alias_dict={"user": "user_id", "cover": "user_cover", "region_code": "user_region_code"}
                # 外键字段还原成ID，并起别名
            )

            return {'size': int(size), 'page': int(page), 'total': total, 'list': res_data}, None
        elif user_group_id:
            # TODO 已经用了DJango的ORM，就不要用第三方的ORM了 20241206 by Sieyoo
            res_obj = {}
            # res_obj = db.table("role_user_to_group"). \
            #     select("role_user_to_group.user_group_id",
            #            "role_user_to_group.user_id",
            #            "uuid",
            #            "username",
            #            "fullname",
            #            "nickname",
            #            "phone",
            #            "email",
            #            "user_info",
            #            "user_type",
            #            "privacies",
            #            "register_time",
            #            "is_delete",
            #            "real_name",
            #            "sex",
            #            "birth",
            #            "tags",
            #            "signature",
            #            "avatar",
            #            "cover",
            #            "language",
            #            "region_code",
            #            "more",
            #            "field_1",
            #            "field_2",
            #            "field_3",
            #            "field_4",
            #            "field_5",
            #            "field_6",
            #            "field_7",
            #            "field_8",
            #            "field_9",
            #            "field_10",
            #            "field_11",
            #            "field_12",
            #            "field_13",
            #            "field_14",
            #            "field_15",
            #            ). \
            #     left_join("user_detail_info", "user_detail_info.user_id", "=", "role_user_to_group.user_id"). \
            #     left_join("user_base_info", "user_base_info.id", "=", "role_user_to_group.user_id"). \
            #     where("role_user_to_group.user_group_id", user_group_id)

            result_list = res_obj.paginate(size, page)
            total = result_list.total
            res_data = filter_result_field(
                result_list=filter_result_field(  # 扩展字段替换
                    result_list=result_list,
                    alias_dict=field_map,
                ),
                remove_filed_list=DetailInfoService.user_detail_remove_fields,  # 移除未配置的扩展字段已经主键ID
                alias_dict={"user": "user_id", "cover": "user_cover", "region_code": "user_region_code"}
                # 外键字段还原成ID，并起别名
            )

            return {'size': int(size), 'page': int(page), 'total': total, 'list': res_data}, None
        else:
            search_params = format_params_handle(
                param_dict=params,
                filter_filed_list=all_field_list + ["register_time_start", "register_time_end", "user_id_list"],
                alias_dict=reversal_filed_map
            )
            search_params = format_params_handle(
                param_dict=search_params,
                alias_dict={
                    "user_type": "user_type__contains",
                    "username": "username__contains",
                    "nickname": "nickname__contains",
                    "email": "email__contains",
                    "phone": "phone__contains",
                    "fullname": "fullname__contains",
                    "real_name": "real_name__contains",
                    "register_time_start": "user__register_time__gte",
                    "register_time_end": "user__register_time__lte",
                    "user_id_list": "user__id__in"
                }
            )
            list_set = detail_info_obj.filter(**search_params)
            total = list_set.count()
            paginator = Paginator(list_set, size)
            try:
                list_set = paginator.page(page)
            except EmptyPage:
                list_set = paginator.page(paginator.num_pages)
            except Exception as e:
                return None, e.__str__()
            res_list = list(list_set.object_list)

        res_data = filter_result_field(
            result_list=filter_result_field(  # 扩展字段替换
                result_list=res_list,
                alias_dict=field_map,
            ),
            remove_filed_list=DetailInfoService.user_detail_remove_fields,  # 移除未配置的扩展字段已经主键ID
            alias_dict={"user": "user_id", "cover": "user_cover", "region_code": "user_region_code"}  # 外键字段还原成ID，并起别名
        )
        # 分情况返回数据
        if not user_id_list is None and isinstance(user_id_list, list):
            return res_data, None
        else:
            return {'size': int(size), 'page': int(page), 'total': total, 'list': res_data}, None

    @classmethod
    def get_detail(cls, user_id: int = None, user_uuid: str = None):
        """
        获取当前用户的基础信息和详细信息集合
        :param user_id: 通过用户ID搜索
        :param user_uuid: 通过用户UUID搜索
        :return: detail_info,err_msg
        """

        # 边界防传字串
        user_id, is_pass = JTransformType.to(user_id, "int", {})

        # 二选一必填
        if not user_id and not user_uuid:
            return None, '用户ID或UUID必填'

        # 查询用户信息
        user_set = BaseInfo.objects.annotate(user_id=F('id'), user_uuid=F('uuid'))
        if user_id:
            user_set = user_set.filter(id=user_id)
        elif user_uuid:
            user_set = user_set.filter(uuid=user_uuid)

        # 左连详细信息
        user_set = user_set.select_related('user_detail_info')  # select_related 用于正向查询，当左连表不存在时不会处理空值。

        # 日期格式化
        user_set = user_set.extra(select={
            'register_time': 'DATE_FORMAT(register_time, "%%Y-%%m-%%d %%H:%%i:%%s")',
            'birth_format': 'DATE_FORMAT(birth, "%%Y-%%m-%%d %%H:%%i:%%s")',  # 临时存放字段。因为左连表字段冲突
        })

        # 访问数据库
        user_set = user_set.first()
        if not user_set:
            return None, '用户不存在'
        detail_set = user_set.user_detail_info if hasattr(user_set, 'user_detail_info') else {}
        # print(f">detail_set:{detail_set}")

        # 获取拓展配置
        field_map_list = ExtendField.objects.all().values("field", 'field_index')

        # 生成字典数据
        whole_dict = {}
        base_dict = {k: getattr(user_set, k) for k in cls.base_fields}
        detail_dict = {k: getattr(detail_set, k) if hasattr(detail_set, k) else None for k in cls.detail_fields}
        extend_dict = {it['field']: getattr(detail_set, it['field_index']) for it in field_map_list if
                       hasattr(detail_set, it['field_index'])}
        whole_dict.update(base_dict, **detail_dict, **extend_dict)
        whole_dict['birth'] = user_set.birth_format  # 修正日期格式化时字段冲突失效的问题
        # print(f"whole_dict: {whole_dict}")

        # ================== section 追加信息 start ==============
        # # 获取用户审核信息
        # result_dict = ["UN_APPLY", "VERIFYING", "VERIFY_PASS", "VERIFY_REJECT"]
        # # print('> get_detail filter_dict:', filter_dict)
        # real_name_result = result_dict[filter_dict.get('real_name_is_pass', 0)]  # 实名认证状态
        # audit_result = result_dict[filter_dict.get('audit_status', 0)]  # 镖师认证状态
        # # print("> get_detail real_name_result, audit_result:", real_name_result, audit_result)
        #
        # if real_name_result == "VERIFY_REJECT":  # 审核不通过才需要原因
        #     reply_record = UserApplyRecord.objects.filter(user_id=user_id, apply_type_id=1,
        #                                                   result=real_name_result).order_by("-id").values(
        #         "reject_reason").first()
        #     if reply_record:
        #         filter_dict["reject_real_name_reason"] = reply_record["reject_reason"]
        # if audit_result == "VERIFY_REJECT":  #
        #     reply_record = UserApplyRecord.objects.filter(user_id=user_id, apply_type_id=2,
        #                                                   result=audit_result).order_by("-id").values(
        #         "reject_reason").first()
        #     if reply_record:
        #         filter_dict["reject_audit_status_reason"] = reply_record["reject_reason"]
        # # ================== section 追加信息 end ================

        return whole_dict, None

    @classmethod
    def create_or_update_detail(cls, params: dict = None, **kwargs):
        """
        添加或者更新用户的详细信息
        :param params: 添加/修改参数
        :return: None,err_msg
        """
        # 参数判断
        kwargs, is_pass = JTransformType.to(variable=kwargs, var_type="dict", default={})
        params, is_pass = JTransformType.to(variable=params, var_type="dict", default={})
        params.update(kwargs)

        user_id, is_pass = JTransformType.to(variable=params.pop('user_id', None), var_type="int")
        if not user_id:
            return None, "参数错误,user_id不能为空"
        # 判断用户是否存在
        user_base = BaseInfo.objects.filter(id=user_id)
        user_base_info = user_base.first()
        if not user_base_info:
            return None, '用户不存在'
        # =========== section 获取扩展字段的映射，默认值 start =================
        extend_field_list = ExtendField.objects.all().values("field", 'field_index', 'default')
        alias_dict = {item['field']: item['field_index'] for item in extend_field_list}  # 字段还原映射字典
        default_map = {item['field_index']: item['default'] for item in extend_field_list if
                       not item['default'] is None}  # 默认字段
        filter_filed_list = [i.name for i in DetailInfo._meta.fields]  # 字段列表
        # 强制类型转换,防止修改报错
        filter_filed_list.remove("id")
        filter_filed_list.remove("birth")
        filter_filed_list.remove("region_code")
        filter_filed_list.remove("more")
        # filter_filed_list.append("birth|date")
        filter_filed_list.append("region_code|int")
        filter_filed_list.append("more|dict")
        filter_filed_list.append("subcompany_id|int")
        # =========== section 获取扩展字段的映射，默认值 end   =================

        # =========== section 把扩展字段还原成 start =================
        # 剔除掉不是配置的扩展字段,还有原表的字段
        transformed_params = format_params_handle(
            param_dict=format_params_handle(
                param_dict=params,
                alias_dict=alias_dict
            ),
            filter_filed_list=filter_filed_list,
        )
        transformed_params.setdefault("user_id", user_id)
        # print("transformed_params >>>", transformed_params)
        # =========== section 把扩展字段还原成 end   =================
        # =========== section 进行数据库操作 start ============
        try:
            # 判断是否添加过
            detail_user_obj = DetailInfo.objects.filter(user_id=user_id)
            if not detail_user_obj.first():
                # 没有添加，进行添加操作
                transformed_params.pop("id", None)  # 添加的时候不能有ID主键，防止主键冲突
                # 在添加的时候给字段默认值
                for field_index, default in default_map.items():
                    transformed_params.setdefault(field_index, default)

                DetailInfo.objects.create(**transformed_params)
            else:
                # 添加过进行跟新
                detail_user_obj.update(**transformed_params)
            return None, None
        except Exception as e:
            return None, "参数配置错误：" + str(e)
        # =========== section 进行数据库操作 end   ============

    @classmethod
    def get_extend_fields(cls) -> list:
        """
        获取用户表扩展字段，前端渲染使用
        :return: fields_list,None
        """
        extend_fields = ExtendField.objects.order_by("-sort").all().values()
        return list(extend_fields), None

    @classmethod
    def set_extend_fields(cls, params) -> list:
        """
        获取用户表扩展字段，前端渲染使用。
        :param params 添加的参数
        :return: fields_list,None
        """
        allow_params = {}
        extend_fields = ExtendField.objects.order_by("-sort").all().values()
        return list(extend_fields), None
