package cn.wisenergy.service.common;

import cn.wisenergy.common.utils.R;
import cn.wisenergy.common.utils.StringUtil;
import cn.wisenergy.mapper.*;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.enums.CardStatus;
import cn.wisenergy.model.enums.OperationTypeEnum;
import cn.wisenergy.model.enums.PayType;
import cn.wisenergy.model.enums.SchemeTypeEnums;
import cn.wisenergy.model.vo.AddLimitVo;
import cn.wisenergy.model.vo.UserInfoVo;
import cn.wisenergy.service.app.UserLimitService;
import cn.wisenergy.service.app.UserVolunteerService;
import cn.wisenergy.service.app.VolunteerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 86187
 * @ Description: 事务方法公共类
 * @ Author     : 86187
 * @ Date       : 2021/1/28 15:59
 */
@Component
@Slf4j
public class VolunteerManager {

    @Autowired
    private UserLimitMapper userLimitMapper;

    @Autowired
    private UserLimitRecordMapper userLimitRecordMapper;

    @Autowired
    private CardMapper cardMapper;

    @Autowired
    private PayRecordMapper payRecordMapper;

    @Autowired
    private SchemeRecordMapper schemeRecordMapper;

    @Autowired
    private UserVolunteerService userVolunteerService;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private StaffUserVipMapper staffUserVipMapper;

    @Autowired
    private ScoreInfoMapper scoreInfoMapper;

    @Autowired
    private SchemeMapper schemeMapper;

    @Autowired
    private VolunteerService volunteerService;

    @Autowired
    private VolunteerMapper volunteerMapper;

    @Autowired
    private UserLimitService userLimitService;

    @Autowired
    private LoginRecordMapper loginRecordMapper;

    /**
     * 错误码
     */
    private static final int ERROR_CODE = 1;

    /**
     * 副科是六选三科
     */
    private static final int CLASS_COUNT = 3;

    /**
     * 更新用户查询信息并保存扣减记录
     *
     * @param userLimit 查询信息
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLimitSaveRecord(UserLimit userLimit) {
        //1、更新查询信息
        int count = userLimitMapper.edit(userLimit);
        if (count == 0) {
            return false;
        }

        //2、保存扣减记录
        UserLimitRecord userLimitRecord = new UserLimitRecord();
        userLimitRecord.setMinusLimit(1);
        userLimitRecord.setUserLimitId(userLimit.getId());
        userLimitRecord.setUserId(userLimit.getUserId());
        int record = userLimitRecordMapper.add(userLimitRecord);

        if (record == 0) {
            return false;
        }
        return true;
    }

    /**
     * 更新充值卡状态和用户查询次数及增加充值记录
     *
     * @param cardInfo   充值卡信息
     * @param userLimit  用户查询次数信息
     * @param addLimitVo 接口入参
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLimitAndRecord(Price price, CardInfo cardInfo, UserLimit userLimit, AddLimitVo addLimitVo) {

        //是充值卡
        if (PayType.REFILL_CARD.getCode().equals(addLimitVo.getPayType())) {
            //1、更新充值卡状态
            cardInfo.setStatus(CardStatus.ALREADY_USED.getCode());
            int count = cardMapper.edit(cardInfo);
            if (count == 0) {
                return false;
            }

            //2、更新用户查询次数信息
            int limit = userLimitMapper.edit(userLimit);
            if (limit == 0) {
                return false;
            }

            //3、保存充值记录
            PayRecord payRecord = new PayRecord();
            payRecord.setCardId(cardInfo.getId());
            payRecord.setMoney(Integer.valueOf(cardInfo.getMoney()));
            payRecord.setPayLimit(cardInfo.getLimit());
            payRecord.setResult(0);
            payRecord.setType(addLimitVo.getPayType());
            payRecord.setUserId(addLimitVo.getUserId());
            int pay = payRecordMapper.add(payRecord);
            if (pay == 0) {
                return false;
            }
        } else {
            //1、更新用户查询次数信息
            int limit = userLimitMapper.edit(userLimit);
            if (limit == 0) {
                return false;
            }

            //2、保存充值记录
            PayRecord payRecord = new PayRecord();
            payRecord.setCardId(null);
            payRecord.setMoney(addLimitVo.getPayMoney());
            payRecord.setPayLimit(price.getUseLimit());
            payRecord.setResult(0);
            payRecord.setType(addLimitVo.getPayType());
            payRecord.setUserId(addLimitVo.getUserId());
            payRecord.setTradeNo(addLimitVo.getTradeNo());
            QueryWrapper<PayRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("trade_no", payRecord.getTradeNo());
            PayRecord byTradeNo = payRecordMapper.selectOne(queryWrapper);
            int pay = 0;
            if (null != byTradeNo) {
                pay = payRecordMapper.updateById(payRecord);
            } else {
                pay = payRecordMapper.add(payRecord);
            }
            if (pay == 0) {
                return false;
            }
        }

        return true;
    }

    /**
     * 保存方案查询记录和关联关系
     *
     * @param user 用户信息
     * @param list 志愿信息
     * @return true 成功  false 失败
     */
    @Transactional(rollbackFor = Exception.class)
    public R<Integer> saveUserVolunteer(User user, List<Volunteer> list, ScoreInfo scoreInfo, String name) {
        //1、保存方案查询记录
        SchemeQueryRecord schemeQueryRecord = new SchemeQueryRecord();
        schemeQueryRecord.setMajorName(name);
        schemeQueryRecord.setStudentType(user.getExamType());
        schemeQueryRecord.setUserId(user.getId());
        schemeQueryRecord.setIsDelete(0);
        if (null == scoreInfo.getMajorGrade()) {
            schemeQueryRecord.setMajorScore("0");
        } else {
            schemeQueryRecord.setMajorScore(scoreInfo.getMajorGrade().toString());
        }
        schemeQueryRecord.setScore(scoreInfo.getCultureGrade().toString());

        List<Integer> ids = list.stream().map(Volunteer::getId).collect(Collectors.toList());
        //保存方案查询记录
        int count = schemeRecordMapper.add(schemeQueryRecord);
        if (count == 0) {
            return R.error("保存方案查询记录失败!");
        }

        List<UserVolunteer> volunteerList = new ArrayList<>();
        for (Integer id : ids) {
            UserVolunteer userVolunteer = new UserVolunteer();
            userVolunteer.setSchemeRecordId(schemeQueryRecord.getId());
            userVolunteer.setUserId(user.getId());
            userVolunteer.setVolunteerId(id);
            volunteerList.add(userVolunteer);
        }

        //调用扣减查询次数接口
        R<Boolean> result = userLimitService.minusLimit(user.getId());
        if (null != result && result.getCode() == ERROR_CODE) {
            return R.error("扣减查询次数失败!");
        }

        //保存方案志愿关联关系
        boolean bool = userVolunteerService.saveBatch(volunteerList);
        if (!bool) {
            return R.error("保存方案志愿关联关系失败!");
        }
        return R.ok(schemeQueryRecord.getId());
    }

    /**
     * 保存方案查询记录和关联关系
     *
     * @param user 用户信息
     * @param list 志愿信息
     * @return true 成功  false 失败
     */
    @Transactional(rollbackFor = Exception.class)
    public R<Integer> saveUserVolunteerVip(User user, List<Volunteer> list, ScoreInfo scoreInfo, String name) {
        //1、保存方案查询记录
        SchemeQueryRecord schemeQueryRecord = new SchemeQueryRecord();
        schemeQueryRecord.setMajorName(name);
        schemeQueryRecord.setStudentType(user.getExamType());
        schemeQueryRecord.setUserId(user.getId());
        schemeQueryRecord.setIsDelete(0);
        if (null == scoreInfo.getMajorGrade()) {
            schemeQueryRecord.setMajorScore("0");
        } else {
            schemeQueryRecord.setMajorScore(scoreInfo.getMajorGrade().toString());
        }
        schemeQueryRecord.setScore(scoreInfo.getCultureGrade().toString());

        List<Integer> ids = list.stream().map(Volunteer::getId).collect(Collectors.toList());
        //保存方案查询记录
        int count = schemeRecordMapper.add(schemeQueryRecord);
        if (count == 0) {
            return R.error("保存方案查询记录失败!");
        }

        //调用扣减查询次数接口
        R<Boolean> result = userLimitService.minusLimit(user.getId());
        if (null != result && result.getCode() == ERROR_CODE) {
            return R.error("扣减查询次数失败!");
        }
        return R.ok(schemeQueryRecord.getId());
    }

    /**
     * 保存个人信息
     *
     * @param user      用户信息
     * @param scoreInfo 成绩信息
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAndSaveUserInfo(User user, ScoreInfo scoreInfo, Integer flag) {
        //1、更新用户信息
        int count = usersMapper.edit(user);
        if (count == 0) {
            return false;
        }

        //2、保存用户成绩信息
        if (null == scoreInfo.getMajorGrade()) {
            scoreInfo.setMajorGrade(0.00);
        }

        //flag =1  添加
        if (null != flag && flag == 1) {
            int save = scoreInfoMapper.add(scoreInfo);
            if (save == 0) {
                return false;
            }
        }

        //flag =2  编辑
        if (null != flag && flag == 2) {
            int edit = scoreInfoMapper.edit(scoreInfo);
            if (edit == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 保存vip个人信息
     *
     * @param user      用户信息
     * @param scoreInfo 成绩信息
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAndSaveUserVipInfo(User user, ScoreInfo scoreInfo, Integer flag, Integer staffId) {

        //添加vip客户信息
        //1、更新用户信息
        int count = usersMapper.edit(user);
        if (count == 0) {
            return false;
        }

        //2、保存用户成绩信息
        if (null == scoreInfo.getMajorGrade()) {
            scoreInfo.setMajorGrade(0.00);
        }

        //flag =1  添加
        if (null != flag && flag == 1) {
            int save = scoreInfoMapper.add(scoreInfo);
            if (save == 0) {
                return false;
            }
        }

        //flag =2  编辑
        if (null != flag && flag == 2) {
            int edit = scoreInfoMapper.edit(scoreInfo);
            if (edit == 0) {
                return false;
            }
        }

        //绑定vip客户与员工的关系
        StaffUserVip staffUserVip = new StaffUserVip();
        staffUserVip.setStaffId(staffId);
        staffUserVip.setUserVipId(user.getId());
        staffUserVip.setIsDelete(0);
        int add = staffUserVipMapper.add(staffUserVip);

        //判断数据是否添加成功
        if (add == 0) {
            return false;
        }
        return true;
    }

    /**
     * 编辑个人信息
     *
     * @param user      用户信息
     * @param scoreInfo 成绩信息
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAndUserInfo(User user, ScoreInfo scoreInfo) {
        //1、更新用户信息
        int count = usersMapper.edit(user);
        if (count == 0) {
            return false;
        }

        //2、保存用户成绩信息
        int save = scoreInfoMapper.edit(scoreInfo);
        if (save == 0) {
            return false;
        }

        return true;
    }

    /**
     * 保存方案和志愿信息
     *
     * @param schemeInfo 方案信息
     * @param list       志愿信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveSchemeAndVolunteer(SchemeInfo schemeInfo, List<Volunteer> list) {
        //1、保存方案信息
        int count = schemeMapper.add(schemeInfo);
        if (count == 0) {
            throw new RuntimeException("保存方案信息失败!");
        }

        //保存志愿信息
        for (Volunteer volunteer : list) {
            volunteer.setSchemeId(schemeInfo.getId());
            volunteer.setType(schemeInfo.getType());
            if (!SchemeTypeEnums.UNDERGRADUATE_CULTURE.getCode().equals(volunteer.getType()) ||
                    !SchemeTypeEnums.JUNIOR_COLLEGE_MAJOR.getCode().equals(volunteer.getType())) {
                volunteer.setLowestRank(null);
            }
        }
        boolean bool = volunteerService.saveBatch(list);
        if (!bool) {
            throw new RuntimeException("保存志愿信息失败!");
        }
    }

    /**
     * 删除方案志愿
     *
     * @param schemeInfo 方案信息
     * @param schemeId   方案id
     * @param size       志愿数据条数
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSchemeAndVolunteer(SchemeInfo schemeInfo, Integer schemeId, Integer size) {
        //更行方案状态为删除
        int sum = schemeMapper.edit(schemeInfo);
        if (sum == 0) {
            return false;
        }


        //更行志愿状态为删除
        int count = volunteerMapper.updateBySchemeId(schemeId);
        if (size != count) {
            return false;
        }

        return true;
    }

    /**
     * 检查成绩信息
     *
     * @param scoreInfo 成绩
     * @return true or false
     */
    public R<Boolean> checkScore(ScoreInfo scoreInfo) {
        int count = 0;
        if (null != scoreInfo.getPoliticsGrade()) {
            count = count + 1;
        }
        if (null != scoreInfo.getHistoryGrade()) {
            count = count + 1;
        }
        if (null != scoreInfo.getBiologyGrade()) {
            count = count + 1;
        }
        if (null != scoreInfo.getChemistryGrade()) {
            count = count + 1;
        }
        if (null != scoreInfo.getPhysicsGrade()) {
            count = count + 1;
        }
        if (null != scoreInfo.getGeographyGrade()) {
            count = count + 1;
        }

        if (count > CLASS_COUNT) {
            return R.error(1, "只能填三科副科成绩", false);
        }
        return R.ok(0, true);
    }

    /**
     * 保存用户注册信息,初始化查询次数信息,注册、登录操作信息
     *
     * @param phone  手机
     * @param secret 密码
     * @param source 来源
     * @return 结果
     */
    @Transactional
    public R<UserInfoVo> saveUserAndLimit(String phone, String secret, Integer source) {
        //1、添加用户信息
        User userInfo = new User();
        userInfo.setPhone(phone);
        userInfo.setPassword(secret);
        userInfo.setIsDelete(0);
        userInfo.setSource(source);

        int count = usersMapper.add(userInfo);
        if (count == 0) {
            return R.error("考生注册失败!");
        }

        //2、保存用户查询信息
        UserLimit addLimit = new UserLimit();
        addLimit.setUserId(userInfo.getId());
        addLimit.setUseLimit(0);
        addLimit.setUsableLimit(0);
        addLimit.setTotalLimit(0);
        int limit = userLimitMapper.add(addLimit);
        if (limit == 0) {
            return R.error("注册添加用户查询信息失败!");
        }

        //3、保存注册记录
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setType(OperationTypeEnum.USER_REGISTER.getCode());
        loginRecord.setUserId(userInfo.getId());
        String name = OperationTypeEnum.getByCode(OperationTypeEnum.USER_REGISTER.getCode());
        loginRecord.setOperationName(name);
        int record = loginRecordMapper.add(loginRecord);
        if (record == 0) {
            return R.error("保存注册记录失败!");
        }

        //3、保存登录记录
        LoginRecord login = new LoginRecord();
        login.setType(OperationTypeEnum.USER_LOGIN.getCode());
        login.setUserId(userInfo.getId());
        String nameSecond = OperationTypeEnum.getByCode(OperationTypeEnum.USER_LOGIN.getCode());
        login.setOperationName(nameSecond);
        int number = loginRecordMapper.add(login);
        if (number == 0) {
            return R.error("保存登录记录失败!");
        }

        //7、封装返回参数
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setUserId(userInfo.getId());
        userInfoVo.setPhone(userInfo.getPhone());
        return R.ok(0, userInfoVo);
    }
}