package com.td.boss.game.combosses.controller;

import com.td.boss.common.controller.*;
import com.td.boss.common.pojo.Result;
import com.td.boss.config.enums.ResultEnum;
import com.td.boss.game.combosses.pojo.ComBosses;
import com.td.boss.game.combosses.vo.BossesVo;
import com.td.boss.game.combosses.vo.ComBossesVo;
import com.td.boss.game.combosses.service.ComBossesService;
import com.td.boss.game.combossesbattle.pojo.ComBossesBattle;
import com.td.boss.game.combossesbattle.service.ComBossesBattleService;
import com.td.boss.game.comgeneralattributes.pojo.ComGeneralAttributes;
import com.td.boss.game.comgeneralattributes.service.ComGeneralAttributesService;
import com.td.boss.game.comusers.service.ComUsersService;
import com.td.boss.game.comusers.vo.ComUsersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Date;

@RestController
@RequestMapping("/game/comBosses/")
public class ComBossesController extends CommonController<ComBossesVo, ComBosses, Integer> {
    @Autowired
    private ComBossesService comBossesService;

    @Autowired
    private ComGeneralAttributesService comGeneralAttributesService;

    @Autowired
    private ComBossesBattleService comBossesBattleService;

    @Autowired
    private ComUsersService comUsersService;


    @GetMapping("getTotalKill")
    public Result<Map> getTotalKill(@RequestParam("bossId") Integer bossId) {
        ComBosses comBosses = comBossesService.findById(bossId);
        Map map = new HashMap();
        if (comBosses == null) {
            return Result.of(null, false, ResultEnum.BOSS_DOES_NOT_EXIST.getMessage(), ResultEnum.BOSS_DOES_NOT_EXIST.getCode());
        }
        map.put("totalKill", comBosses.getAllHealth());
        return Result.of(map);
    }

    /**
     * 获取世界boss 属性，后台控制显示
     *
     * @param bossId
     * @return
     */
    @GetMapping("getWorldBossAttribute")
    public Result<Map> getWorldBossAttribute(@RequestParam("bossId") Integer bossId) {
        ComBosses comBosses = comBossesService.findById(bossId);
        Map map = new HashMap();
        if (comBosses == null) {
            return Result.of(null, false, ResultEnum.BOSS_DOES_NOT_EXIST.getMessage(), ResultEnum.BOSS_DOES_NOT_EXIST.getCode());
        }

        map.put("allHealth", comBosses.getAllHealth());
        map.put("restHealth", comBosses.getRestHealth());
        map.put("allTime", comBosses.getAllTime());
        map.put("restTime", comBosses.getRestTime());
        map.put("attributeType", comBosses.getAttributeType());

        return Result.of(map);
    }

    /**
     * 获取战斗中boss属性
     *
     * @param attributeType
     * @return
     */
    @GetMapping("getBattleBossAttribute")
    public Result<ComGeneralAttributes> getBattleBossAttribute(@RequestParam("attributeType") Integer attributeType) {

        ComGeneralAttributes comBosses = comGeneralAttributesService.findByType(attributeType);
        if (comBosses == null) {
            return Result.of(null, false, ResultEnum.BOSS_DOES_NOT_EXIST.getMessage(), ResultEnum.BOSS_DOES_NOT_EXIST.getCode());
        }
        return Result.of(comBosses);
    }

    /**
     * 获取全部 boss 总属性
     *
     * @return
     */
    @GetMapping("getBossAllInfo")
    public Result<List<BossesVo>> getBossAllInfo() {
        List<ComBosses> comBossesList = comBossesService.findAll();
        if (comBossesList.size() == 0) {
            return Result.of(null, false, ResultEnum.BOSS_DOES_NOT_EXIST.getMessage(), ResultEnum.BOSS_DOES_NOT_EXIST.getCode());
        }

        List<BossesVo> bossesVoList = comBossesList.stream().map(e -> {
            BossesVo bossesVo = new BossesVo();
            //获取战斗相关属性
            ComGeneralAttributes generalAttributes = comGeneralAttributesService.findByType(e.getAttributeType());
            bossesVo.setBossesId(e.getId());
            bossesVo.setName(e.getName());
            bossesVo.setAllHealth(e.getAllHealth());
            bossesVo.setRestHealth(e.getRestHealth());
            bossesVo.setAttributes(generalAttributes);
            bossesVo.setEndTime(e.getEndTime());
            bossesVo.setCurrentTime(new Date());
            return bossesVo;
        }).collect(Collectors.toList());

        return Result.of(bossesVoList);
    }

    /**
     * 进入战斗模式
     *
     * @param userId
     * @param playerId
     * @param bossId
     * @return
     */
    @GetMapping("intoCombat")
    @Transactional
    public Result<Map> intoCombat(@RequestParam("userId") String userId,
                                  @RequestParam("playerId") Integer playerId,
                                  @RequestParam("bossId") Integer bossId) {
        //todo 目前用悲观锁处理com_boss的属性问题
        //1.判断用户体力是否充足
        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
        if (comUsersVo.getEnergy() <= 0) {
            return Result.of(null, false, ResultEnum.USER_ENERGY_IS_INSUFFICIENT.getMessage(), ResultEnum.USER_ENERGY_IS_INSUFFICIENT.getCode());
        }

        ComBosses comBosses = comBossesService.findById(bossId);
        if (comBosses == null) {
            return Result.of(null, false, ResultEnum.BOSS_DOES_NOT_EXIST.getMessage(), ResultEnum.BOSS_DOES_NOT_EXIST.getCode());
        }
        if(comBosses.getAllHealth()<0){
            //boss 血量为零且不存在玩家打斗，不用发起战斗
            return Result.of(null, false, ResultEnum.BOSS_HEALTH_IS_ZERO.getMessage(), ResultEnum.BOSS_HEALTH_IS_ZERO.getCode());
        }
        //todo 判断是否过期
        Date currentDate = new Date();
        if (currentDate.after(comBosses.getEndTime())) {
            //如果当前日期大于结束日期
            return Result.of(null, false, ResultEnum.BOSS_BATTLE_EXPIRED.getMessage(), ResultEnum.BOSS_BATTLE_EXPIRED.getCode());
        }
        //判断battle 下面，是否存在相应的战斗状态
        ComBossesBattle playerComBossesBattle = comBossesBattleService.findByPlayerIdAndBossId(playerId,bossId);
        if (playerComBossesBattle == null) {
            //如果新添加战斗的情况下，判断boss剩余血量
            //todo 后面这里要处理一种情况是，boss挑战时间到了。重置boss战斗，可等玩家全部战斗结束后重置，即otherComBossesBattle list为零
            //2.进入格斗，comBoss 表中，即世界boss血量减一，进入战斗状态
            comBosses = comBossesService.intoCombat(bossId);
            playerComBossesBattle = new ComBossesBattle();
            playerComBossesBattle.setCount(0);
            if (comBosses.getAllHealth() < 0) {
                //todo 如果boss血量为0。返回失败信息，比如提示玩家正在战斗中..来判断是否最后击杀boss
                //     判断玩家是否正在战斗中
                List<ComBossesBattle> otherComBossesBattle = comBossesBattleService.findAllByBossesId(bossId);
                if (otherComBossesBattle.size() == 0) {
                    //boss 血量为零且不存在玩家打斗，不用发起战斗
                    return Result.of(null, false, ResultEnum.BOSS_HEALTH_IS_ZERO.getMessage(), ResultEnum.BOSS_HEALTH_IS_ZERO.getCode());
                } else {
                    //todo 如果存在玩家打斗，判断打斗列表是否过期
                    //     获取一个一局战斗过期的数据，来给当前的玩家刷新数据
                    boolean hasBattle = false;
                    for (int i = 0; i < otherComBossesBattle.size(); i++) {
                        ComBossesBattle temp = otherComBossesBattle.get(i);
                        //判断时间，是否过期，还没结束
                        long currentTime = currentDate.getTime();
                        long startTime = temp.getStartTime().longValue();
                        int minutes = (int) ((currentTime - startTime) / (1000 * 60));
                        //如果超过时间的，并且没有完成战斗或者 战斗失败
                        if (minutes > 1 && (temp.getIsBattle() == 0 || temp.getIsState() == 0)) {
                            System.out.println("两个时间之间的分钟差为：" + minutes);
                            //根据战斗状态 重新设置一个playerId,此数据记录为战斗结束
                            temp.setIsBattle(1);//此数据判断完成战斗
                            comBossesBattleService.addComBossesBattle(temp);
                            hasBattle = true;
                            break;
                        }

                    }
                    //如果没有过期数据，提示
                    if (!hasBattle) {
                        return Result.of(null, false, ResultEnum.BOSS_AND_PLAYERS_IN_BATTLE.getMessage(), ResultEnum.BOSS_AND_PLAYERS_IN_BATTLE.getCode());
                    }
                }
            }
            //3.如果boss血量不为零，bosses产生战斗时候，优先给玩家创建一个新战斗数据
            playerComBossesBattle.setPlayerId(playerId);
            playerComBossesBattle.setBossesId(bossId);
        }else if(playerComBossesBattle.getIsState() == 1){
            //如果存在战斗数据，则重新重置boss战斗血量
            comBosses = comBossesService.intoCombat(bossId);
            if(comBosses.getAllHealth()<0){
                //boss 血量为零且不存在玩家打斗，不用发起战斗
                return Result.of(null, false, ResultEnum.BOSS_HEALTH_IS_ZERO.getMessage(), ResultEnum.BOSS_HEALTH_IS_ZERO.getCode());
            }
        }
        //todo 如果playerComBossesBattle本身存在，即战斗数据库更新相应的数据，比如重新开始一场。目前处理相当于reset
        playerComBossesBattle.setIsState(0);
        playerComBossesBattle.setIsBattle(0); //（1:战斗结束，0：战斗持续中）
        playerComBossesBattle.setReduceHp(1);
        playerComBossesBattle.setReduceEnergy(1); //消耗一点体力
        Long timeTemp = System.currentTimeMillis();
        BigInteger bigInt = new BigInteger(timeTemp.toString());
        playerComBossesBattle.setStartTime(bigInt);
        playerComBossesBattle.setCount(playerComBossesBattle.getCount() + 1);
        playerComBossesBattle = comBossesBattleService.addComBossesBattle(playerComBossesBattle);

        //更新体力值
        comUsersVo.setEnergy(comUsersVo.getEnergy() - 1);
        comUsersService.save(comUsersVo);

        //返回部分参数
        Map userMap = new HashMap();
        userMap.put("energy", comUsersVo.getEnergy());
        Map battleStateMap = new HashMap();
        battleStateMap.put("isState", playerComBossesBattle.getIsState());
        battleStateMap.put("isBattle", playerComBossesBattle.getIsBattle());
        battleStateMap.put("reduceHP", playerComBossesBattle.getReduceHp());
        battleStateMap.put("reduceEnergy", playerComBossesBattle.getReduceEnergy());
        battleStateMap.put("startTime", playerComBossesBattle.getStartTime());
        Map map = new HashMap();
        map.put("userInfo", userMap);
        map.put("battleState", battleStateMap);
        return Result.of(map);
    }


    @GetMapping("finishCombat")
    @Transactional
    public Result<Map> finishCombat(@RequestParam("userId") String userId,
                                    @RequestParam("playerId") Integer playerId,
                                    @RequestParam("bossId") Integer bossId) {

        //检测是否有战斗
        ComBossesBattle playerComBossesBattle = comBossesBattleService.findByPlayerIdAndBossId(playerId,bossId);
        if (playerComBossesBattle == null) {
            return Result.of(null, false, ResultEnum.PLAYER_DOES_NOT_ATTRIBUTES.getMessage(), ResultEnum.PLAYER_DOES_NOT_ATTRIBUTES.getCode());
        }
        //如果战斗过期
        Date currentDate = new Date();
        long currentTime = currentDate.getTime();
        long startTime = playerComBossesBattle.getStartTime().longValue();
        int minutes = (int) ((currentTime - startTime) / (1000 * 60));
        //如果超过时间的，并且没有完成战斗或者 战斗失败
        if (minutes > 1) {
            System.out.println("finishCombat 两个时间之间的分钟差为：" + minutes);
            return Result.of(null, false, ResultEnum.BOSS_BATTLE_EXPIRE.getMessage(), ResultEnum.BOSS_BATTLE_EXPIRE.getCode());

        }
        playerComBossesBattle.setIsState(1);
        playerComBossesBattle.setIsBattle(1);
        comBossesBattleService.addComBossesBattle(playerComBossesBattle);
        Map map = new HashMap();
        map.put("isBattle", playerComBossesBattle.getIsBattle());
        return Result.of(map);
    }

}
