import random

from DCbackend.settings import IPINFO
from backend.Service.AdminService import AdminService
from backend.Service.SMSService import SMSService

from base import logger

import re

import requests
from django.core.paginator import Paginator
from django.db import transaction

from DCbackend import settings
from DCbackend.utils.common import success, fail, pageData
from backend.Form.WechatUserForm import WechatUserForm
from backend.models import WechatUser, Admin
from django.core.cache import cache
#微信公众号
class WechatService:
    @staticmethod
    @transaction.atomic
    def insertInfo(request):
        form = WechatUserForm(request.POST)
        if form.is_valid():
            form.save()
            return success("保存成功")
        else:
            return fail(form.errors)

    @staticmethod
    def getInfoList(request):
        page = request.POST.get("page")
        pageSize = request.POST.get("pageSize")
        if page is None:
            page = 1
        if pageSize is None:
            pageSize = 10

        where = {}

        name = request.POST.get("name", '')
        if name:
            where["name__icontains"] = name

        status = request.POST.get("status")
        if status:
            where['status'] = status

        paginator = Paginator(WechatUser.objects.filter(**where).exclude(status=4).order_by("-id"),
                              pageSize)  # 每页显示10条数据
        page_obj = paginator.get_page(page)
        dataList = []
        for item in page_obj:
            info = WechatService.getDetail(item)
            dataList.append(info)
        return success(pageData(page, pageSize, paginator.num_pages, paginator.count, dataList))

    @staticmethod
    def getDetail(item: WechatUser):
        return {
            "id": item.id,
            'name': item.name,
            'nikeName': item.nikeName,
            'phone': item.phone,
            'openid': item.openid,
            'age': item.age,
            'level': item.level,
            'user_id': item.user_id,
            'mini_url': item.mini_url,
            'examine': item.examine,
            'status': item.status,
            'source': item.source

        }

    @staticmethod
    @transaction.atomic
    def updateUserInfo(request):
        openid = request.POST.get("openid")

        wechatUser = WechatUser.objects.filter(openid=openid).exclude(status=4).first()
        if not wechatUser:
            return fail("未登录小程序")

        id_card = request.POST.get("id_card")
        if WechatService.is_valid_id(id_card):
            wechatUser.id_card = id_card
        else:
            return fail("身份证格式错误")

        wechatUser.name = request.POST.get("name")
        wechatUser.nikeName = request.POST.get("nikeName")
        wechatUser.age = request.POST.get("age")
        wechatUser.mini_url = request.POST.get("mini_url")
        wechatUser.phone = request.POST.get("purePhoneNumber")
        wechatUser.examine = request.POST.get("examine")
        wechatUser.save()
        return success("提交审核成功")

    @staticmethod
    @transaction.atomic
    def updateNikeName(request):
        openid = request.POST.get("openid")

        wechatUser = WechatUser.objects.filter(openid=openid).exclude(status=4).first()
        if not wechatUser:
            return fail("未登录小程序")
        wechatUser.nikeName = request.POST.get("nikeName")
        wechatUser.save()
        return success("提交审核成功")

    @staticmethod
    @transaction.atomic
    def to_examine(request):
        id = request.POST.get("id")
        if not id:
            return fail("id为空")
        wechatUser = WechatUser.objects.filter(id=id).exclude(status=4).first()
        if not wechatUser:
            return fail("无此小程序用户信息")
        level = request.POST.get("level")
        wechatUser.level = level
        wechatUser.examine = 1
        wechatUser.save()
        return success("审核完成")

    @staticmethod
    def is_valid_id(id_card):
        pattern = r'^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$'
        return bool(re.match(pattern, id_card))

    @staticmethod
    def deleteUserInfo(request):
        id = request.POST.get("id")
        wechatUser = WechatUser.objects.filter(id=id).first()
        if wechatUser:
            wechatUser.status = 4
            wechatUser.save()
            return success("删除成功")
        else:
            return fail("删除失败")

    @staticmethod
    def get_access_token(request):
        try:
            # 首先尝试从缓存中获取 access_token
            access_token = cache.get('wechat_access_token')
            if access_token:
                return access_token

            # return success("m没有获取到")
            # 如果缓存中没有，则从微信服务器获取新的 access_token
            appid = settings.WECHAT_APPID
            secret = settings.WECHAT_SECRET
            url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}"

            response = requests.get(url)
            result = response.json()

            if 'access_token' in result:
                access_token = result['access_token']
                expires_in = result.get('expires_in', 7200)  # 默认7200秒
                # 将 access_token 存入缓存，有效期设置比微信给的稍短一些
                cache.set('wechat_access_token', access_token, expires_in - 200)

                return access_token
            else:
                error_msg = result.get('errmsg', '未知错误')
                return fail(f"获取access_token失败: {error_msg}")

        except Exception as e:
            return fail(f"获取access_token时发生错误: {str(e)}")

    @staticmethod
    @transaction.atomic
    def wechatLogin(request):
        try:
            js_code = request.POST.get("code")
            if not js_code:
                return fail(f"缺少code参数,{js_code}")

            appid = settings.WECHAT_APPID
            secret = settings.WECHAT_SECRET
            url = "https://api.weixin.qq.com/sns/jscode2session"

            params = {
                "appid": appid,
                "secret": secret,
                "js_code": js_code,
                "grant_type": "authorization_code"
            }

            response = requests.get(url, params=params)
            result = response.json()

            if 'openid' in result:
                # 创建新的WechatUser对象
                wechat_user, created = WechatUser.objects.get_or_create(
                    openid=result['openid'],
                    source="mini",
                    defaults={
                        'level': 1,
                        'status': 5  # 假设1表示活跃状态
                    }
                )

                return success({
                    "openid": result['openid'],
                    "session_key": result.get('session_key'),
                    "unionid": result.get('unionid'),
                    "user_id": wechat_user.id,
                    "is_new_user": created
                }, "微信登录成功")
            else:
                error_msg = result.get('errmsg', '未知错误')
                return fail(f"微信登录失败: {error_msg}")

        except Exception as e:
            return fail(f"微信登录过程中发生错误: {str(e)}")

    @staticmethod
    @transaction.atomic
    def getUserPhoneNumber(request):
        try:
            access_token = WechatService.get_access_token(request)
            if not access_token:
                return fail("access_token为空")

            code = request.POST.get("code")
            if not code:
                return fail("缺少code参数")

            openid = request.POST.get("openid")
            if not openid:
                return fail("缺少openid")

            url = f"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={access_token}"

            data = {
                "code": code
            }

            response = requests.post(url, json=data)
            result = response.json()

            if result.get('errcode') == 0:
                phone_info = result.get('phone_info', {})
                purePhoneNumber = phone_info.get('purePhoneNumber')

                WechatUser.objects.filter(openid=openid, source="mini").update(phone=purePhoneNumber)

                return success({
                    "phoneNumber": phone_info.get('phoneNumber'),
                    "purePhoneNumber": purePhoneNumber,
                    "countryCode": phone_info.get('countryCode'),
                }, "获取用户手机号成功")
            else:
                error_msg = result.get('errmsg', '未知错误')
                return fail(f"获取用户手机号失败: {error_msg}")

        except Exception as e:
            return fail(f"获取用户手机号过程中发生错误: {str(e)}")

    @staticmethod
    def getOpenPid(request):
        try:
            access_token_result = WechatService.get_access_token(request)
            if not access_token_result:
                return fail("获取access_token失败")

            access_token = access_token_result

            code = request.POST.get("code")
            if not code:
                return fail("缺少code参数")

            url = f"https://api.weixin.qq.com/wxa/getpluginopenpid?access_token={access_token}"

            data = {
                "code": code
            }

            response = requests.post(url, json=data)
            result = response.json()

            if result.get('errcode') == 0:
                openpid = result.get('openpid')
                return success(openpid, "获取插件用户openPid成功")
            else:
                error_msg = result.get('errmsg', '未知错误')
                return fail(f"获取插件用户openPid失败: {error_msg}")

        except Exception as e:
            return fail(f"获取插件用户openPid过程中发生错误: {str(e)}")

    @staticmethod
    def getUserInfo(request):
        openid = request.POST.get("openid")
        if not openid:
            return fail("缺少 openid 参数")

        try:
            user = WechatUser.objects.filter(openid=openid).exclude(status=4).first()
            if not user:
                return fail("未找到用户信息")
            user_info = {
                "id": user.id,
                "name": user.name,
                "nikeName": user.nikeName,
                "phone": user.phone,
                "openid": user.openid,
                "age": user.age,
                "level": user.level,
                "user_id": user.user_id,
                "id_card": user.id_card,
                "mini_url": user.mini_url,
                "examine": user.examine,
                "status": user.status,
                "source": user.source,
            }
            return success(user_info)
        except WechatUser.DoesNotExist:
            return fail("用户不存在")

    @staticmethod
    def getKbmUrl(request):
        openid = request.POST.get("openid")

        # waibu = "https://ai.raycos.net/api/v1/run/951e3ba4-c66a-496c-9497-7dbddc2647f8?stream=false"
        # neibu = "https://ai.raycos.net/api/v1/run/9263c538-2cd2-4c1b-8c9a-3bb986920d6d?stream=false"
        #
        info = WechatUser.objects.filter(openid=openid).exclude(status=4).first()
        waibu = {}
        waibuurl = "http://ai.raycos.net/api/v1/run/951e3ba4-c66a-496c-9497-7dbddc2647f8?stream=false"
        waibutweaks = {
            "ChatInput-dDbhW": {
                "sender": info.openid,
                "sender_name": info.openid
            },
            "Prompt-1stgH": {},
            "ChatOutput-b1zWw": {},
            "OllamaModel-5n7vc": {},
            "Milvus-1X7fT": {},
            "OllamaEmbeddings-V29wK": {},
            "Memory-GrHZr": {
                "session_id": info.openid
            },
            "ParseData-0dk9n": {}
        }

        waibu["url"] = waibuurl
        waibu["tweaks"] = waibutweaks

        neibu = {}
        neibuurl = "https://ai.raycos.net/api/v1/run/9263c538-2cd2-4c1b-8c9a-3bb986920d6d?stream=false"
        neibutweaks = {
            "ChatInput-NYqTq": {
                "sender": info.openid,
                "sender_name": info.openid
            },
            "Prompt-oVfSC": {},
            "ChatOutput-sA5Uc": {},
            # "SplitText-GvztW": {},
            # "File-rHitZ": {},
            "OllamaModel-UxNZ1": {},
            "Milvus-fRZVH": {},
            "OllamaEmbeddings-lHoKv": {},
            "Memory-ZBrXL": {
                "session_id": info.openid
            },
            "ParseData-ZmaJQ": {}

        }
        neibu["url"] = neibuurl
        neibu["tweaks"] = neibutweaks

        if not openid:
            return success(waibu, "普通用户返回外部知识库链接")

        if not info:
            return success(waibu, "普通用户返回外部知识库链接")
        if info.level == 1:
            return success(waibu, "普通用户返回外部知识库链接")

        return success(neibu, "内部人员返回内部知识库链接")

    @staticmethod
    @transaction.atomic
    def updateBackground(request):
        id = request.POST.get("id")
        wechatUser = WechatUser.objects.filter(id=id).first()
        if wechatUser:
            wechatUser.name = request.POST.get("name")
            wechatUser.nikeName = request.POST.get("nikeName")
            wechatUser.phone = request.POST.get("phone")
            wechatUser.openid = request.POST.get("openid")
            wechatUser.age = request.POST.get("age")
            wechatUser.level = request.POST.get("level")
            wechatUser.user_id = request.POST.get("user_id")
            wechatUser.id_card = request.POST.get("id_card")
            wechatUser.mini_url = request.POST.get("mini_url")
            wechatUser.status = request.POST.get("status")
            wechatUser.save()
            return success("修改成功")
        else:
            return fail("修改失败")
    @staticmethod
    def pcSMS(request):
        phone = request.POST.get("phone")
        if not phone:
            return fail("手机号为空")
        verification_code = ''.join(random.choices('0123456789', k=6))
        result = SMSService.send_sms(phone, verification_code)
        if result and result.get('Code') == 'OK':
            cache.set(f"sms_code:{phone}", verification_code, timeout=3*60)
            return success("验证码发送成功")
        else:
            return fail("验证码发送失败")

    #校验验证码
    @staticmethod
    def codeCheckout(request):
        phone = request.POST.get("phone")
        if not phone:
            return fail("手机号为空")
        verification_code = request.POST.get("verification_code")
        if not verification_code:
            return fail("验证码为空")
        stored_code = cache.get(f"sms_code:{phone}")
        if verification_code == stored_code:
            return success(phone,"验证成功")
        else:
            return fail("验证失败,请检查验证码和手机号")
    @staticmethod
    @transaction.atomic
    def pcLoging(request):
        try:
            phone = request.POST.get("phone")
            if not phone:
                return fail("手机号为空")

            info, created = WechatUser.objects.get_or_create(
                phone=phone,
                source="pc",
                defaults={
                    'level': 1,
                    'status': 5
                }
            )

            waibu = {
                "url": f"http://{IPINFO}:7860/api/v1/run/951e3ba4-c66a-496c-9497-7dbddc2647f8?stream=false",
                "tweaks": {
                    "ChatInput-dDbhW": {
                        "sender": info.phone,
                        "sender_name": info.phone
                    },
                    "Prompt-1stgH": {},
                    "ChatOutput-b1zWw": {},
                    "OllamaModel-5n7vc": {},
                    "Milvus-1X7fT": {},
                    "OllamaEmbeddings-V29wK": {},
                    "Memory-GrHZr": {
                        "session_id": info.phone
                    },
                    "ParseData-0dk9n": {}
                }
            }
            return success(waibu,"登录成功")

        except Exception as e:
            logger.info(f"登录异常：{e}")
            return fail(str(e))


    @staticmethod
    def pcInnerAi(request):
        token = request.POST.get("token")
        if not token:
            return fail("token为空")
        adminInfo = AdminService.verify_token(token)
        if not adminInfo:
            return fail("查无此人")

        uid = adminInfo.id
        neibu = {
            "url": f"http://{IPINFO}:7860/api/v1/run/ed188be9-5bf5-4194-b35d-6a583a44452d?stream=false",
            "tweaks":{
            "ChatInput-aJZLS": {
                "sender": str(uid),
                "sender_name": str(uid)
            },
            "Prompt-hc9OF": {},
            "ChatOutput-5HfMA": {},
            # "SplitText-GvztW": {},
            # "File-rHitZ": {},
            "OllamaModel-kxuW7": {},
            "Milvus-q5ixS": {},
            "OllamaEmbeddings-ANKWT": {},
            "Memory-FHaLh": {
                "session_id": str(uid)
            },
            "ParseData-tNR5t": {}
            }
        }

        return success(neibu,"内部链接")














