from django.core.paginator import Paginator
import time
import datetime
from operator import itemgetter
from django.db.models import Q, Sum, Count
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from smartfarming.models.ascend import MongoBase, MongoLandInfo, MongoPlantInfo, MongoAreaJob, LandPlanInfo, CountryModel, PlanWeekend
from smartfarming.models.user import DeviceUser
from smartfarming.models.device import MongoDevice
from smartfarming.models.worm_forecast import MongoCBDphoto
from smartfarming.models.pest_count import MongoCBDPestWarning
from smartfarming.models.weather import MongoQXZ_Alarm_Log_New
from smartfarming.serializers.ascend_serializers import LandPlanInfoSerializers
from smartfarming.utils import get_recent_month, get_weather
from smartfarming.api.views.forecast.all_dict import insect_dict
from smartfarming.models.device import MongoDevice


class LandPlanInfoAPIView(APIView):

    def post(self, request):
        # 种植采收列表及统计信息
        request_data = request.data 
        plan = request_data.get("plan")
        year = request_data.get("year")
        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
        start_timestamp, end_timestatmp = 0, 0
        if year:
            start_timestamp = datetime.datetime(int(year), 1,1,0,0).timestamp()
            end_timestatmp = datetime.datetime(int(year), 12,31,23,59).timestamp()
        plan_ids_head = []
        if plan :
            plan_ids_head = MongoPlantInfo.objects.filter(plantname__icontains=plan).values_list("id", flat=True)
        if plan_ids_head and year:
            queryset = LandPlanInfo.objects.filter(Q(plan_id__in = plan_ids_head) & Q(addtime__gte=start_timestamp, addtime__lte=end_timestatmp)).exclude(recovery_time=0).filter(is_delete=1).order_by("-addtime")
        elif year:
            queryset = LandPlanInfo.objects.filter(addtime__gte=start_timestamp, addtime__lte=end_timestatmp).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
        elif plan_ids_head:
            queryset = LandPlanInfo.objects.filter(plan_id__in = plan_ids_head).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
        else:
            queryset = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
        total_obj = queryset.count()
        paginator = Paginator(queryset, page_size)
        page_obj = paginator.get_page(page_num)
        serializers = LandPlanInfoSerializers(page_obj, many=True)
        # 折线图
        year_value = LandPlanInfo.objects.all().exclude(recovery_time=0).values_list("addtime", flat=True).order_by("-addtime")
        years = []
        for year in year_value:
            y = datetime.datetime.fromtimestamp(year).year
            if y not in years:
                years.append(y)
        years.reverse()
        # 获取最近5年的作物ID
        end = datetime.datetime(int(years[-1]) -5, 12,31,23,59).timestamp()
        start = datetime.datetime(int(years[-1]), 12,31,23,59).timestamp()
        plan_ids = LandPlanInfo.objects.filter(addtime__gte=end, addtime__lte=start).exclude(recovery_time=0).distinct().values_list("plan_id", flat=True).order_by("plan_id")
        counts = []
        # 组织具体数据
        for i in years:
            start_timestamp = datetime.datetime(i, 1,1,0,0).timestamp()
            end_timestatmp = datetime.datetime(i, 12,31,23,59).timestamp()
            plan_totals = LandPlanInfo.objects.filter(
                addtime__gte=start_timestamp, 
                addtime__lte=end_timestatmp).exclude(recovery_time=0).values("plan_id").annotate(total=Sum("recovery_kg")).order_by("plan_id").values_list("plan_id", "total")
            inners = {}
            for k in plan_totals:
                inners[str(k[0])] = k[1]
            pid =[]
            for j in plan_ids:
                pid.append(inners.get(str(j), 0))
            counts.append(pid)
        transpose_matrix = [[row[i] for row in counts] for i in range(len(counts[0]))]
        plannames = []
        # 组织农作物
        for p in plan_ids:
            plan_obj = MongoPlantInfo.objects.filter(id=p)
            if plan_obj:
                planname = plan_obj.first().plantname +"-"+ plan_obj.first().planttype
            else:
                planname = ""
            plannames.append(planname)
        return Response({
            "code": 0, 
            "msg": "success", 
            "data": serializers.data, 
            "count": total_obj, 
            "charts": {
                "years": years,
                "data": transpose_matrix,
                "plan": plannames
            }
        })


class PlanNameAPIView(APIView):

    def post(self, request):
        try:
            # 作物名字
            plan_ids = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).values_list("plan_id", flat=True).order_by("-addtime")
            plans = MongoPlantInfo.objects.filter(is_delete=1, id__in=plan_ids).values_list("plantname", flat=True).distinct()
            return Response({"code": 0, "msg": "success", "data": plans})
        except Exception as e:
            return Response({"code": 0, "msg": "success", "data": []})
        

class PlanAreaAPIView(APIView):

    def post(self, request):
        # 种植面积与作物个数统计
        land_plan_ids = LandPlanInfo.objects.filter(status="采收").filter(recovery_kg=0).values("land_id", "plan_id")
        plan_land = []
        plans = []
        plan_area = 0
        for i in land_plan_ids:
            landarea = MongoLandInfo.objects.get(id=i.get("land_id")).landarea
            plant = MongoPlantInfo.objects.get(id=i.get("plan_id"))
            plantname = f"{plant.plantname}({plant.planttype})"
            plan_land.append(
                {
                    "name": plantname,
                    "value": round(float(landarea), 2)
                }
            )
            plans.append(plantname) if plantname not in plans else None 
            plan_area += round(float(landarea), 2)
        return Response({"code": 0, "msg": "success", "data": {"lands_area": round(plan_area, 2), "plans_count": len(plans), "p_list": plan_land}})
    

class DeviceCountAPIView(APIView):

    def post(self, request):
        # 统计设备在线或离线统计
        device_status = MongoDevice.objects.values("device_status").annotate(total=Count("id"))
        online = 0
        offline = 0
        for k in device_status:
            if k.get("device_status") == 1:
                online = k.get("total")
            if k.get("device_status") == 0:
                offline = k.get("total")

        # 设备分类 
        device_type = MongoDevice.objects.values("device_type_id").annotate(total=Count("id"))
        config_dict = settings.CONFIG.get("device_type_zh")
        device_type = {config_dict.get(str(result["device_type_id"])): result["total"] for result in device_type}
        return Response({
            "code": 0, 
            "msg": "success", 
            "data": {
                "device_status": {"online": online, "offline": offline},
                "device_category": device_type
                }
            })


class RecentPestCountAPIView(APIView):

    def post(self, request):
        # 统计最近一个月的害虫排名
        start = get_recent_month(1)
        data = MongoCBDphoto.objects.filter(uptime__gte=start).values_list("indentify_result", flat=True)
        try:
            pest_count = {}
            for i in data:
                tp_lst = i.split("#")
                for k in tp_lst:
                    pest = k.split(",")
                    p_0 = pest[0]
                    p_1 = pest[1]
                    p_name = insect_dict.get(p_0)
                    if p_name not in pest_count.keys():
                        pest_count[p_name] = int(p_1)
                    else:
                        pest_count[p_name] += int(p_1)
            result = sorted(pest_count.items(), key=itemgetter(1), reverse=False)
            result = {m[0]:m[1] for m in result[-10:]}
            return Response({"code": 0, "msg": "success", "data": result})
        except Exception as e:
            return Response({"code": 2, "msg": "数据有误,请核查"})


# 网站顶部滚动预警信息
class AlermNewsAPIView(APIView):

    def post(self, request):
        try:
            myuser = request.myuser
            try:
                ip = request.META['HTTP_X_FORWARDED_FOR']
            except Exception as e:
                ip = request.META['REMOTE_ADDR']
            # 获取天气预警
            weather_data = get_weather(ip)
            weather = []
            for i in weather_data:
                alarm = i.get("alarm")
                if alarm:
                    for k in alarm:
                        weather.append(k.get("alarm_content"))
            # 获取虫睛预警
            user_id = str(myuser.id)
            pest_query = MongoCBDPestWarning.objects.all().order_by("-id")[:3]
            pest = []
            for p in pest_query:
                content = p.warning_content
                pest.append(content.replace("【云飞科技】尊敬的用户:", "").replace(",(详情请登陆http://hnyfwlw.com查看)", "").replace(",请注意防范(详情请登陆http://hnyfwlw.com查看)", ""))
            # 气象预警
            qx_query = MongoQXZ_Alarm_Log_New.objects.filter(user_id=user_id).order_by('-id')[:3]
            qx = []
            for q in qx_query:
                qx.append(q.warning_content)
            data = []
            if weather:
                for i in weather:
                    data.append(i)
            if pest:
                for i in pest:
                    data.append(i)
            if qx:
                for i in qx:
                    data.append(i)
            return Response({"code": 0,"msg":"success", "data": data})
        except Exception as e:
            print(e)
            return Response({"code": 2, "msg": "获取数据失败"})
        

class QxzCameraList(APIView):
    permission_classes = []
    authentication_classes = []
    def post(self, request):
        # 气象与监控绑定列表
        qxz_ids = MongoDevice.objects.filter(device_type_id__in = [5, 8]).values("device_id")
        cam_ids = MongoDevice.objects.filter(device_type_id = 6).values_list("device_id", flat=True)
        return Response({"code": 0,"msg":"success", "data": {"qxz_ids": qxz_ids, "cam_ids": cam_ids}})
    

class QxzCameraUpdate(APIView):
    permission_classes = []
    authentication_classes = []
    def post(self, request):
        # 气象与监控更新
        request_data = request.data 
        try:
            qx_id = request_data.get("qx_id")
            ca_id = request_data.get("ca_id")
            qx_lng_lat = MongoDevice.objects.filter(device_id=qx_id).values_list("lng", "lat")
            ca_obj = MongoDevice.objects.get(device_id=ca_id)
            if qx_lng_lat:
                ca_obj.lng = float(qx_lng_lat[0][0]) + 0.00004
                ca_obj.lat = float(qx_lng_lat[0][1]) + 0.00004
                ca_obj.save()
            return Response({"code": 0,"msg":"success"})
        except Exception as e:
            return Response({"code": 2,"msg":"失败"})