import os
import json
import time 
import shutil
import requests
import zipstream
import uuid
from datetime import datetime
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http import HttpResponse, JsonResponse, StreamingHttpResponse
from django.views.generic.base import View
from kedong.settings import MEDIA_ROOT
from django.conf import settings

from smartfarming.models.worm_forecast import MongoCBDphoto
JsonResponse = lambda x: HttpResponse(json.dumps(x, indent=True),content_type="application/json")


config = settings.CONFIG
server_web = config.get("server_web")


def down_image(image_name,url):
    content = requests.get(url).content
    with open("%s"%image_name,"wb") as f:
        f.write(content)
    return image_name


class ZipUtilities(object):
    """
    将文件或者文件夹打包成ZIP格式的文件,然后下载,在后台可以通过response完成下载
    """
    zip_file = None

    def __init__(self):
        self.zip_file = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED)

    def to_zip(self, file, name):
        if os.path.isfile(file):
            self.zip_file.write(file, arcname=os.path.basename(file))
        else:
            self.add_folder_to_zip(file, name)

    def add_folder_to_zip(self, folder, name):
        for file in os.listdir(folder):
            full_path = os.path.join(folder, file)
            if os.path.isfile(full_path):
                self.zip_file.write(
                    full_path,arcname=os.path.join(name, os.path.basename(full_path)))
            elif os.path.isdir(full_path):
                self.add_folder_to_zip(
                    full_path,os.path.join(name, os.path.basename(full_path)))

    def close(self):
        if self.zip_file:
            self.zip_file.close()


class FileUploadView(APIView):
    # 上传图片
    def post(self, request):
        path = request.data.get("model", "others")
        local_path = os.path.join(MEDIA_ROOT, path)
        os.mkdir(local_path) if not os.path.exists(local_path) else None 
        file_obj = request.data['file']
        if file_obj.size > 1024 * 1024 * 200:
            return Response({"code": 2, "msg": "请上传小于200M文件"})
        try:
            stamp = int(datetime.now().timestamp())
            unique_id = uuid.uuid4()
            combined_id = str(stamp) + "-" + str(unique_id)
            file_name = combined_id + "." + ((file_obj.name).split("."))[-1]
            with open(f"{local_path}/{file_name}", 'wb') as f:
                for chunk in file_obj.chunks():
                    f.write(chunk)
            return Response({"url": f'{server_web}/media/{path}/{file_name}', "code": 0, "msg": "success"})
        except Exception as e:
            return Response({"code": 2, "msg": "图片保存失败，请检查或重试"})


class ImaggeDownloadView(View):
    """
    测报灯图片下载
    """
    def post(self, request):
        img_id = request.POST.get("img_id")
        device_type = request.POST.get("device_type")
        if not img_id:
            return JsonResponse({"msg":"参数缺失","code":"10004"})
        img_id_list = img_id.split(",")
        if device_type == "5":
            models = MongoCBDphoto
        else:
            return JsonResponse({"msg":"参数超出范围","code":"10001"})
        path = config.get("img_download")
        os.mkdir(path) if not os.path.exists(path) else None 
        # 先删除,然后在保存
        try:
            shutil.rmtree(path)
        except :
            pass
        cbd_img_query = models.objects.filter(id__in=img_id_list)  
        if not cbd_img_query:
            return JsonResponse({"msg":"未找到图片","code":"10003"})  
        for x in cbd_img_query:
            img_name  = x.addr.split("/")[-1]
            if not os.path.exists(path):
                os.makedirs(path)
            now_time = str(int(time.time()))
            paths =   path + "/"  + now_time+"_"+img_name
            down_image(paths, server_web + x.addr)
        utilities = ZipUtilities()
        folder_name = "img"
        utilities.add_folder_to_zip(path, folder_name)
        try:
            response = StreamingHttpResponse(utilities.zip_file)
            response['Content-Type'] = 'application/octet-stream'
            response['Content-Disposition'] = 'attachment;filename="{0}"'.format(folder_name)
        except Exception as e:
            return JsonResponse({"msg":"下载失败","error":e,"code":"10002"})
        return response
    
    