from rest_framework.views import APIView
from rest_framework.response import Response
from django.conf import settings
from django.core.paginator import Paginator
import time
import json
import logging
from smartfarming.utils import get_addr_by_lag_lng
from smartfarming.serializers.device_serializers import DeviceSerializers
from smartfarming.models.device import MongoDevice, MongoCBDData, MongoSCDData, MongoXYCBData
from smartfarming.models.weather import MongoQXZ_Base_Info, MongoQXZ_Info_Record, MongoQXZ_Conf
from django.db.models import Q

from smartfarming.qxz import data_deal


logger = logging.getLogger("myapp")
device_type_en = (settings.CONFIG).get("device_type_en")
device_type_zh = (settings.CONFIG).get("device_type_zh")


class CbdScdXyDeviceSaveAPIView(APIView):
    permission_classes = []
    authentication_classes = []

    def post(self, request):
        # 测报灯设备及数据入库
        data = request.data 
        topic = data.get("topic")
        payload = data.get("payload")
        cmd = payload.get("cmd")
        topic_msg = topic.split("/")
        now = int(time.time())
        if topic_msg and len(topic_msg) == 5 and cmd:
            device_id = topic_msg[-1]
            try:
                device_type = topic_msg[2]
                device_type_id = device_type_en.get(device_type)
                if device_type_id == 2:
                    model = MongoSCDData
                elif device_type_id == 3:
                    model = MongoCBDData
                elif device_type_id == 8:
                    model = MongoXYCBData
                # 在设备信息表中查找是否有数据,如果没有数据则增加
                device_name = device_type_zh.get(device_type_id)
                device, is_created = MongoDevice.objects.get_or_create(
                    device_id = device_id,
                    defaults={
                        "device_id": device_id,
                        "device_type_id": device_type_id,
                        "device_name": device_name,
                        "addtime": now
                    }
                )
                if is_created:
                    logger.info(f"{device_type} 设备 {device_id} 入库成功")
                # 获取数据并更新设备
                if cmd == "data":
                    ext = payload.get("ext")
                    if ext:
                        # 增加设备数据
                        model.objects.create(
                            device_id = device_id,
                            device_data = str(ext),
                            addtime = now
                        )
                        lng = ext.get("lng")
                        lat = ext.get("lat")
                        dver_num = ext.get("dver")
                        device.device_status = 1
                        device.uptime = now
                        if dver_num:
                            device.dver_num = dver_num
                        if lng and lat and dver_num:
                            device.lng = lng
                            device.lat = lat
                            # 根据经纬度获取省市级
                            is_success, province, city, district = get_addr_by_lag_lng(lat, lng)
                            if is_success:
                                # 更新地理位置坐标
                                device.province = province
                                device.city = city
                                device.district = district
                            device.save()
                elif cmd == "offline":
                    ext = data.get("ext")
                    if ext:
                        # 增加设备数据
                        model.objects.create(
                            device_id=device_id,
                            device_data = str(ext),
                            addtime=now
                        )
                        # 更新设备状态
                        device = MongoDevice.objects.filter(device_id=device_id).first()
                        device.device_status = 0
                        device.save()
                return Response({"code": 0, "msg": "success"})
            except Exception as e:
                logger.error(f"测报灯设备 {device_id} 处理上报数据或增加设备失败，错误原因：{e.args}")
                return Response({"code": 2, "msg": f"处理测报灯上报数据失败 {device_id}"}) 
        else:
            return Response({"code": 2, "msg": "请核对数据结构"}) 
        
class QxzDeviceAddAPIViw(APIView):

    def post(self, request):
        # 气象站上传数据
        request_data = request.data 
        device_id = request_data.get("StationID")
        uptime = request_data.get("MonitorTime")
        data = request_data.get("data")
        if data:
            # 30分钟上报一次的数据
            conf_data = data_deal(data)
            qxz_data = MongoQXZ_Conf()
            qxz_data.device_id = 2
            qxz_data.e1 = data[1]
            qxz_data.e2 = data[2]
            qxz_data.e3 = data[3]
            qxz_data.e4 = data[4]
            qxz_data.e5 = data[5]
            qxz_data.e6 = data[6]
            qxz_data.e7 = data[7]
            qxz_data.e8 = data[8]
            qxz_data.e9 = data[9]
            qxz_data.e10 = data[10]
            qxz_data.e11 = data[11]
            qxz_data.e12 = data[12]
            qxz_data.e13 = data[13]
            qxz_data.e14 = data[14]
            qxz_data.e15 = data[15]
            qxz_data.e16 = data[16]
            qxz_data.e17 = data[17]
            qxz_data.e18 = data[18]
            qxz_data.e19 = data[19]
            qxz_data.e20 = data[20]
            qxz_data.e21 = data[21]
            qxz_data.e22 = data[22]
            qxz_data.e23 = data[23]
            qxz_data.e24 = data[24]
            qxz_data.e25 = data[25]
            qxz_data.e26 = data[26]
            qxz_data.e27 = data[27]
            qxz_data.e28 = data[28]
            qxz_data.e29 = data[29]
            qxz_data.e30 = data[30]



class DeviceListAPIView(APIView):

    def post(self, request):
        # 设备列表
        request_data = request.data
        device_id = request_data.get("device_id")
        device_status = request_data.get("device_status")
        search = request_data.get("search")
        page_num = int(request_data.get("pagenum")) if request_data.get("pagenum") else 1
        page_size = int(request_data.get("pagesize")) if request_data.get("pagesize") else 10
        if device_id:
            queryset = MongoDevice.objects.filter(device_id=device_id).order_by("-uptime")
        elif device_status:
            queryset = MongoDevice.objects.filter(device_status=device_status).order_by("-uptime")
        elif search:
            queryset = MongoDevice.objects.filter(Q(device_name__icontains=search) | Q(device_id__icontains=search))
        else:
            queryset = MongoDevice.objects.all().order_by("-uptime")
        total_obj = queryset.count()
        paginator = Paginator(queryset, page_size)
        page_obj = paginator.get_page(page_num)
        serializers = DeviceSerializers(page_obj, many=True)
        return Response({"code": 0, "msg": "success", "data": serializers.data, "count": total_obj}) 


class DeviceChangeAPIView(APIView):

    def post(self, request):
        # 修改设备信息
        request_data = request.data 
        device_name = request_data.get("device_name")
        device_id = request_data.get("device_id")
        lng = request_data.get("lng")
        lat = request_data.get("lat")
        device = MongoDevice.objects.get(device_id=device_id)
        if device_name:
            device.device_name = device_name
        if lng and lat:
            device.lng = lng
            device.lat = lat 
            is_success, province, city, district = get_addr_by_lag_lng(lat, lng)
            if is_success:
                # 更新地理位置坐标
                device.province = province
                device.city = city
                device.district = district
        device.save()
        return Response({"code": 0, "msg": "success"})


