# -*- encoding: utf-8 -*-
"""
@File    : UserDeviceShareController.py
@Time    : 2023/1/7 15:05
@Author  : stephen
@Email   : zhangdongming@asj6.wecom.work
@Software: PyCharm
"""
import json
import logging
import threading
import time

import boto3
import botocore
from botocore import client
from django.db import transaction
from django.db.models import Q
from django.views import View

from Model.models import DeviceSharePermission, DeviceChannelUserSet, DeviceChannelUserPermission, UidChannelSetModel, \
    Device_Info
from Object.ContentSecurityObject import ContentSecurity
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.UserDeviceService import UserDeviceService
from Ansjer.config import CONFIG_CN, CONFIG_INFO, CONFIG_TEST, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
    AWS_SES_ACCESS_REGION, AWS_IOT_SES_ACCESS_CHINA_REGION
from Model.models import DeviceWallpaper
from Object.AWS.AmazonS3Util import AmazonS3Util

LOGGER = logging.getLogger('info')


class UserDeviceShareView(View):

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.GET, request, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.POST, request, operation)

    def validation(self, request_dict, request, operation):
        token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
        lang = request_dict.get('lang', token.lang)
        response = ResponseObject(lang)
        if token.code != 0:
            return response.json(token.code)
        if operation == 'user-permissions':
            return self.get_user_share_permission(request_dict, response)
        elif operation == 'permissions-save':
            return self.user_channel_permission_save(request_dict, response)
        elif operation == 'permissions-test':
            return self.synch_share_device_permission(response)
        elif operation == 'getWallpaperList':
            return self.get_wallpaper_list(request_dict, response)
        elif operation == 'getUploadWallpaper':
            return self.get_upload_wallpaper(request_dict, response)
        elif operation == 'notifyUploadWallpaper':
            return self.notify_upload_wallpaper(request_dict, response)
        elif operation == 'delWallpaper':
            return self.del_wallpaper(request_dict, response)
        elif operation == 'selectWallpaper':
            return self.select_wallpaper(request_dict, response)
        else:
            return response.json(404)

    @classmethod
    def get_user_share_permission(cls, request_dict, response):
        """
        获取用户分享权限
        @param request_dict: 设备uid
        @param response: 响应对象
        @return: permission List
        """
        try:
            uid = request_dict.get('uid', None)
            user_id = request_dict.get('userId', None)
            channel_count = request_dict.get('channelCount', None)
            if not all([user_id, uid, channel_count]):
                return response(444, 'uid, userId and channelCount is required')
            user_permission_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) \
                .values('id', 'channels')
            if not user_permission_qs.exists():
                return response.json(0, {})
            up_id = user_permission_qs[0]['id']
            channel_permission_qs = DeviceChannelUserPermission.objects.filter(channel_user_id=up_id) \
                .values('permission_id', 'channel_user_id')
            if not channel_permission_qs.exists():
                return response.json(0, {})
            channel_list = list(range(1, int(channel_count) + 1))
            share_channel_list = user_permission_qs[0]['channels'].split(',')
            c_list = []
            for channel in channel_list:
                is_select = 1 if str(channel) in share_channel_list else 0
                c_list.append({'channelIndex': channel, 'isSelect': is_select})
            p_list = []
            permission_qs = DeviceSharePermission.objects.all()
            share_permission_list = [item['permission_id'] for item in channel_permission_qs]
            for item in permission_qs:
                is_select = 1 if item.id in share_permission_list else 0
                p_list.append({'permissionId': item.id, 'code': item.code, 'isSelect': is_select})
            data = {'channels': c_list, 'permissions': p_list}
            return response.json(0, data)
        except Exception as e:
            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @classmethod
    def user_channel_permission_save(cls, request_dict, response):
        """
        主用户分享设备时设置通道权限保存
        """
        try:
            uid = request_dict.get('uid', None)
            channels = request_dict.get('channels', None)  # 通道集合，多个','隔开
            user_id = request_dict.get('userId', None)
            permission_ids = request_dict.get('permissionIds', None)  # 权限集合，多个','隔开
            if not all([user_id, uid, channels, permission_ids]):
                return response.json(444)
            p_ids = []
            device_user_set = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
            now_time = int(time.time())
            with transaction.atomic():
                is_delete = False
                if not device_user_set.exists():
                    device_set = {'uid': uid, 'user_id': user_id, 'channels': channels,
                                  'created_time': now_time, 'updated_time': now_time}
                    device_user_set = DeviceChannelUserSet.objects.create(**device_set)
                    channel_user_id = device_user_set.id
                else:
                    DeviceChannelUserSet.objects.update(channels=channels, updated_time=now_time)
                    channel_user_id = device_user_set.first().id
                    is_delete = True
                if ',' in permission_ids:
                    p_ids = [int(val) for val in permission_ids.split(',')]
                if is_delete:
                    DeviceChannelUserPermission.objects.filter(
                        channel_user_id=channel_user_id).delete()
                if not p_ids:
                    channel_permission = {'permission_id': int(permission_ids),
                                          'channel_user_id': channel_user_id,
                                          'created_time': now_time}
                    DeviceChannelUserPermission.objects.create(**channel_permission)
                else:
                    channel_permission_list = []
                    for item in p_ids:
                        channel_permission_list.append(DeviceChannelUserPermission(
                            permission_id=int(item),
                            channel_user_id=channel_user_id,
                            created_time=now_time))
                    DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
                return response.json(0)
        except Exception as e:
            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def qrcode_share_channel_permission_save(user_id, uid):
        """
        二维码分享保存通道权限
        @param user_id: 用户id
        @param uid: 用户设备ID
        @return: True | False
        """
        try:
            if not all([user_id, uid]):
                return False
            with transaction.atomic():
                ds_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
                if ds_qs.exists():
                    return True
                UserDeviceService.update_device_channel(uid)
                channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid).values('channel')
                if not channel_qs.exists():
                    return False
                channel_list = [str(val['channel']) for val in channel_qs]
                channel_str = ','.join(channel_list)
                now_time = int(time.time())
                device_set = {'uid': uid, 'user_id': user_id, 'channels': channel_str,
                              'created_time': now_time, 'updated_time': now_time}
                device_user_set = DeviceChannelUserSet.objects.create(**device_set)
                channel_permission_qs = DeviceSharePermission.objects \
                    .all().values('id', 'code').order_by('sort')
                user_set_id = device_user_set.id
                channel_permission_list = []
                for item in channel_permission_qs:
                    channel_permission_list.append(DeviceChannelUserPermission(
                        permission_id=item['id'],
                        channel_user_id=user_set_id,
                        created_time=now_time))
                DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
            return True
        except Exception as e:
            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return False

    @staticmethod
    def synch_share_device_permission(response):
        """
        同步分析设备权限
        @param response: 响应结果
        """
        device_info_qs = Device_Info.objects \
            .filter(~Q(Type__in=[1, 2, 3, 4, 10001]), ~Q(primaryUserID=''), isShare=1) \
            .values('userID_id', 'UID').order_by('-data_joined')
        if not device_info_qs.exists():
            return response.json(0)
        for item in device_info_qs:
            UserDeviceShareView.qrcode_share_channel_permission_save(item['userID_id'], item['UID'])
        return response.json(0)

    @classmethod
    def get_wallpaper_list(cls, request_dict, response):
        """
        获取设备壁纸列表
        @param request_dict:
        @param response:
        @return:
        """
        try:
            device_type = int(request_dict.get('deviceType', None))
            uid = request_dict.get('uid', None)
            channel = int(request_dict.get('channel', 1))
            LOGGER.info('获取设备壁纸列表参数:{}'.format(request_dict))
            if not all([device_type, uid]):
                return response.json(444)

            # 查询用户自定义壁纸
            user_wallpaper_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
                                                               device_type=device_type, parent_id=0, status=1)

            # 查询系统默认壁纸
            def_wallpaper_qs = DeviceWallpaper.objects.filter(classification=1, device_type=device_type, uid='',
                                                              status=1)

            # 查询用户选中的壁纸
            user_checked_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
                                                             device_type=device_type, parent_id__gt=0, status=1)
            checked_id = user_checked_qs[0].parent_id if user_checked_qs.exists() else 0

            wallpaper_list = []
            if def_wallpaper_qs.exists() or user_wallpaper_qs.exists():
                # 初始化存储桶客户端
                if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
                    s3 = boto3.client(
                        's3',
                        aws_access_key_id=AWS_ACCESS_KEY_ID[0],
                        aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
                        config=botocore.client.Config(signature_version='s3v4'),
                        region_name='cn-northwest-1'
                    )
                else:
                    s3 = boto3.client(
                        's3',
                        aws_access_key_id=AWS_ACCESS_KEY_ID[1],
                        aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
                        config=botocore.client.Config(signature_version='s3v4'),
                        region_name='us-east-1'
                    )

                # 处理系统默认壁纸和用户自定义壁纸
                all_wallpapers_qs = def_wallpaper_qs.union(user_wallpaper_qs)
                for item in all_wallpapers_qs:
                    obj_key = item.obj_prefix + item.obj_name
                    params = {
                        'Key': obj_key,
                        'Bucket': 'ansjerfilemanager',
                    }
                    response_url = s3.generate_presigned_url(
                        'get_object', Params=params, ExpiresIn=3600)
                    wallpaper = {
                        'id': item.id,
                        'url': response_url,
                        'state': 1 if checked_id == item.id else 0,
                        'classification': item.classification
                    }
                    wallpaper_list.append(wallpaper)

            return response.json(0, {'wallpapers': wallpaper_list})

        except Exception as e:
            LOGGER.error('查询设备壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(5)

    @classmethod
    def get_upload_wallpaper(cls, request_dict, response):
        """
        获取设备壁纸上传链接
        @param request_dict:
        @param response:
        @return:
        """
        try:
            uid = request_dict.get('uid', None)
            channel = int(request_dict.get('channel', 1))

            if not uid:
                return response.json(444)

            # 初始化存储桶客户端
            if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
                s3 = boto3.client(
                    's3',
                    aws_access_key_id=AWS_ACCESS_KEY_ID[0],
                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
                    config=botocore.client.Config(signature_version='s3v4'),
                    region_name='cn-northwest-1'
                )
            else:
                s3 = boto3.client(
                    's3',
                    aws_access_key_id=AWS_ACCESS_KEY_ID[1],
                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
                    config=botocore.client.Config(signature_version='s3v4'),
                    region_name='us-east-1'
                )

            # 生成唯一的文件名
            file_name = f"{int(time.time())}.png"
            obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"

            # 生成预签名的 URL
            presigned_url = s3.generate_presigned_url(
                'put_object',
                Params={
                    'Bucket': 'ansjerfilemanager',
                    'Key': obj_key,
                },
                ExpiresIn=600
            )

            # 返回预签名的URL和字段
            return response.json(0, {
                'uploadUrl': presigned_url,
                'fileName': file_name,
            })

        except Exception as e:
            LOGGER.error('获取上传链接异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(5)

    @classmethod
    def notify_upload_wallpaper(cls, request_dict, response):
        """
        确认壁纸上传成功，创建DeviceWallpaper
        @param request_dict:
        @param response:
        @return:
        """
        try:
            uid = request_dict.get('uid', None)
            file_name = request_dict.get('fileName', None)
            channel = int(request_dict.get('channel', 1))

            if not all([uid, file_name]):
                return response.json(444)

            device_info_qs = Device_Info.objects.filter(UID=uid).values('id', 'Type')
            device_type = device_info_qs[0]['Type'] if device_info_qs.exists() else ''

            # 初始化存储桶客户端
            if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
                s3 = boto3.client(
                    's3',
                    aws_access_key_id=AWS_ACCESS_KEY_ID[0],
                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
                    config=botocore.client.Config(signature_version='s3v4'),
                    region_name='cn-northwest-1'
                )
            else:
                s3 = boto3.client(
                    's3',
                    aws_access_key_id=AWS_ACCESS_KEY_ID[1],
                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
                    config=botocore.client.Config(signature_version='s3v4'),
                    region_name='us-east-1'
                )

            obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"
            params = {'Bucket': "ansjerfilemanager", 'Key': obj_key}
            image_url = s3.generate_presigned_url('get_object', Params=params)
            service = 'profilePhotoCheck'
            LOGGER.info('壁纸链接:{}'.format(image_url))
            service_dict = {'imageUrl': image_url}
            service_parameters = json.dumps(service_dict)
            legal = ContentSecurity().image_review(service, service_parameters)
            if not legal:
                # 异步删除
                thread = threading.Thread(target=cls.delete_wallpaper, args=(obj_key,))
                thread.start()
                return response.json(184)

            DeviceWallpaper.objects.create(
                device_type=device_type,
                storage_type=1,
                channel=channel,
                uid=uid,
                obj_prefix=f'app/static/device-wallpaper/{uid}/',
                obj_name=file_name,
                classification=2,  # 自定义壁纸分类
                status=1,
                parent_id=0,
                created_time=int(time.time())
            )
            return response.json(0)

        except Exception as e:
            LOGGER.error('壁纸创建失败:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(5)

    @classmethod
    def del_wallpaper(cls, request_dict, response):
        """
        删除设备壁纸
        """
        wallpaper_id = request_dict.get('wallpaperId', None)
        if not all([wallpaper_id]):
            return response.json(444)
        try:
            wallpaper_id = int(wallpaper_id)
            if DeviceWallpaper.objects.filter(id=wallpaper_id, classification=1).exists():
                return response.json(176, "系统图片不能删除")
            device_wallpaper_qs = DeviceWallpaper.objects.filter(id=wallpaper_id)
            device_wallpaper = device_wallpaper_qs.values("obj_prefix", "obj_name", "uid", "parent_id")
            uid = device_wallpaper[0]['uid']
            obj_name = device_wallpaper[0]['obj_name']

            # 使用中壁纸被删除
            use_device_wallpaper = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0).first()
            if use_device_wallpaper and use_device_wallpaper.parent_id == wallpaper_id:
                system_device_wallpaper = DeviceWallpaper.objects.filter(id=1).first()
                use_device_wallpaper.parent_id = 1
                use_device_wallpaper.storage_type = system_device_wallpaper.storage_type
                use_device_wallpaper.obj_name = system_device_wallpaper.obj_name
                use_device_wallpaper.obj_prefix = system_device_wallpaper.obj_prefix
                use_device_wallpaper.classification = system_device_wallpaper.classification
                use_device_wallpaper.channel = system_device_wallpaper.channel
                use_device_wallpaper.save()

            if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
                s3 = AmazonS3Util(
                    AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
                )
            else:
                s3 = AmazonS3Util(
                    AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
                )

            s3.delete_obj("ansjerfilemanager", f"app/static/device-wallpaper/{uid}/{obj_name}")
            device_wallpaper_qs.delete()

            return response.json(0)

        except Exception as e:
            LOGGER.info('删除壁纸异常:{}'.format(e))
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @classmethod
    def select_wallpaper(cls, request_dict, response):
        """
        用户选取壁纸
        @param request_dict:
        @param response:
        @return:
        """
        try:
            wallpaper_id = request_dict.get('wallpaperId', None)
            uid = request_dict.get('uid', None)
            if not all([wallpaper_id, uid]):
                return response.json(444)
            device_wallpaper = DeviceWallpaper.objects.filter(id=wallpaper_id).values("device_type", "storage_type",
                                                                                      "obj_prefix",
                                                                                      "obj_name",
                                                                                      "classification",
                                                                                      "channel").first()
            device_wallpaper_qs = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0)
            if device_wallpaper_qs.exists():
                device_wallpaper_qs.update(
                    storage_type=device_wallpaper["storage_type"],
                    classification=device_wallpaper["classification"],
                    obj_prefix=device_wallpaper["obj_prefix"],
                    obj_name=device_wallpaper["obj_name"],
                    parent_id=wallpaper_id
                )
            else:
                DeviceWallpaper.objects.create(
                    device_type=device_wallpaper["device_type"],
                    storage_type=device_wallpaper["storage_type"],
                    obj_name=device_wallpaper["obj_name"],
                    obj_prefix=device_wallpaper["obj_prefix"],
                    classification=device_wallpaper["classification"],
                    uid=uid,
                    channel=device_wallpaper["channel"],
                    status=1,
                    parent_id=wallpaper_id,
                    created_time=int(time.time())
                )
            return response.json(0)
        except Exception as e:
            LOGGER.error('用户选取壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return response.json(5)

    @staticmethod
    def delete_wallpaper(file_key):
        try:
            if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
                s3 = AmazonS3Util(
                    AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
                )
            else:
                s3 = AmazonS3Util(
                    AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
                )

            s3.delete_obj("ansjerfilemanager", file_key)
            return True
        except Exception as e:
            LOGGER.info('删除违规壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return False
