package com.gxwebsoft.hjm.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;

import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.DictData;
import com.gxwebsoft.common.system.param.DictDataParam;
import com.gxwebsoft.common.system.service.DictDataService;
import com.gxwebsoft.hjm.service.HjmCarService;
import com.gxwebsoft.hjm.entity.HjmCar;
import com.gxwebsoft.hjm.param.HjmCarParam;
import com.gxwebsoft.hjm.param.HjmCarImportParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.hjm.service.GpsDiagnosticService;
import com.gxwebsoft.hjm.service.HjmFenceService;
import com.gxwebsoft.hjm.service.HjmGpsLogService;
import com.gxwebsoft.hjm.service.MqttService;
import com.gxwebsoft.hjm.service.impl.HjmCarServiceImpl;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;


/**
 * 黄家明_车辆管理控制器
 *
 * @author 科技小王子
 * @since 2025-04-14 16:43:26
 */
@Tag(name = "黄家明_车辆管理管理")
@RestController
@RequestMapping("/api/hjm/hjm-car")
public class HjmCarController extends BaseController {
  private static final Logger logger = LoggerFactory.getLogger(PushCallback.class);
  @Resource
  private HjmCarService hjmCarService;
  @Resource
  private HjmFenceService hjmFenceService;
  @Resource
  private DictDataService dictDataService;
  @Resource
  private HjmGpsLogService hjmGpsLogService;
  @Resource
  private HjmCarServiceImpl hjmCarServiceImpl;
  @Resource
  private MqttService mqttService;
  @Resource
  private GpsDiagnosticService gpsDiagnosticService;

  @Operation(summary = "分页查询黄家明_车辆管理")
  @GetMapping("/page")
  public ApiResult<PageResult<HjmCar>> page(HjmCarParam param) {
    return success(hjmCarService.pageRel(param));
  }

  @Operation(summary = "查询全部黄家明_车辆管理")
  @GetMapping()
  public ApiResult<List<HjmCar>> list(HjmCarParam param) {
    // 使用关联查询
    return success(hjmCarService.listRel(param));
  }

  @Operation(summary = "根据id查询黄家明_车辆管理")
  @GetMapping("/{id}")
  public ApiResult<HjmCar> get(@PathVariable("id") Integer id) {
    // 使用关联查询
    return success(hjmCarService.getByIdRel(id));
  }

  @Operation(summary = "根据code查询车辆")
  @GetMapping("/getByCode/{code}")
  public ApiResult<HjmCar> getByCode(@PathVariable("code") String code) {
    return success(hjmCarService.getByCode(code));
  }

  @PreAuthorize("hasAuthority('hjm:hjmCar:save')")
  @OperationLog
  @Operation(summary = "添加黄家明_车辆管理")
  @PostMapping()
  public ApiResult<?> save(@RequestBody HjmCar hjmCar) {
    // 记录当前登录用户id
    User loginUser = getLoginUser();
    if (loginUser != null) {
      hjmCar.setUserId(loginUser.getUserId());
    }
    if (hjmCarService.save(hjmCar)) {
      // 重新生成编号
      hjmCar.setCode(hjmCar.getCode().concat(hjmCar.getId().toString()));
      hjmCarService.updateById(hjmCar);
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @Operation(summary = "修改黄家明_车辆管理")
  @PutMapping()
  public ApiResult<?> update(@RequestBody HjmCar hjmCar) {
    // 记录当前登录用户id
    User loginUser = getLoginUser();
    if (loginUser != null) {
      // 判断GPS设备是否被绑定
      final HjmCar byGpsNo = hjmCarService.getByGpsNo(hjmCar.getGpsNo());
      if(byGpsNo != null && byGpsNo.getInstallerId().equals(1)){
        return fail("该GPS设备已被绑定");
      }
      hjmCar.setDriverName(loginUser.getRealName());
      hjmCar.setUserId(loginUser.getUserId());
      hjmCar.setCode(null);
      if (hjmCarService.updateById(hjmCar)) {
        return success("绑定成功");
      }
    }
    return fail("修改失败");
  }

  @PreAuthorize("hasAuthority('hjm:hjmCar:remove')")
  @OperationLog
  @Operation(summary = "删除黄家明_车辆管理")
  @DeleteMapping("/{id}")
  public ApiResult<?> remove(@PathVariable("id") Integer id) {
    // 硬删除（物理删除），不走 @TableLogic 逻辑删除
    if (hjmCarService.hardRemoveById(id)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }

  @PreAuthorize("hasAuthority('hjm:hjmCar:save')")
  @OperationLog
  @Operation(summary = "批量添加黄家明_车辆管理")
  @PostMapping("/batch")
  public ApiResult<?> saveBatch(@RequestBody List<HjmCar> list) {
    if (hjmCarService.saveBatch(list)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @PreAuthorize("hasAuthority('hjm:hjmCar:update')")
  @OperationLog
  @Operation(summary = "批量修改黄家明_车辆管理")
  @PutMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody BatchParam<HjmCar> batchParam) {
    if (batchParam.update(hjmCarService, "id")) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @PreAuthorize("hasAuthority('hjm:hjmCar:remove')")
  @OperationLog
  @Operation(summary = "批量删除黄家明_车辆管理")
  @DeleteMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
    // 硬删除（物理删除），不走 @TableLogic 逻辑删除
    if (hjmCarService.hardRemoveByIds(ids)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }


  /**
   * excel批量导入车辆
   * Excel表头格式：车辆名称、车辆图片、类型、管理负责人、车辆编号、司机ID、保险状态、GPS设备编号、电子围栏ID、电子围栏名称、位置、纬度、经度、区域、地址、组织ID、父级组织ID、微信小程序码、用户ID、排序、备注、状态
   */
  @PreAuthorize("hasAuthority('hjm:hjmCar:save')")
  @Transactional(rollbackFor = {Exception.class})
  @Operation(summary = "批量导入车辆")
  @PostMapping("/import")
  public ApiResult<List<String>> importBatch(MultipartFile file) {
    ImportParams importParams = new ImportParams();
    List<String> errorMessages = new ArrayList<>();
    int successCount = 0;

    try {
      List<HjmCarImportParam> list = ExcelImportUtil.importExcel(file.getInputStream(), HjmCarImportParam.class, importParams);

      // 获取当前登录用户
      User loginUser = getLoginUser();
      Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;

      for (int i = 0; i < list.size(); i++) {
        HjmCarImportParam param = list.get(i);
        try {
          // 手动转换对象，避免JSON序列化问题
          HjmCar item = convertImportParamToEntity(param);

          // 设置必填字段的默认值
          if (item.getUserId() == null && currentUserId != null) {
            item.setUserId(currentUserId);
          }
          if (item.getStatus() == null) {
            item.setStatus(0); // 默认状态为正常
          }
          if (item.getDeleted() == null) {
            item.setDeleted(0); // 默认未删除
          }
          if (item.getType() == null) {
            item.setType(0); // 默认类型为汽车
          }

          // 验证必填字段
          if (item.getCode() == null) {
            errorMessages.add("第" + (i + 1) + "行：车辆编号不能为空");
            continue;
          }
          // 保存数据
          if (hjmCarService.save(item)) {
            successCount++;
          } else {
            errorMessages.add("第" + (i + 1) + "行：保存失败");
          }

        } catch (Exception e) {
          errorMessages.add("第" + (i + 1) + "行：" + e.getMessage());
          System.err.println("导入第" + (i + 1) + "行数据失败: " + e.getMessage());
          e.printStackTrace();
        }
      }

      // 返回结果
      if (errorMessages.isEmpty()) {
        return success("成功导入" + successCount + "条数据", null);
      } else {
        return success("导入完成，成功" + successCount + "条，失败" + errorMessages.size() + "条", errorMessages);
      }

    } catch (Exception e) {
      System.err.println("批量导入车辆失败: " + e.getMessage());
      e.printStackTrace();
      return fail("导入失败：" + e.getMessage(), null);
    }
  }

  /**
   * 下载车辆导入模板
   */
  @Operation(summary = "下载车辆导入模板")
  @GetMapping("/import/template")
  public void downloadTemplate(HttpServletResponse response) throws IOException {
    // 创建空的导入参数列表作为模板
    List<HjmCarImportParam> templateList = new ArrayList<>();

    // 添加一行示例数据
    HjmCarImportParam example = new HjmCarImportParam();
    example.setName("示例车辆");
    example.setType(0);
    example.setKuaidiAdmin("管理员");
    example.setCode("CAR");
    example.setInsuranceStatus("正常");
    example.setGpsNo("GPS001");
    example.setDistrict("示例区域");
    example.setStatus(0);
    example.setComments("这是示例数据，请删除后填入真实数据");
    templateList.add(example);

    // 设置导出参数
    ExportParams exportParams = new ExportParams("车辆导入模板", "车辆信息");

    // 生成Excel
    Workbook workbook = ExcelExportUtil.exportExcel(exportParams, HjmCarImportParam.class, templateList);

    // 设置响应头
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-Disposition", "attachment; filename=car_import_template.xlsx");

    // 输出到响应流
    workbook.write(response.getOutputStream());
    workbook.close();
  }

  /**
   * 将HjmCarImportParam转换为HjmCar实体
   */
  private HjmCar convertImportParamToEntity(HjmCarImportParam param) {
    HjmCar entity = new HjmCar();

    // 基本字段转换
    entity.setName(param.getName());
    entity.setImage(param.getImage());
    entity.setType(param.getType());
    entity.setKuaidiAdmin(param.getKuaidiAdmin());
    entity.setCode(param.getCode());
    entity.setDriverId(param.getDriverId());
    entity.setInsuranceStatus(param.getInsuranceStatus());
    entity.setGpsNo(param.getGpsNo());
    entity.setFenceId(param.getFenceId());
    entity.setFenceName(param.getFenceName());
    entity.setLocation(param.getLocation());
    entity.setLatitude(param.getLatitude());
    entity.setLongitude(param.getLongitude());
    entity.setDistrict(param.getDistrict());
    entity.setAddress(param.getAddress());
    entity.setOrganizationId(param.getOrganizationId());
    entity.setOrganizationParentId(param.getOrganizationParentId());
    entity.setMpCode(param.getMpCode());
    entity.setUserId(param.getUserId());
    entity.setSortNumber(param.getSortNumber());
    entity.setComments(param.getComments());
    entity.setStatus(param.getStatus());

    return entity;
  }

  @Operation(summary = "根据坐标解析地址(腾讯地图)")
  @GetMapping("/pageByQQMap")
  public ApiResult<PageResult<HjmCar>> pageByQQMap(HjmCarParam param) {
    // 检查必要的坐标参数
    if (param.getLatitude() == null || param.getLatitude().isEmpty() ||
        param.getLongitude() == null || param.getLongitude().isEmpty()) {
      // 如果坐标为空，直接返回分页结果
      param.setLimit(500L);
      param.setStatus(1);
      return success(hjmCarService.pageRel(param));
    }

    final DictDataParam dictDataParam = new DictDataParam();
    dictDataParam.setDictCode("QQMapKey");
//    final List<DictData> dictDataList = dictDataService.listRel(dictDataParam);
//    if (!CollectionUtils.isEmpty(dictDataList)) {
//      final DictData dictData = dictDataList.get(0);
      final String API_KEY = "RDABZ-IF7AB-L4AUO-JHMX3-GBSGE-KIF53";
      String url = "https://apis.map.qq.com/ws/geocoder/v1/?location=".concat(param.getLatitude()).concat(",").concat(param.getLongitude()).concat("&key=").concat(API_KEY);
      final String string = HttpUtil.get(url);
      if (string.contains("\"result\":")) {
        JSONObject jsonObject = JSONObject.parseObject(string);
        JSONObject result = jsonObject.getJSONObject("result");
        JSONObject address_component = result.getJSONObject("address_component");
        String district = address_component.getString("district");
        System.out.println("district = " + district);
        param.setDistrict(district);
        return success(hjmCarService.pageRel(param));
      }
//    }
    param.setLimit(100L);
    return success(hjmCarService.pageRel(param));
  }

  @Operation(summary = "获取MQTT连接状态")
  @GetMapping("/mqtt/status")
  public ApiResult<?> getMqttStatus() {
    boolean connected = mqttService.isConnected();
    String clientInfo = mqttService.getClientInfo();
    return success("MQTT状态查询成功", Map.of(
        "connected", connected,
        "clientInfo", clientInfo,
        "status", connected ? "已连接" : "未连接"
    ));
  }

  @Operation(summary = "重新连接MQTT")
  @PostMapping("/mqtt/reconnect")
  public ApiResult<?> reconnectMqtt() {
    try {
      mqttService.reconnect();
      return success("MQTT重连请求已发送");
    } catch (Exception e) {
      logger.error("MQTT重连失败", e);
      return fail("MQTT重连失败: " + e.getMessage());
    }
  }

  @Operation(summary = "GPS数据诊断")
  @GetMapping("/gps/diagnose")
  public ApiResult<?> diagnoseGpsData() {
    try {
      Map<String, Object> report = gpsDiagnosticService.diagnoseGpsDataIssues();
      return success("GPS数据诊断完成", report);
    } catch (Exception e) {
      logger.error("GPS数据诊断失败", e);
      return fail("GPS数据诊断失败: " + e.getMessage());
    }
  }

  @Operation(summary = "检查特定GPS设备")
  @GetMapping("/gps/check/{gpsNo}")
  public ApiResult<?> checkSpecificGpsDevice(@PathVariable String gpsNo) {
    try {
      Map<String, Object> deviceInfo = gpsDiagnosticService.checkSpecificGpsDevice(gpsNo);
      return success("GPS设备检查完成", deviceInfo);
    } catch (Exception e) {
      logger.error("检查GPS设备失败: {}", gpsNo, e);
      return fail("检查GPS设备失败: " + e.getMessage());
    }
  }




}
