/*
 * 文 件 名:  MockPileController
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  Mock充电桩控制接口
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/12/23
 */
package com.ruoyi.ems.controller;

import com.ruoyi.ems.charging.mock.config.MockPileAutoConfiguration;
import com.ruoyi.ems.charging.mock.model.MockGunState;
import com.ruoyi.ems.charging.mock.simulator.MockPileClient;
import com.ruoyi.ems.charging.mock.simulator.MockPileClientManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Mock充电桩控制接口
 * 提供REST API用于手动控制Mock客户端
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/23]
 */
@RestController
@RequestMapping("/api/mock/charging")
@ConditionalOnProperty(name = "adapter.charging-pile.mock.enabled", havingValue = "true")
public class MockPileController {

    @Autowired
    private MockPileClientManager clientManager;

    /**
     * 启动mock
     */
    @GetMapping("/startClient")
    public String startClient() {
        clientManager.startAll();
        return "success";
    }

    /**
     * 停止mock
     */
    @GetMapping("/stopClient")
    public String stopClient() {
        clientManager.stopAll();
        return "success";
    }

    /**
     * 获取状态统计
     */
    @GetMapping("/status")
    public Map<String, Object> getStatus() {
        return clientManager.getStatistics();
    }

    /**
     * 获取所有客户端状态
     */
    @GetMapping("/clients")
    public List<Map<String, Object>> getClients() {
        List<Map<String, Object>> result = new ArrayList<>();

        for (MockPileClient client : clientManager.getAllClients()) {
            Map<String, Object> clientInfo = new LinkedHashMap<>();
            clientInfo.put("pileCode", client.getPileCode());
            clientInfo.put("connected", client.isConnected());
            clientInfo.put("loggedIn", client.isLoggedIn());

            List<Map<String, Object>> guns = new ArrayList<>();
            for (MockGunState gunState : client.getAllGunStates()) {
                Map<String, Object> gunInfo = new LinkedHashMap<>();
                gunInfo.put("gunNo", gunState.getGunNo());
                gunInfo.put("status", gunState.isCharging() ? "charging" : "idle");
                gunInfo.put("ratedPower", gunState.getRatedPower());
                gunInfo.put("outputPower", String.format("%.2f", gunState.getOutputPower()));
                gunInfo.put("outputVoltage", String.format("%.1f", gunState.getOutputVoltage()));
                gunInfo.put("outputCurrent", String.format("%.1f", gunState.getOutputCurrent()));
                gunInfo.put("soc", gunState.getSoc());
                gunInfo.put("chargingEnergy", String.format("%.4f", gunState.getChargingEnergy()));
                gunInfo.put("chargingTime", gunState.getChargingTime());
                gunInfo.put("transactionNo", gunState.getTransactionNo());
                guns.add(gunInfo);
            }
            clientInfo.put("guns", guns);

            result.add(clientInfo);
        }

        return result;
    }

    /**
     * 获取指定枪的状态
     */
    @GetMapping("/gun/{pileCode}/{gunNo}")
    public Map<String, Object> getGunStatus(
            @PathVariable String pileCode,
            @PathVariable String gunNo) {

        MockGunState gunState = clientManager.getGunState(pileCode, gunNo);
        if (gunState == null) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "未找到指定的枪");
            error.put("pileCode", pileCode);
            error.put("gunNo", gunNo);
            return error;
        }

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("pileCode", gunState.getPileCode());
        result.put("gunNo", gunState.getGunNo());
        result.put("fullGunNo", gunState.getFullGunNo());
        result.put("status", gunState.isCharging() ? "charging" : "idle");
        result.put("gunConnected", gunState.isGunConnected());
        result.put("ratedPower", gunState.getRatedPower());
        result.put("maxOutputPowerPercent", gunState.getMaxOutputPowerPercent());
        result.put("outputPower", String.format("%.2f", gunState.getOutputPower()));
        result.put("outputVoltage", String.format("%.1f", gunState.getOutputVoltage()));
        result.put("outputCurrent", String.format("%.1f", gunState.getOutputCurrent()));
        result.put("gunTemperature", gunState.getGunTemperature());
        result.put("soc", gunState.getSoc());
        result.put("batteryMaxTemp", gunState.getBatteryMaxTemp());
        result.put("chargingEnergy", String.format("%.4f", gunState.getChargingEnergy()));
        result.put("chargedAmount", String.format("%.4f", gunState.getChargedAmount()));
        result.put("chargingTime", gunState.getChargingTime());
        result.put("remainingTime", gunState.getRemainingTime());
        result.put("transactionNo", gunState.getTransactionNo());
        result.put("vin", gunState.getVin());
        result.put("hardwareFault", gunState.getHardwareFault());

        return result;
    }

    /**
     * 手动开始充电
     */
    @PostMapping("/start/{pileCode}/{gunNo}")
    public Map<String, Object> startCharging(
            @PathVariable String pileCode,
            @PathVariable String gunNo) {

        Map<String, Object> result = new HashMap<>();
        result.put("pileCode", pileCode);
        result.put("gunNo", gunNo);

        try {
            clientManager.startCharging(pileCode, gunNo);
            result.put("success", true);
            result.put("message", "充电已启动");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

    /**
     * 手动停止充电
     */
    @PostMapping("/stop/{pileCode}/{gunNo}")
    public Map<String, Object> stopCharging(
            @PathVariable String pileCode,
            @PathVariable String gunNo) {

        Map<String, Object> result = new HashMap<>();
        result.put("pileCode", pileCode);
        result.put("gunNo", gunNo);

        try {
            clientManager.stopCharging(pileCode, gunNo);
            result.put("success", true);
            result.put("message", "充电已停止");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

    /**
     * 获取所有枪的状态列表
     */
    @GetMapping("/guns")
    public List<Map<String, Object>> getAllGuns() {
        List<Map<String, Object>> result = new ArrayList<>();

        for (MockGunState gunState : clientManager.getAllGunStates()) {
            Map<String, Object> gunInfo = new LinkedHashMap<>();
            gunInfo.put("fullGunNo", gunState.getFullGunNo());
            gunInfo.put("pileCode", gunState.getPileCode());
            gunInfo.put("gunNo", gunState.getGunNo());
            gunInfo.put("status", gunState.isCharging() ? "充电中" : "空闲");
            gunInfo.put("ratedPower", gunState.getRatedPower() + "kW");
            gunInfo.put("outputPower", String.format("%.1fkW", gunState.getOutputPower()));
            gunInfo.put("soc", gunState.getSoc() + "%");
            gunInfo.put("energy", String.format("%.2fkWh", gunState.getChargingEnergy()));
            result.add(gunInfo);
        }

        return result;
    }
}
