import base64
import os
from datetime import time

import cv2
from django.core.files.storage import FileSystemStorage
from django.shortcuts import render, get_object_or_404

from app01.models import UserInfo
from multi_model_detection.models import OperationRecord
from multi_model_detection.views import models, MODEL_PATHS
from .models import DiseaseWiki

def disease_wiki_list(request):

    query = request.GET.get('search', '')

    wikis = DiseaseWiki.objects.exclude(category='SHAPE').order_by('-create_time')
    if query:
        wikis = wikis.filter(name__icontains=query)
    return render(request, 'encyclopedia/wiki_list.html', {
        'wikis': wikis,
        'title': '茄子病虫害百科',
        'query': query
    })

def shape_wiki_list(request):

    query = request.GET.get('search', '')

    wikis = DiseaseWiki.objects.filter(category='SHAPE').order_by('-create_time')
    if query:
        wikis = wikis.filter(name__icontains=query)
    return render(request, 'encyclopedia/wiki_list.html', {
        'wikis': wikis,
        'title': '茄子品相分级百科',
        'query': query
    })

def wiki_detail(request, wiki_id):
    wiki = get_object_or_404(DiseaseWiki, id=wiki_id)
    return render(request, 'encyclopedia/wiki_detail.html', {'wiki': wiki})


from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import DiseaseWiki


@csrf_exempt
def api_miniapp_wiki_list(request):
    """小程序专属：获取百科列表接口"""
    if request.method == "GET" or request.method == "POST":
        try:
            # 获取所有百科数据，按创建时间倒序
            wikis = DiseaseWiki.objects.all().order_by('-create_time')
            data_list = []

            for w in wikis:
                # 拼接完整的图片 URL
                image_url = ""
                if w.wiki_image:
                    image_url = request.build_absolute_uri(w.wiki_image.url)

                data_list.append({
                    "id": w.id,
                    "name": w.name,
                    # get_category_display() 会把 'PEST' 自动转换成 '虫害百科'
                    "category": w.get_category_display(),
                    "symptoms": w.symptoms,
                    "treatment": w.treatment,
                    "image_url": image_url
                })

            return JsonResponse({"code": 200, "msg": "获取成功", "data": data_list})

        except Exception as e:
            import traceback
            traceback.print_exc()
            return JsonResponse({"code": 500, "msg": f"获取百科失败: {str(e)}"})

    return JsonResponse({"code": 405, "msg": "请求方法错误"})

# === 以下为小程序专属接口 ===

@csrf_exempt
def api_miniapp_get_models(request):
    """小程序获取可用模型列表"""
    if request.method == "GET":
        # 返回 MODEL_PATHS 中配置的所有模型名称
        model_names = list(MODEL_PATHS.keys())
        return JsonResponse({'code': 200, 'data': model_names})
    return JsonResponse({'code': 405, 'msg': '仅支持 GET'})

@csrf_exempt
def api_miniapp_multi_detect(request):
    """小程序提交图片及勾选的模型进行联合检测"""
    if request.method == "POST":
        try:
            image_file = request.FILES.get('image')
            user_id = request.POST.get('user_id')
            # 接收前端用逗号分隔的模型名称字符串，例如 "YOLO11-1,YOLOv8"
            models_param = request.POST.get('models', '')
            selected_models = [m for m in models_param.split(',') if m]

            if not image_file or not selected_models:
                return JsonResponse({'code': 400, 'msg': '请上传图片并至少选择一个模型'})

            fs = FileSystemStorage()
            filename = fs.save(f"uploads/miniapp_{image_file.name}", image_file)
            image_path = fs.path(filename)
            image = cv2.imread(image_path)

            results = []
            start_time = time.time()

            # 遍历选中的模型进行推理
            for model_name in selected_models:
                result_data = {'model': model_name}
                if model_name in models:
                    try:
                        res = models[model_name].predict(image)
                        if res and len(res[0].boxes) > 0:
                            annotated_image = res[0].plot()
                            _, buffer = cv2.imencode('.jpg', annotated_image)
                            # 拼接好 base64 前缀直接发给前端
                            result_data['image_base64'] = "data:image/jpeg;base64," + base64.b64encode(buffer).decode('utf-8')
                            result_data['count'] = len(res[0].boxes)
                        else:
                            result_data['error'] = "未检测到明显目标"
                    except Exception as e:
                        result_data['error'] = f"检测异常: {str(e)}"
                else:
                    result_data['error'] = "模型未找到"
                results.append(result_data)

            duration = round(time.time() - start_time, 3)

            # 记录到多模型专属的 OperationRecord
            if user_id:
                user_info = UserInfo.objects.filter(id=user_id).first()
                if user_info:
                    OperationRecord.objects.create(
                        user=user_info,
                        operation_type="IMAGE",
                        description=f"小程序多模型联合检测 ({','.join(selected_models)})。耗时: {duration}s",
                        result_path=filename
                    )

            os.remove(image_path)  # 推理完删除本地原图节省空间

            return JsonResponse({
                'code': 200,
                'msg': '多路并行检测完成',
                'data': {
                    'results': results,
                    'inference_time': duration,
                    'total_count': sum([r.get('count', 0) for r in results])
                }
            })

        except Exception as e:
            import traceback
            traceback.print_exc()
            return JsonResponse({'code': 500, 'msg': f'服务器错误: {str(e)}'})

    return JsonResponse({'code': 405, 'msg': '仅支持 POST'})