package com.haha.sdk.api;

import com.haha.sdk.HahaClient;
import com.haha.sdk.exception.HahaException;
import com.haha.sdk.model.DeviceInfo;
import com.haha.sdk.model.DeviceOnlineStatus;
import com.haha.sdk.model.OpenDoorResult;
import lombok.extern.slf4j.Slf4j;

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

/**
 * 设备相关API
 * 
 * @author haha-sdk
 * @version 1.0.0
 */
@Slf4j
public class DeviceApi extends BaseApi {
    
    public DeviceApi(HahaClient client) {
        super(client);
    }
    
    /**
     * 获取设备列表
     * 
     * @param pageNo 页码
     * @param pageSize 每页数量
     * @return 设备列表
     * @throws HahaException 调用失败时抛出
     */
    public List<DeviceInfo> getDeviceList(int pageNo, int pageSize) throws HahaException {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("page_no", String.valueOf(pageNo));
        params.put("page_size", String.valueOf(pageSize));
        
        return post("/device/getlist", params, DeviceInfo.class, true);
    }
    
    /**
     * 查询设备是否为多门单开
     * 
     * @param deviceId 设备ID
     * @return 多门单开类型：0-非多门单开，2-双门单开，3-三门单开，4-四门单开
     * @throws HahaException 调用失败时抛出
     */
    public Integer isMultiDoorUnique(String deviceId) throws HahaException {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        
        Map<String, Object> result = post("/device/isMultiDoorUnique", params);
        Object data = result.get("data");
        if (data instanceof Map) {
            return (Integer) ((Map<?, ?>) data).get("multi_door_unique");
        }
        return 0;
    }
    
    /**
     * 设备开门
     * 
     * @param deviceId 设备ID
     * @param outUserId 商户系统用户编号（非哈哈系统产生），6-32位数字或字母
     * @param openType 开门类型：IN 表示上货，OUT 表示消费
     * @param doorIndex 门编号：A 左门，B 右门，双门单开柜该参数必传
     * @param source 请求来源（可选）
     * @return 开门结果
     * @throws HahaException 调用失败时抛出
     */
    public OpenDoorResult openDoor(String deviceId, String outUserId, String openType, String doorIndex, String source) throws HahaException {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        params.put("out_user_id", outUserId);
        params.put("open_type", openType);
        if (doorIndex != null && !doorIndex.isEmpty()) {
            params.put("door_index", doorIndex);
        }
        if (source != null && !source.isEmpty()) {
            params.put("source", source);
        }
        
        Map<String, Object> result = post("/door/open", params);
        Object data = result.get("data");
        if (data instanceof Map) {
            OpenDoorResult openResult = new OpenDoorResult();
            openResult.setActivityId((String) ((Map<?, ?>) data).get("activity_id"));
            openResult.setUserId((String) ((Map<?, ?>) data).get("user_id"));
            return openResult;
        }
        throw new HahaException("开门失败：返回数据格式错误");
    }
    
    /**
     * 查询设备在线状态
     * 
     * @param deviceId 设备ID
     * @return 设备在线状态
     * @throws HahaException 调用失败时抛出
     */
    public DeviceOnlineStatus getOnlineStatus(String deviceId) throws HahaException {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        
        Map<String, Object> result = post("/device/getDeviceOnlineStatus", params);
        Object data = result.get("data");
        if (data instanceof Map) {
            DeviceOnlineStatus status = new DeviceOnlineStatus();
            status.setDeviceId((String) ((Map<?, ?>) data).get("device_id"));
            status.setIsOnline(Integer.valueOf((String) ((Map<?, ?>) data).get("is_online")));
            return status;
        }
        throw new HahaException("查询设备在线状态失败：返回数据格式错误");
    }
    
    /**
     * 设置设备音量 (仅限动态柜)
     * 
     * @param deviceId 设备 ID
     * @param voice 音量大小值 0~15
     * @return 是否成功
     * @throws HahaException 调用失败时抛出
     */
    public boolean setVoice(String deviceId, int voice) throws HahaException {
        if (voice < 0 || voice > 15) {
            throw new IllegalArgumentException("音量值必须在 0-15 之间");
        }
            
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        params.put("voice", String.valueOf(voice));
            
        post("/device/voiceControl", params);
        return true;
    }
        
    /**
     * 设置设备温度 (仅限动态柜)
     * 
     * @param deviceId 设备 ID
     * @param temperature 温度值，范围 -30~30℃
     * @return 是否成功
     * @throws HahaException 调用失败时抛出
     */
    public boolean setTemperature(String deviceId, double temperature) throws HahaException {
        if (temperature < -30 || temperature > 30) {
            throw new IllegalArgumentException("温度值必须在 -30~30℃之间");
        }
            
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        params.put("temperature", String.valueOf(temperature));
            
        post("/device/setTemperature", params);
        return true;
    }
    
    /**
     * 查询设备和锁的状态
     * 
     * @param deviceId 设备ID
     * @return 设备状态信息
     * @throws HahaException 调用失败时抛出
     */
    public Map<String, Object> getDeviceStatus(String deviceId) throws HahaException {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", client.getAccessToken());
        params.put("device_id", deviceId);
        
        Map<String, Object> result = post("/device/checkstatus", params);
        Object data = result.get("data");
        if (data instanceof Map) {
            return (Map<String, Object>) data;
        }
        throw new HahaException("查询设备状态失败：返回数据格式错误");
    }
    
}
