package com.njzscloud.supervisory.gps.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.njzscloud.common.core.utils.R;
import com.njzscloud.supervisory.config.JikeProperties;
import com.njzscloud.supervisory.gps.jike.JikeApiClient;
import com.njzscloud.supervisory.gps.jike.JikeResponse;
import com.njzscloud.supervisory.gps.jike.result.JikeEventResult;
import com.njzscloud.supervisory.gps.jike.result.JikeMediaResult;
import com.njzscloud.supervisory.gps.jike.result.JikeTrackResult;
import com.njzscloud.supervisory.gps.tuqiang.jimi.DeviceLocationGetParam;
import com.njzscloud.supervisory.gps.tuqiang.jimi.DeviceLocationGetResult;
import com.njzscloud.supervisory.gps.tuqiang.jimi.DeviceTrackListParam;
import com.njzscloud.supervisory.gps.tuqiang.jimi.DeviceTrackListResult;
import com.njzscloud.supervisory.gps.tuqiang.jimi.util.JimiUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * GPS
 */
@Slf4j
@RestController
@RequestMapping("/gps")
public class GPSController {

    @Autowired
    private JikeProperties jikeProperties;

    /**
     * 实时定位
     */
    @RequestMapping("/obtain_location")
    public R<?> obtainLocation(DeviceLocationGetParam param) {
        DeviceLocationGetResult result = JimiUtil.request(param);
        if (result.isSucc()) {
            return R.success(result.getResult());
        }
        return R.failed();
    }

    /**
     * 轨迹查询（图强）
     */
    @RequestMapping("/track_list")
    public R<?> trackList(DeviceTrackListParam param) {
        DeviceTrackListResult result = JimiUtil.request(param);
        if (result.isSucc()) {
            return R.success(result.getResult());
        }
        return R.failed();
    }

    /**
     * 历史轨迹查询（即刻物联）
     *
     * @param imei  设备号
     * @param stime 开始时间(格式: yyyy-MM-dd HH:mm:ss)
     * @param etime 结束时间(格式: yyyy-MM-dd HH:mm:ss)
     * @return 返回前端期望的格式 {latitude, longitude, direction}
     */
    @RequestMapping("/jike_track_list")
    public R<?> jikeTrackList(@RequestParam String imei,
                              @RequestParam String stime,
                              @RequestParam String etime) {
        try {
            JikeApiClient client = new JikeApiClient(jikeProperties);

            Map<String, String> params = new HashMap<>();
            params.put("imei", imei);
            params.put("stime", String.valueOf(DateUtil.parse(stime).getTime()));
            params.put("etime", String.valueOf(DateUtil.parse(etime).getTime()));

            log.info("即刻物联轨迹查询请求: {}", params);

            String response = client.doGet("/open-api/gps-trace/list", params);
            log.info("即刻物联轨迹查询响应: {}", response);

            JikeResponse<List<JikeTrackResult>> result = com.alibaba.fastjson2.JSON.parseObject(
                    response,
                    new com.alibaba.fastjson2.TypeReference<JikeResponse<List<JikeTrackResult>>>() {
                    }
            );

            if (result.isSuccess()) {
                List<TrackPoint> trackPoints = convertToTrackPoints(result.getData());
                return R.success(trackPoints);
            } else {
                log.error("即刻物联轨迹查询失败: " + result.getHeader().getMessage());
                return R.failed();
            }
        } catch (Exception e) {
            log.error("即刻物联轨迹查询异常", e);
            return R.failed();
        }
    }

    /**
     * 将即刻轨迹转换为前端期望的格式
     */
    private List<TrackPoint> convertToTrackPoints(List<JikeTrackResult> jikeResults) {
        if (jikeResults == null || jikeResults.isEmpty()) {
            return Collections.emptyList();
        }
        return jikeResults.stream().map(track -> {
            TrackPoint point = new TrackPoint();
            // gpsText 格式: "lng,lat"
            String gpsText = track.getGpsText();
            if (gpsText != null && gpsText.contains(",")) {
                String[] parts = gpsText.split(",");
                try {
                    point.setLongitude(Double.parseDouble(parts[0]));
                    if (parts.length > 1) {
                        point.setLatitude(Double.parseDouble(parts[1]));
                    }
                } catch (NumberFormatException e) {
                    log.warn("GPS坐标解析失败: {}", gpsText);
                }
            }
            point.setDirection(track.getDirection() != null ? track.getDirection() : 0);
            return point;
        }).collect(Collectors.toList());
    }

    /**
     * 轨迹点
     */
    @Data
    public static class TrackPoint {
        private Double latitude;
        private Double longitude;
        private Integer direction;
    }

    /**
     * 历史报警事件查询（即刻物联）
     * @param imei 设备号
     * @param stime 开始时间(格式: yyyy-MM-dd HH:mm:ss)
     * @param etime 结束时间(格式: yyyy-MM-dd HH:mm:ss)
     */
    @RequestMapping("/event_list")
    public R<?> eventList(@RequestParam String imei,
                          @RequestParam String stime,
                          @RequestParam String etime) {
        try {
            JikeApiClient client = new JikeApiClient(jikeProperties);

            Map<String, String> params = new HashMap<>();
            params.put("imei", imei);
            params.put("eventTypeList", "25840,58648");
            params.put("stime", String.valueOf(DateUtil.parse(stime).getTime()));
            params.put("etime", String.valueOf(DateUtil.parse(etime).getTime()));

            String response = client.doGet("/open-api/v2/event/list", params);
            log.info("即刻物联历史报警事件查询响应: {}", response);

            JikeResponse<List<JikeEventResult>> result = JSON.parseObject(
                    response,
                    new TypeReference<JikeResponse<List<JikeEventResult>>>() {}
            );

            if (result.isSuccess()) {
                List<MediaItem> mediaItems = extractMediaList(result.getData());
                return R.success(mediaItems);
            } else {
                log.error("即刻物联历史报警事件查询失败: " + result.getHeader().getMessage());
                return R.failed();
            }
        } catch (Exception e) {
            log.error("即刻物联历史报警事件查询异常", e);
            return R.failed();
        }
    }

    /**
     * 从报警事件中提取所有mediaList并转换mediaType为中文
     */
    private List<MediaItem> extractMediaList(List<JikeEventResult> events) {
        if (events == null || events.isEmpty()) {
            return Collections.emptyList();
        }
        List<MediaItem> allMedia = new ArrayList<>();
        for (JikeEventResult event : events) {
            if (event.getMediaList() != null) {
                for (JikeMediaResult media : event.getMediaList()) {
                    MediaItem item = new MediaItem();
                    item.setId(media.getId());
                    item.setChannel(media.getChannel());
                    item.setMedia(media.getMedia());
                    item.setMediaType(media.getMediaType());
                    item.setMediaTypeText(getMediaTypeText(media.getMediaType()));
                    allMedia.add(item);
                }
            }
        }
        return allMedia;
    }

    /**
     * 获取媒体类型中文说明
     * mediaType: -1未知，0图片，1音频，2视频，3文本，4其它
     */
    private String getMediaTypeText(Integer mediaType) {
        if (mediaType == null) {
            return "未知";
        }
        switch (mediaType) {
            case -1: return "未知";
            case 0: return "图片";
            case 1: return "音频";
            case 2: return "视频";
            case 3: return "文本";
            case 4: return "其它";
            default: return "未知";
        }
    }

    /**
     * 媒体项
     */
    @Data
    public static class MediaItem {
        private Long id;
        private Integer channel;
        private String media;
        private Integer mediaType;
        private String mediaTypeText;
    }
}
