package com.kym.miniapp.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.kym.common.R;
import com.kym.common.annotation.ApiLog;
import com.kym.common.config.WxConfig;
import com.kym.common.enums.WxApi;
import com.kym.common.utils.HttpUtil;
import com.kym.entity.admin.queryParams.StationQueryParam;
import com.kym.entity.miniapp.ChargeOrder;
import com.kym.entity.miniapp.queryParams.OrderQueryParams;
import com.kym.entity.platform.response.PlatformResponse;
import com.kym.service.admin.StationService;
import com.kym.service.miniapp.ChargeOrderService;
import com.kym.service.miniapp.ChargeService;
import com.kym.service.platform.PlatformNotifyService;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Map;


/**
 * 充电
 *
 * @author skyline
 * @since 2023-06-27
 */
@RestController
@RequestMapping("/charge")
public class ChargeController {

    private final StationService stationService;

    private final ChargeService chargeService;

    private final ChargeOrderService chargeOrderService;

    private final PlatformNotifyService enNotifyService;

    private final WxConfig wxConfig;


    public ChargeController(StationService stationService, ChargeService chargeService,
                            ChargeOrderService chargeOrderService,
                            PlatformNotifyService enNotifyService, WxConfig wxConfig) {
        this.stationService = stationService;
        this.chargeService = chargeService;
        this.chargeOrderService = chargeOrderService;
        this.enNotifyService = enNotifyService;
        this.wxConfig = wxConfig;
    }

//    /**
//     * 充电站列表
//     *
//     * @param pageNum
//     * @param pageSize
//     * @return
//     */
//    @SneakyThrows
//    @GetMapping("/listStation")
//    @SaIgnore
//    R<?> listChargeStation(
//            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
//            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
//        return R.success(stationService.queryLocalStationInfo(pageNum, pageSize));
//    }


    /**
     * 充电站列表
     *
     * @param params
     * @return
     */
    @GetMapping("/listStation")
    @SaIgnore
    R<?> listChargeStation(@ModelAttribute StationQueryParam params) {
        return R.success(stationService.listStationForApp(params));
    }

    /**
     * 站点信息（包含充电枪信息）
     *
     * @param stationId
     * @return
     */
    @GetMapping("/stationInfo/{stationId}")
    @SaIgnore
    R<?> stationInfo(@PathVariable String stationId) {
        return R.success(stationService.stationInfo(stationId));
    }


    /**
     * 根据设备短ID获取站点信息（包含充电枪信息）
     *
     * @param shortId
     * @return
     */
    @GetMapping("/stationInfoByShortId/{shortId}")
    @SaIgnore
    R<?> stationInfoByShortId(@PathVariable String shortId) {
        return R.success(stationService.stationInfoByShortId(shortId));
    }


    /**
     * 根据设备短ID获取站点信息（包含充电枪信息）
     *
     * @return
     */
    @GetMapping("/stationInfoByConnectorId/{connectorId}")
    @SaIgnore
    R<?> stationInfoByConnectorId(@PathVariable String connectorId) {
        return R.success(stationService.stationInfoByConnectorId(connectorId));
    }


    /**
     * 根据设备短ID获取站点信息（包含充电枪信息）
     *
     * @return
     */
    @GetMapping("/stationInfoByEquipmentId/{equipmentId}")
    @SaIgnore
    R<?> stationInfoByEquipmentId(@PathVariable String equipmentId) {
        return R.success(stationService.stationInfoByEquipmentId(equipmentId));
    }


    /**
     * 充电站状态
     *
     * @param ids
     * @return
     */
    @GetMapping("/stationStatus")
    @SaIgnore
    R<?> stationStatus(@RequestParam("stationIds") String ids) {
        // 请求en+接口
        var response = stationService.stationStatus(ids.split(","));
        return R.success(response);
    }

    @ApiLog("启动充电")
    @GetMapping("/startCharge/{connectorId}")
    R<?> startCharge(@PathVariable("connectorId") String connectorId,
                     @RequestParam(value = "userRechargeRightsId", required = false) Long userRechargeRightsId,
                     @RequestParam(value = "userCouponId", required = false) Long userCouponId,
                     @RequestParam(value = "isBooking", defaultValue = "false") Boolean isBooking,
                     @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
                     @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        var userId = StpUtil.getLoginIdAsLong();
        return R.success(chargeService.queryStartCharge(userId, connectorId, userRechargeRightsId, userCouponId, isBooking, startTime, endTime));
    }

    @ApiLog("取消预约充电")
    @GetMapping("/cancelBooking")
    R<?> cancelBooking() {
        chargeService.cancelBooking();
        return R.success();
    }

    @ApiLog("修改预约充电时间")
    @GetMapping("/modifyBookingTime")
    R<?> modifyBookingTime(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime) {
        chargeService.modifyBookingTime(startChargeSeq, startTime);
        return R.success();
    }

    @ApiLog("预约改立即充电")
    @GetMapping("immediatelyCharge/{connectorId}")
    R<?> immediatelyCharge(@PathVariable("connectorId") String connectorId) {
        return R.success(chargeService.immediatelyCharge(connectorId));
    }

    @ApiLog("停止充电")
    @GetMapping("/stopCharge/{connectorId}")
    R<?> stopCharge(@PathVariable("connectorId") String connectorId) {
        chargeService.queryStopCharge(StpUtil.getLoginIdAsLong(), connectorId);
        return R.success();
    }

    /**
     * 查询当前用户充电状态
     *
     * @return
     */
    @GetMapping("/chargeStatus")
    R<ChargeOrder> chargeStatus() {
        return R.success(chargeService.queryEquipChargeStatus());
    }

    /**
     * 查询充电策略
     *
     * @param connectorId
     * @return
     */
    @GetMapping("/businessPolicy/{connectorId}")
    @SaIgnore
    R<?> businessPolicy(@PathVariable("connectorId") String connectorId) {
        return R.success(chargeService.queryEquipBusinessPolicy(connectorId));
    }

    /**
     * 用户订单列表
     *
     * @return
     */
    @GetMapping("/listUserChargeOrders")
    R<?> listUserChargeOrders(@ModelAttribute OrderQueryParams params) {
        return R.success(chargeOrderService.listUserChargeOrders(params));
    }

    /**
     * 充电订单详情
     *
     * @param startChargeSeq
     * @return
     */
    @GetMapping("/orderDetail/{startChargeSeq}")
    R<?> orderDetail(@PathVariable("startChargeSeq") String startChargeSeq) {
        return R.success(chargeOrderService.orderDetailForApp(startChargeSeq));
    }

    /**
     * 订单优惠详情
     *
     * @param startChargeSeq
     * @param discountType
     * @return
     */
    @GetMapping("/orderDiscountDetail")
    R<?> orderDiscountDetail(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("discountType") String discountType) {
        return R.success(chargeOrderService.orderDiscountDetail(startChargeSeq, discountType));
    }

    /**
     * 图片二维码识别
     *
     * @param imgUrl
     * @return
     */
    @GetMapping("/qrCode")
    R<?> qrCode(String imgUrl) {
        var accessTokenJson = HttpUtil.getJson(WxApi.WX_GET_ACCESS_TOKEN.getApi(), Map.of("appid", wxConfig.getAppid(), "secret", wxConfig.getSecret()));
        var accessToken = accessTokenJson.getString("access_token");
        // https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/img-ocr/img/scanQRCode.html
        // 问候微信API文档撰写祖宗十八代，这里img_url也是url传参！！！
        var res = HttpUtil.post(WxApi.WX_QR_CODE.getApi().replace("ACCESS_TOKEN", accessToken).concat("&img_url=%s".formatted(imgUrl)), Map.of(), JSONObject.class);
        return R.success(res);
    }

    //====================================================以上是请求EN+接口==============================================================

    // 【我们请求en+时，数据都要加密验签；en+推送给我们的数据，需要验签解密，响应不需要加密。】

    //====================================================以下是EN+推送接口==============================================================

    /**
     * 【互联互通平台】提供Token
     */
    @ApiLog("互联互通平台推送请求Token")
    @PostMapping("/{platformName}/query_token")
    PlatformResponse queryToken(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.queryToken(platformName, json));
    }

    /**
     * 【互联互通平台】推送场站设备状态变化
     *
     * @param json
     * @return 0:接收 1：丢弃/忽略，不需要重试
     */
//    @ApiLog("推送场站设备状态变化")
    @PostMapping("/{platformName}/notification_stationStatus")
    PlatformResponse notificationStationStatus(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleNotificationStationStatus(platformName, json));
    }

    /**
     * 【互联互通平台】推送启动充电结果
     *
     * @param json
     * @return StartChargeSeq SuccStat 0:成功 1：失败  FailReason 0:无 1：接收失败
     */
    @ApiLog("推送启动充电结果")
    @PostMapping("/{platformName}/notification_start_charge_result")
    PlatformResponse notificationStartChargeResult(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleNotificationStartChargeResult(platformName, json));
    }

    /**
     * 【互联互通平台】推送充电状态
     *
     * @param json
     * @return
     */
//    @ApiLog("推送充电状态")
    @PostMapping("/{platformName}/notification_equip_charge_status")
    PlatformResponse notificationEquipChargeStatus(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleNotificationEquipChargeStatus(platformName, json));
    }

    /**
     * 【互联互通平台】推送停止充电结果
     *
     * @param json
     * @return
     */
    @ApiLog("推送停止充电结果")
    @PostMapping("/{platformName}/notification_stop_charge_result")
    PlatformResponse notificationStopChargeResult(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleNotificationStopChargeResult(platformName, json));
    }

    /**
     * 【互联互通平台】推送充电订单信息
     *
     * @param json
     * @return
     */
    @ApiLog("推送充电订单信息")
    @PostMapping("/{platformName}/notification_charge_order_info")
    PlatformResponse notificationChargeOrderInfo(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleNotificationChargeOrderInfo(platformName, json));
    }

    /**
     * 【互联互通平台】推送订单对账结果信息
     *
     * @param json
     * @return
     */
    @ApiLog("推送订单对账结果信息")
    @PostMapping("/{platformName}/check_charge_orders")
    PlatformResponse checkChargeOrders(@PathVariable(value = "platformName", required = false) String platformName, @RequestBody JSONObject json) {
        return new PlatformResponse(enNotifyService.handleCheckChargeOrders(platformName, json));
    }


    //====================================================以下是手动同步数据接口==============================================================

    /**
     * 拉取充电站信息数据并更新本地服务器数据
     *
     * @return
     */
    @GetMapping("/pullEnStations/{stationId}")
    R<?> pullEnStationInfos(@PathVariable String stationId) {
        stationService.pullEnStationInfos(stationId);
        return R.success();
    }


}
