package com.ff.api.controller;


import cn.hutool.core.bean.BeanUtil;
import com.ff.annotation.CheckHeader;
import com.ff.api.request.MemberCreateApiRequest;
import com.ff.api.request.MemberInfoAllApiRequest;
import com.ff.api.request.MemberInfoApiRequest;
import com.ff.api.response.MemberInfoAllResponse;
import com.ff.api.response.MemberInfoResponse;
import com.ff.base.constant.Constants;
import com.ff.base.core.controller.BaseController;
import com.ff.base.core.domain.AjaxResult;
import com.ff.base.enums.ErrorCode;
import com.ff.base.exception.base.ApiException;
import com.ff.base.exception.base.BaseException;
import com.ff.base.manager.AsyncManager;
import com.ff.base.utils.StringUtils;
import com.ff.common.domain.TenantSecretKey;
import com.ff.config.KeyConfig;
import com.ff.game.api.IGamesService;
import com.ff.game.api.request.*;
import com.ff.game.domain.GameSecretKey;
import com.ff.game.service.IGameSecretKeyService;
import com.ff.game.service.IGameService;
import com.ff.member.domain.Member;
import com.ff.member.service.IMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

/**
 * api控制器
 *
 * @author shi
 * @date 2025/02/10
 */
@RestController
@CheckHeader
@RequestMapping("/api/member")
@Slf4j
public class ApiMemberController extends BaseController {


    @Autowired
    private Map<String, IGamesService> gamesService;


    @Resource
    private IGameService gameService;


    @Resource
    private KeyConfig keyConfig;

    @Resource
    private IGameSecretKeyService gameSecretKeyService;

    @Resource
    private IMemberService memberService;


    @Autowired
    @Qualifier("threadPoolTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 创建成员
     *
     * @param memberCreateApiRequest 创建成员api请求
     * @return {@link AjaxResult }
     */
    @PostMapping("/create")
    @Transactional
    public AjaxResult createMember(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) {

        IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE);
        ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());

        TenantSecretKey tenantSecretKey = keyConfig.get();
        GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberCreateApiRequest.getPlatformCode(), memberCreateApiRequest.getCurrencyCode());
        ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());

        String gameAccount = StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn());
        //向第三方注册账号
        CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder()
                .account(gameAccount)
                .agentId(gameSecretKey.getCode())
                .agentKey(gameSecretKey.getKey())
                .build();
        Boolean result = iGamesService.createMember(gamesBaseRequestDTO);
        Assert.isTrue(result, "建立游戏账号失败");

        List<Member> members = memberService.selectMemberList(Member.builder()
                .tenantKey(tenantSecretKey.getTenantKey()).gameAccount(gameAccount).build());
        if (CollectionUtils.isEmpty(members)) {
            //注册本地账号
            Member member = Member.builder()
                    .tenantKey(tenantSecretKey.getTenantKey())
                    .memberAccount(memberCreateApiRequest.getAccount())
                    .gameAccount(gameAccount)
                    .platformCode(memberCreateApiRequest.getPlatformCode())
                    .currencyCode(memberCreateApiRequest.getCurrencyCode())
                    .build();
            return toAjax(memberService.insertMember(member));
        }
        return toAjax(Boolean.TRUE);

    }


    /**
     * 获取会员信息
     *
     * @param memberInfoApiRequest 成员信息api请求
     * @return {@link AjaxResult }
     */
    @PostMapping("/info")
    public AjaxResult getMemberInfo(@Validated @RequestBody MemberInfoApiRequest memberInfoApiRequest) {
        IGamesService iGamesService = gamesService.get(memberInfoApiRequest.getPlatformCode() + Constants.SERVICE);
        ApiException.notNull(iGamesService, ErrorCode.PLATFORM_NOT_EXIST.getCode());


        TenantSecretKey tenantSecretKey = keyConfig.get();
        GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberInfoApiRequest.getPlatformCode(), memberInfoApiRequest.getCurrencyCode());
        ApiException.notNull(gameSecretKey, ErrorCode.CURRENCY_NOT_EXIST.getCode());

        Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberInfoApiRequest.getAccount(), memberInfoApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
        ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());

        //向第三方查询账号
        MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
                .accounts(member.getGameAccount())
                .agentId(gameSecretKey.getCode())
                .agentKey(gameSecretKey.getKey())
                .build();
        MemberInfoResponseDTO memberInfo = iGamesService.getMemberInfo(gamesBaseRequestDTO);
        MemberInfoResponse memberInfoResponse=new MemberInfoResponse();
        BeanUtils.copyProperties(memberInfo,memberInfoResponse);
        return AjaxResult.success(memberInfoResponse);
    }


    /**
     * 信息全部
     *
     * @param memberInfoAllApiRequest 成员信息所有api请求
     * @return {@link AjaxResult }
     */
    @PostMapping("/info/all")
    public AjaxResult infoAll(@Validated @RequestBody MemberInfoAllApiRequest memberInfoAllApiRequest) {

        TenantSecretKey tenantSecretKey = keyConfig.get();
        Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberInfoAllApiRequest.getAccount(), memberInfoAllApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()));
        ApiException.notNull(member, ErrorCode.ACCOUNT_NOT_EXIST.getCode());


        List<GameSecretKey> gameSecretKeys = gameSecretKeyService.selectGameSecretKeyList(GameSecretKey.builder().systemCode(memberInfoAllApiRequest.getCurrencyCode()).build());


        // 创建线程池
        Map<String, BigDecimal> balanceMap = new LinkedHashMap<>();
        CountDownLatch latch = new CountDownLatch(gameSecretKeys.size());

        // 使用List存储Future对象，用于获取异步执行的结果
        List<Future<MemberInfoAllResponse>> futures = new ArrayList<>();

        // 提交异步任务到线程池
        for (GameSecretKey gameSecretKey : gameSecretKeys) {
            futures.add(threadPoolTaskExecutor.submit(() -> {
                try {
                    IGamesService iGamesService = gamesService.get(gameSecretKey.getPlatform() + Constants.SERVICE);
                    MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder()
                            .accounts(member.getGameAccount())
                            .agentId(gameSecretKey.getCode())
                            .agentKey(gameSecretKey.getKey())
                            .build();
                    //查询余额
                    MemberInfoResponseDTO memberInfo = iGamesService.getMemberInfo(gamesBaseRequestDTO);
                    return MemberInfoAllResponse.builder()
                            .account(member.getGameAccount())
                            .balance(memberInfo.getBalance())
                            .status(memberInfo.getStatus())
                            .platformCode(gameSecretKey.getPlatform())
                            .build();
                } finally {
                    latch.countDown(); // 任务完成后减少计数
                }
            }));
        }


        // 等待所有线程执行完毕
        try {
            latch.await();
            // 获取每个Future的结果
            for (Future<MemberInfoAllResponse> future : futures) {
                // 汇总结果
                MemberInfoAllResponse memberInfoAllResponse = future.get();
                balanceMap.put(memberInfoAllResponse.getPlatformCode(), memberInfoAllResponse.getBalance());
            }
        } catch (Exception e) {
            log.error("获取会员信息失败", e);
            throw new BaseException("获取会员信息失败");
        }


        return AjaxResult.success(balanceMap);
    }




}
