# Create your views here.
# 导入必要的模块
import datetime  # 处理日期时间
import itertools  # 提供迭代器相关功能
import json  # 处理JSON数据
import logging  # 日志记录
from datetime import timezone  # 时区处理
from itertools import groupby  # 用于对序列进行分组

import django  # Django框架核心
import requests  # 发送HTTP请求
from django.contrib.auth.decorators import login_required  # 登录验证装饰器
from django.http import HttpResponse  # HTTP响应
from django.http import JsonResponse  # JSON格式响应
from django.shortcuts import render  # 渲染模板
from django.views.decorators.csrf import csrf_exempt  # 禁用CSRF验证装饰器

from .models import OwnTrackLog  # 导入当前应用的模型

# 配置日志记录器
logger = logging.getLogger(__name__)


# 禁用CSRF验证的视图函数，用于处理OwnTracks的日志记录
@csrf_exempt
def manage_owntrack_log(request):
    try:
        # 从请求中读取并解析JSON数据
        s = json.loads(request.read().decode('utf-8'))
        # 提取必要的字段
        tid = s['tid']
        lat = s['lat']
        lon = s['lon']

        # 记录日志信息
        logger.info(
            'tid:{tid}.lat:{lat}.lon:{lon}'.format(
                tid=tid, lat=lat, lon=lon))
        # 验证字段是否存在
        if tid and lat and lon:
            # 创建并保存新的日志记录
            m = OwnTrackLog()
            m.tid = tid
            m.lat = lat
            m.lon = lon
            m.save()
            return HttpResponse('ok')  # 返回成功响应
        else:
            return HttpResponse('data error')  # 数据不完整错误响应
    except Exception as e:
        # 记录异常信息
        logger.error(e)
        return HttpResponse('error')  # 异常错误响应


# 需要登录才能访问的视图，用于显示地图
@login_required
def show_maps(request):
    # 仅允许超级用户访问
    if request.user.is_superuser:
        # 获取当前UTC日期作为默认日期
        defaultdate = str(datetime.datetime.now(timezone.utc).date())
        # 从请求参数中获取日期，默认为当前日期
        date = request.GET.get('date', defaultdate)
        # 准备上下文数据
        context = {
            'date': date
        }
        # 渲染模板并返回
        return render(request, 'owntracks/show_maps.html', context)
    else:
        # 非超级用户返回403禁止访问
        from django.http import HttpResponseForbidden
        return HttpResponseForbidden()


# 需要登录才能访问的视图，用于显示日志日期列表
@login_required
def show_log_dates(request):
    # 获取所有记录的创建时间
    dates = OwnTrackLog.objects.values_list('creation_time', flat=True)
    # 提取日期部分并去重排序
    results = list(sorted(set(map(lambda x: x.strftime('%Y-%m-%d'), dates))))

    # 准备上下文数据
    context = {
        'results': results
    }
    # 渲染模板并返回
    return render(request, 'owntracks/show_log_dates.html', context)


# 将GPS坐标转换为高德地图坐标的函数
def convert_to_amap(locations):
    convert_result = []
    # 创建迭代器
    it = iter(locations)

    # 每次处理30个坐标（高德API限制）
    item = list(itertools.islice(it, 30))
    while item:
        # 格式化坐标为"经度,纬度;经度,纬度"形式
        datas = ';'.join(
            set(map(lambda x: str(x.lon) + ',' + str(x.lat), item)))

        # 高德API密钥和接口地址
        key = '8440a376dfc9743d8924bf0ad141f28e'
        api = 'http://restapi.amap.com/v3/assistant/coordinate/convert'
        # 请求参数
        query = {
            'key': key,
            'locations': datas,
            'coordsys': 'gps'  # 源坐标系统为GPS
        }
        # 发送转换请求
        rsp = requests.get(url=api, params=query)
        result = json.loads(rsp.text)
        # 处理转换结果
        if "locations" in result:
            convert_result.append(result['locations'])
        # 处理下一批坐标
        item = list(itertools.islice(it, 30))

    # 合并所有转换结果并返回
    return ";".join(convert_result)


# 需要登录才能访问的视图，用于获取轨迹数据
@login_required
def get_datas(request):
    # 获取当前UTC时间
    now = django.utils.timezone.now().replace(tzinfo=timezone.utc)
    # 默认查询日期为今天
    querydate = django.utils.timezone.datetime(
        now.year, now.month, now.day, 0, 0, 0)
    # 如果请求中指定了日期，则使用指定日期
    if request.GET.get('date', None):
        date = list(map(lambda x: int(x), request.GET.get('date').split('-')))
        querydate = django.utils.timezone.datetime(
            date[0], date[1], date[2], 0, 0, 0)
    # 计算查询日期的下一天（用于范围查询）
    nextdate = querydate + datetime.timedelta(days=1)
    # 查询指定日期范围内的所有记录
    models = OwnTrackLog.objects.filter(
        creation_time__range=(querydate, nextdate))
    result = list()
    # 如果有查询结果
    if models and len(models):
        # 按tid分组处理记录
        for tid, item in groupby(
                sorted(models, key=lambda k: k.tid), key=lambda k: k.tid):

            # 构建返回数据结构
            d = dict()
            d["name"] = tid
            paths = list()
            # 注释掉的代码：使用高德转换后的经纬度
            # locations = convert_to_amap(
            #     sorted(item, key=lambda x: x.creation_time))
            # for i in locations.split(';'):
            #     paths.append(i.split(','))

            # 使用GPS原始经纬度
            # 按创建时间排序并添加到路径列表
            for location in sorted(item, key=lambda x: x.creation_time):
                paths.append([str(location.lon), str(location.lat)])
            d["path"] = paths
            result.append(d)
    # 返回JSON格式的结果
    return JsonResponse(result, safe=False)