package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
import com.yonge.cooleshow.biz.dal.service.SysMessageService;
import com.yonge.cooleshow.biz.dal.service.UserAccountService;
import com.yonge.cooleshow.biz.dal.vo.TeacherEarningVo;
import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yonge.cooleshow.biz.dal.entity.UserAccountRecord;
import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
import com.yonge.cooleshow.biz.dal.dto.search.UserAccountRecordSearch;
import com.yonge.cooleshow.biz.dal.dao.UserAccountRecordDao;
import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;


@Service
public class UserAccountRecordServiceImpl extends ServiceImpl<UserAccountRecordDao, UserAccountRecord> implements UserAccountRecordService {

    private static final Logger log = LoggerFactory.getLogger(UserAccountRecordService.class);

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private CourseScheduleService courseScheduleService;

    @Autowired
    private UserAccountService userAccountService;

    @Override
    public UserAccountRecordVo detail(Long id) {
        UserAccountRecordVo detail = baseMapper.detail(id);
        return detail;
    }

    @Override
    public UserAccountRecordVo detail(String orderNo, AccountBizTypeEnum bizType, Long bizId) {
        UserAccountRecordVo detail = baseMapper.detailByBiz(orderNo, bizType, bizId);
        return detail;
    }

    @Override
    public IPage<UserAccountRecordVo> selectPage(IPage<UserAccountRecordVo> page, UserAccountRecordSearch query) {
        return page.setRecords(baseMapper.selectPage(page, query));
    }

    @Override
    public List<UserAccountRecordVo> selectAll(UserAccountRecordSearch query) {
        return baseMapper.selectAll(query);
    }

    @Override
    public IPage<UserAccountRecordVo> sharePage(IPage<UserAccountRecordVo> page, UserAccountRecordSearch query) {
        return page.setRecords(baseMapper.sharePage(page, query));
    }

    @Override
    public HttpResponseResult<UserAccountVo> accountTotal(UserAccountRecordSearch query) {
        UserAccountVo accountVo = baseMapper.accountTotal(query);
        if (null == accountVo) {
            accountVo = new UserAccountVo();
        }
        accountVo.setAmountUnrecorded(null == accountVo.getAmountUnrecorded() ? BigDecimal.ZERO : accountVo.getAmountUnrecorded());
        accountVo.setAmountRecorded(null == accountVo.getAmountRecorded() ? BigDecimal.ZERO : accountVo.getAmountRecorded());
        accountVo.setAmountTotal(null == accountVo.getAmountTotal() ? BigDecimal.ZERO : accountVo.getAmountTotal());
        accountVo.setAmountUsable(null == accountVo.getAmountUsable() ? BigDecimal.ZERO : accountVo.getAmountUsable());
        accountVo.setAmountFrozen(null == accountVo.getAmountFrozen() ? BigDecimal.ZERO : accountVo.getAmountFrozen());
        return HttpResponseResult.succeed(accountVo);
    }

    @Override
    public void updateWaitRecord() {
        //平台账户修改
        List<String> paramNames = new ArrayList<>();
        paramNames.add(AccountBizTypeEnum.ACTI_REGIST_SHARE.getCode());
        paramNames.add(AccountBizTypeEnum.LIVE_SHARE.getCode());
        paramNames.add(AccountBizTypeEnum.VIDEO.getCode());
        paramNames.add(AccountBizTypeEnum.VIDEO_SHARE.getCode());
        paramNames.add(AccountBizTypeEnum.MUSIC.getCode());
        paramNames.add(AccountBizTypeEnum.MUSIC_SHARE.getCode());
        paramNames.add(AccountBizTypeEnum.ALBUM.getCode());
        paramNames.add(AccountBizTypeEnum.ALBUM_SHARE.getCode());
        paramNames.add(AccountBizTypeEnum.VIP.getCode());
        paramNames.add(AccountBizTypeEnum.VIP_SHARE.getCode());
        List<UserAccountRecord> accountRecords = baseMapper.queryCanAccountByBizType(paramNames);
        for (UserAccountRecord accountRecord : accountRecords) {
            userAccountService.accountChange(accountRecord, PostStatusEnum.RECORDED);
        }
    }

    @Override
    public UserAccountRecordVo appDetail(Long id) {
        UserAccountRecordVo detail = baseMapper.appDetail(id);
        return detail;
    }

    @Override
    public IPage<UserAccountRecordVo> appSelectPage(IPage<UserAccountRecordVo> page, UserAccountRecordSearch query) {
        return page.setRecords(baseMapper.appSelectPage(page, query));
    }

    @Override
    public BigDecimal getMonthDecimal(Long userId) {
        return baseMapper.selectMonthDecimal(userId);
    }

    @Override
    public void sendTeacherEarning() {
        List<TeacherEarningVo> teacherEarningVoList = baseMapper.selectTodayTeacherEarning();
        if (CollectionUtils.isEmpty(teacherEarningVoList)) {
            return;
        }
        for (TeacherEarningVo teacherEarningVo : teacherEarningVoList) {
            Map<Long, String> receivers = new HashMap<>();
            String url = sysMessageService.selectConfigUrl(MessageTypeEnum.COURSE_SETTLEMENT.getCode());
            receivers.put(teacherEarningVo.getTeacherId(), teacherEarningVo.getTeacherPhone());
            String dateString = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            try {
                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.COURSE_SETTLEMENT,
                        receivers, null, 0, url, ClientEnum.TEACHER.getCode(), dateString);
                log.info(" COURSE_SETTLEMENT ok");
            } catch (Exception e) {
                log.warn("老师课酬结算消息推送失败，{}", e.getMessage());
            }
        }
    }


    @Override
    public List<UserAccountRecord> selectRecordByOrderDetail(UserOrderDetailVo userOrderDetailVo) {
        List<UserAccountRecord> records = new ArrayList<>();
        //订单类型: 学生端（ VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ） 老师端（VIP、开通会员 PINAO_ROOM、琴房时长）
        //获取业务id
        List<Long> bizIds = new ArrayList<>();
        if (GoodTypeEnum.VIP.equals(userOrderDetailVo.getGoodType())){
            bizIds.add(userOrderDetailVo.getBizId());
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP, bizIds));
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP_SHARE, bizIds));
        }else if(GoodTypeEnum.VIDEO.equals(userOrderDetailVo.getGoodType())){
            bizIds.add(userOrderDetailVo.getBizId());
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIDEO, bizIds));
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIDEO_SHARE, bizIds));
        }else if(GoodTypeEnum.MUSIC.equals(userOrderDetailVo.getGoodType())){
            bizIds.add(userOrderDetailVo.getBizId());
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.MUSIC, bizIds));
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.MUSIC_SHARE, bizIds));
        }else if(GoodTypeEnum.PRACTICE.equals(userOrderDetailVo.getGoodType())){
            //查询课程组下所有课程id
            List<CourseSchedule> cancel = courseScheduleService.list(Wrappers.<CourseSchedule>lambdaQuery()
                    .eq(CourseSchedule::getCourseGroupId, userOrderDetailVo.getBizId())
            );
            cancel.stream().forEach(o -> bizIds.add(o.getId()));
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.PRACTICE, bizIds));
        }else if(GoodTypeEnum.LIVE.equals(userOrderDetailVo.getGoodType())){
            List<Long> groupId = Arrays.asList(userOrderDetailVo.getBizId());
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.LIVE_SHARE, groupId));
            //查询课程组下所有课程id
            List<CourseSchedule> cancel = courseScheduleService.list(Wrappers.<CourseSchedule>lambdaQuery()
                    .eq(CourseSchedule::getCourseGroupId, userOrderDetailVo.getBizId())
            );
            cancel.stream().forEach(o -> bizIds.add(o.getId()));
            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.LIVE, bizIds));
        }
        return records;
    }

}