package cn.sikey.mcdisk.service;

import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.sikey.framework.common.exception.ServiceException;
import cn.sikey.mcdisk.config.McdiskConfig;
import cn.sikey.mcdisk.config.OkHttpUtil;
import cn.sikey.mcdisk.config.RedisUtil;
import cn.sikey.mcdisk.controller.app.familycloud.vo.InviteFamilyMemberRespVO;
import cn.sikey.mcdisk.controller.app.wristwatch.vo.AuthorizeRespVO;
import cn.sikey.mcdisk.convert.OauthConvert;
import cn.sikey.mcdisk.dal.dataobject.AuthorizeDO;
import cn.sikey.mcdisk.dal.mysql.AuthorizeMapper;
import cn.sikey.mcdisk.enums.AccountTypeEnum;
import cn.sikey.mcdisk.enums.ApiEndpointsEnum;
import cn.sikey.mcdisk.enums.CodeStatusEnum;
import cn.sikey.mcdisk.pojo.McdiskResult;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: nelson
 * @Date: 2025/5/29
 * @Description: 抽象服务
 */
@Slf4j
public class AbstractMcdiskService {

    @Resource
    public McdiskConfig mcdiskConfig;

    @Resource
    public OkHttpUtil okHttpUtil;

    private static final int MCDISK_SUCCESS_STATUS = 0;

    private static final String CHANNEL_ID = "10012";

    @Resource
    private AuthorizeMapper authorizeMapper;

    @Resource
    private RedisUtil redisUtil;

    @Qualifier("myTaskExecutor")
    @Autowired
    public ThreadPoolTaskExecutor myTaskExecutor;

    @Resource
    public InviteFamilyMemberService inviteFamilyMemberService;

    /**
     * 校验headers内容
     *
     * @param headers header
     * @return
     */
    public void validateHeaders(JSONObject headers) {
        if (headers == null || headers.isEmpty()) {
            throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, "header内容不能为空");
        }
    }

    /**
     * 校验body内容
     *
     * @param body 内容
     * @return
     */
    public void validateBody(JSONObject body) {
        if (body == null || body.isEmpty()) {
            throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, "body内容不能为空");
        }
    }

    /**
     * 校验app认证
     *
     * @param userId 用户id
     * @param ticket ticket
     * @return
     */
    public void validateInviteFamilyMember(String userId, String ticket) {
        InviteFamilyMemberRespVO inviteFamilyMemberRespVO = inviteFamilyMemberService.queryAppOauth(userId, ticket);
        if (Objects.nonNull(inviteFamilyMemberRespVO)) {
            throw new ServiceException(CodeStatusEnum.USER_HAS_BEEN_AUTHENTICATED.getCode(), CodeStatusEnum.USER_HAS_BEEN_AUTHENTICATED.getDescription());
        }
    }

    /**
     * 获取header
     *
     * @param deviceId      deviceId
     * @param accessToken accessToken
     * @return
     */
    public Map<String, String> getHeaders(String deviceId, String accessToken) {
        // 准备请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("appid", mcdiskConfig.getAppid());
        headers.put("secretkey", mcdiskConfig.getSecretkey());
        headers.put("accesstoken", accessToken);
        headers.put("deviceId", deviceId);
        headers.put("channelId", CHANNEL_ID);// 硬件类型
        //  headers.put("token", "token");// TODO 通过手表获取
        return headers;
    }

    /**
     * 请求移动云
     *
     * @param apiUrl   请求地址
     * @param jsonBody 请求报文
     * @param headers  请求headers
     * @return
     */
    public McdiskResult getMcdiskResult(String apiUrl, String jsonBody, Map<String, String> headers) {
        String response = okHttpUtil.postJson(apiUrl, jsonBody, headers);
        if (StringUtils.isBlank(response)) {
            throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, "调用移动云盘：返回数据是空");
        }

        McdiskResult mcdiskResult = JSONUtil.toBean(response, McdiskResult.class);
        if (Objects.isNull(mcdiskResult) || mcdiskResult.getCode() != MCDISK_SUCCESS_STATUS || Objects.isNull(mcdiskResult.getData())) {
            throw new ServiceException(mcdiskResult.getCode(), "调用移动云盘：" + mcdiskResult.getMessage());
        }
        return mcdiskResult;
    }

    /**
     * 获取用户家庭云列表
     *
     * @param accountType 用户类型
     * @param ticket      ticket
     * @param accessToken accessToken
     * @return
     */
    private McdiskResult queryFamilyCloud(Integer accountType, String ticket, String accessToken) {
        // 准备请求参数
        String apiUrl = mcdiskConfig.getPath() + ApiEndpointsEnum.QUERY_FAMILY_CLOUD.getPath();
        // 创建根 JSON 对象
        JSONObject jsonObject = new JSONObject();

        // 添加 commonAccountInfo 对象
        JSONObject commonAccountInfo = new JSONObject();
        commonAccountInfo.put("accountType", accountType);
        jsonObject.put("commonAccountInfo", commonAccountInfo);

        // 添加 cloudId 字段
        //  jsonObject.put("cloudID", cloudId);

        // 添加 pageInfo 对象
        JSONObject pageInfo = new JSONObject();
        pageInfo.put("objectID", 0);
        pageInfo.put("pageNum", 1);
        pageInfo.put("pageSize", 99);
        jsonObject.put("pageInfo", pageInfo);

        // 准备请求头
        Map<String, String> headers = getHeaders(ticket, accessToken);

        // 发送请求
        McdiskResult mcdiskResult = getMcdiskResult(apiUrl, jsonObject.toString(), headers);
        log.info("[获取用户家庭云列表]返回数据：{}", mcdiskResult);
        return mcdiskResult;
    }

    /**
     * 查询家庭云下的相册列表
     *
     * @param cloudId     家庭云ID
     * @param ticket      ticket
     * @param accessToken accessToken
     * @return
     */
    public McdiskResult queryCloudPhoto(String cloudId, String ticket, String accessToken) {
        // 准备请求参数
        String apiUrl = mcdiskConfig.getPath() + ApiEndpointsEnum.QUERY_CLOUD_PHOTO.getPath();
        // 创建根 JSON 对象
        JSONObject jsonObject = new JSONObject();

        // 添加 commonAccountInfo 对象
        JSONObject commonAccountInfo = new JSONObject();
        commonAccountInfo.put("accountType", AccountTypeEnum.PHONE_NUMBER.getValue());
        jsonObject.put("commonAccountInfo", commonAccountInfo);

        // 添加 cloudId 字段
        jsonObject.put("cloudID", cloudId);

        // 准备请求头
        Map<String, String> headers = getHeaders(ticket, accessToken);

        // 发送请求
        McdiskResult mcdiskResult = getMcdiskResult(apiUrl, jsonObject.toString(), headers);
        log.info("[查询家庭云下的相册列表]返回数据：{}", mcdiskResult);
        return mcdiskResult;
    }

    /**
     * 校验家庭云名称唯一性
     *
     * @param newCloudName 待创建的家庭云名称
     * @param accountType  用户类型
     * @param ticket       ticket
     * @param accessToken  accessToken
     * @return
     */
    public void validateCloudNameUniqueness(String newCloudName, Integer accountType, String ticket, String accessToken) {
        McdiskResult familyCloud = queryFamilyCloud(accountType, ticket, accessToken);
        String jsonStr = JSONUtil.toJsonStr(familyCloud.getData());
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        JSONArray cloudList = jsonObject.getJSONArray("familyCloudList");

        for (int i = 0; i < cloudList.size(); i++) {
            JSONObject cloudInfo = cloudList.getJSONObject(i);
            String existingName = cloudInfo.getStr("cloudName");

            if (StringUtils.isNotBlank(existingName) && StringUtils.equalsIgnoreCase(existingName.trim(), newCloudName.trim())) {
                throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, "已存在家庭云名称");
            }
        }
    }

    /**
     * 校验家庭云下的相册唯一性
     *
     * @param photoName   待创建的家庭云相册名称
     * @param cloudId     家庭云ID
     * @param ticket      ticket
     * @param accessToken accessToken
     * @return
     */
    public void validateCloudPhotoNameUniqueness(String photoName, String cloudId, String ticket, String accessToken) {
        McdiskResult familyCloud = queryCloudPhoto(cloudId, ticket, accessToken);
        String jsonStr = JSONUtil.toJsonStr(familyCloud.getData());
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        JSONArray cloudPhotoList = jsonObject.getJSONArray("cloudPhotoList");

        for (int i = 0; i < cloudPhotoList.size(); i++) {
            JSONObject cloudInfo = cloudPhotoList.getJSONObject(i);
            String existingPhotoName = cloudInfo.getStr("photoName");

            if (StringUtils.isNotBlank(existingPhotoName) && StringUtils.equalsIgnoreCase(existingPhotoName.trim(), photoName.trim())) {
                throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, "已存在家庭云相册名称");
            }
        }
    }

    /**
     * 邀请用户加入家庭云（链接模式）
     *
     * @param cloudId     家庭云ID
     * @param channelType 邀请渠道（2：微信4：QQ5：二维码），如果没有携带，默认为2：微信
     * @param ticket      ticket
     * @param accessToken accessToken
     * @return
     */
    public McdiskResult inviteFamilyMember(String cloudId, String channelType, String ticket, String accessToken) {
        // 准备请求参数
        String apiUrl = mcdiskConfig.getPath() + ApiEndpointsEnum.INVITE_FAMILY_MEMBER.getPath();
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("cloudID", cloudId);
        jsonObject.set("channelType", channelType);
        String jsonBody = jsonObject.toString();

        // 准备请求头
        Map<String, String> headers = getHeaders(ticket,accessToken);

        // 发送请求
        McdiskResult mcdiskResult = getMcdiskResult(apiUrl, jsonBody, headers);
        log.info("[邀请用户加入家庭云（链接模式）]返回数据：{}", mcdiskResult);
        return mcdiskResult;
    }

    /**
     * 设备是否授权
     *
     * @param deviceId 设备编码
     * @return
     */
    public boolean isAuthorize(String deviceId) {
        return authorizeMapper.queryIsAuthorize(deviceId);
    }

}
