package com.zsElectric.boot.business.controller.applet;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zsElectric.boot.business.model.entity.ChargeOrderInfo;
import com.zsElectric.boot.business.model.entity.UserAccount;
import com.zsElectric.boot.business.model.form.applet.AppInvokeChargeForm;
import com.zsElectric.boot.business.model.form.applet.AppStopChargeForm;
import com.zsElectric.boot.business.model.query.applet.AppChargeOrderInfoQuery;
import com.zsElectric.boot.business.model.vo.ChargeOrderInfoVO;
import com.zsElectric.boot.business.model.vo.applet.AppChargeVO;
import com.zsElectric.boot.business.service.ChargeOrderInfoService;
import com.zsElectric.boot.business.service.UserAccountService;
import com.zsElectric.boot.charging.entity.ThirdPartyApiLog;
import com.zsElectric.boot.charging.mapper.ThirdPartyApiLogMapper;
import com.zsElectric.boot.common.annotation.Log;
import com.zsElectric.boot.common.enums.LogModuleEnum;
import com.zsElectric.boot.core.exception.BusinessException;
import com.zsElectric.boot.core.web.Result;
import com.zsElectric.boot.security.util.SecurityUtils;
import com.zsElectric.boot.system.mapper.DictItemMapper;
import com.zsElectric.boot.system.model.entity.DictItem;
import com.zsElectric.boot.system.service.DictItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Tag(name = "充电订单相关接口")
@Slf4j
@RestController
@RequestMapping("/applet/v1/charge")
@RequiredArgsConstructor
public class AppletChargeController {

    private final ChargeOrderInfoService chargeOrderInfoService;
    private final DictItemService dictItemService;
    private final UserAccountService userAccountService;
    private final ThirdPartyApiLogMapper thirdPartyApiLogMapper;

    /**
     * 充电订单记录
     *
     * @param queryParams
     * @return
     */
    @Operation(summary = "充电订单记录")
    @PostMapping("/getPage")
    public Result<IPage<ChargeOrderInfoVO>> getPage(@RequestBody AppChargeOrderInfoQuery queryParams) {
        IPage<ChargeOrderInfoVO> page = chargeOrderInfoService.getPage(queryParams);
        return Result.success(page);
    }

    /**
     * 充电订单详情
     *
     * @param chargeOrderNo
     * @return
     */
    @Operation(summary = "充电订单详情")
    @GetMapping("/queryOrder/{chargeOrderNo}")
    public Result<ChargeOrderInfoVO> queryOrder(@PathVariable("chargeOrderNo") String chargeOrderNo) {
        ChargeOrderInfoVO infoVO = chargeOrderInfoService.queryOrder(chargeOrderNo);
        return Result.success(infoVO);
    }

    /**
     * 校验用户余额是否满足起充价
     * @return Boolean
     */
    @Operation(summary = "校验用户余额是否满足起充价")
    @PostMapping("/checkUserAccount")
    public Result<Map<String,Object>> checkUserAccount() {

        Map<String,Object> map = new HashMap<>();

        Long userId = SecurityUtils.getUserId();

        //查询订单起充价
        DictItem upRecharge = dictItemService.getOne(Wrappers.<DictItem>lambdaQuery()
                .eq(DictItem::getDictCode, "up_recharge")
                .last("limit 1")
        );
        if(ObjectUtil.isNotEmpty(upRecharge)){
            BigDecimal chargeFee = new BigDecimal(upRecharge.getValue());
            UserAccount one = userAccountService.getOne(Wrappers.lambdaQuery(UserAccount.class).eq(UserAccount::getUserId, userId).last("limit 1"));
            if(one.getBalance().compareTo(chargeFee) < 0){
                map.put("status",Boolean.FALSE);
                map.put("message","用户余额低于起充值 "+chargeFee+" 元，请前往充值后再充电！");
                return Result.success(map);
            }
        }
        map.put("status",Boolean.TRUE);
        return Result.success(map);
    }

    /**
     * 启用充电
     *
     * @param formData
     * @return
     */
    @Operation(summary = "启用充电")
    @PostMapping("/invokeCharge")
    @Log(value = "启用充电", module = LogModuleEnum.APP_CHARGE_ORDER)
    public Result<AppChargeVO> invokeCharge(@Valid @RequestBody AppInvokeChargeForm formData) throws JsonProcessingException {
        AppChargeVO appInvokeChargeVO = chargeOrderInfoService.invokeCharge(formData);
        return Result.success(appInvokeChargeVO);
    }

    /**
     * 结束充电
     *
     * @param formData
     * @return
     */
    @Operation(summary = "结束充电")
    @PostMapping("/stopCharge")
    @Log(value = "结束充电", module = LogModuleEnum.APP_CHARGE_ORDER)
    public Result<AppChargeVO> stopCharge(@RequestBody AppStopChargeForm formData) {
        AppChargeVO appStopChargeVO= chargeOrderInfoService.stopCharge(formData);
        return Result.success(appStopChargeVO);
    }

    /**
     * 查询充电订单的推送数据
     *
     * @param chargeOrderNo 充电订单编号
     * @return 推送数据
     */
    @Operation(summary = "查询充电订单推送数据", description = "通过充电订单编号查询第三方推送的原始数据")
    @GetMapping("/queryPushData/{chargeOrderNo}")
    public Result<String> queryPushData(@PathVariable("chargeOrderNo") String chargeOrderNo) {
        // 1. 通过充电订单编号查询订单信息
        ChargeOrderInfo orderInfo = chargeOrderInfoService.getOne(Wrappers.<ChargeOrderInfo>lambdaQuery()
                .eq(ChargeOrderInfo::getChargeOrderNo, chargeOrderNo)
                .last("LIMIT 1"));
        
        if (orderInfo == null) {
            return Result.failed("订单不存在");
        }
        
        if (orderInfo.getStartChargeSeq() == null) {
            return Result.failed("订单缺少StartChargeSeq");
        }
        
        // 2. 通过start_charge_seq模糊匹配third_party_api_log中的decrypted_request_data
        ThirdPartyApiLog apiLog = thirdPartyApiLogMapper.selectOne(
                Wrappers.<ThirdPartyApiLog>lambdaQuery()
                        .eq(ThirdPartyApiLog::getInterfaceDescription, "推送充电订单信息")
                        .like(ThirdPartyApiLog::getDecryptedRequestData, orderInfo.getStartChargeSeq())
                        .orderByDesc(ThirdPartyApiLog::getCreatedTime)
                        .last("LIMIT 1"));
        
        if (apiLog == null || apiLog.getDecryptedRequestData() == null) {
            return Result.failed("未找到推送数据");
        }
        
        return Result.success(apiLog.getDecryptedRequestData());
    }

}
