package com.ytpm.middle.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.ytpm.agent.model.YtPlatformUserApp;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.ResultTable;
import com.ytpm.handle.CustomerException;
import com.ytpm.middle.dao.AgentMapper;
import com.ytpm.middle.dao.AppMapper;
import com.ytpm.middle.dao.EnterpriseMapper;
import com.ytpm.middle.dao.FinanceMapper;
import com.ytpm.middle.model.YtFinancePayment;
import com.ytpm.middle.model.YtFinancePaymentRecord;
import com.ytpm.middle.model.YtMiddleEnterprise;
import com.ytpm.middle.param.AgentBaseInfoParam;
import com.ytpm.middle.param.AgentForm;
import com.ytpm.middle.service.AgentService;
import com.ytpm.middle.util.RedisUtil;
import com.ytpm.middle.util.TencentSmsUtil;
import com.ytpm.middle.view.AgentBaseInfoListVO;
import com.ytpm.middle.view.FinancePaymentItemVO;
import com.ytpm.oauth.model.YtPlatformUser;
import com.ytpm.util.IDUtil;
import com.ytpm.util.RandomPasswordGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RefreshScope
@Slf4j(topic = "代理商业务")
public class AgentServiceImpl implements AgentService {

    @Resource
    private AgentMapper agentMapper;
    @Resource
    private EnterpriseMapper enterpriseMapper;
    @Resource
    private TencentSmsUtil smsUtil;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private AppMapper appMapper;
    @Resource
    private FinanceMapper financeMapper;

    @Value("${tencent.sms.registryTemplateId}")
    private String registryTemplateId;

    @Value("${tencent.sms.resetTemplateId}")
    private String resetTemplateId;
    @Value("${agent.app.amountItemId}")
    private String agentAppAmountItemId;
    @Value("${agent.app.softItemId}")
    private String agentAppSoftItemId;
    @Value("${agent.app.dataItemId}")
    private String agentAppDataItemId;
    @Value("${agent.app.softFastItemId}")
    private String agentAppSoftFastItemId;
    /**
     * 渠道商基本信息列表
     */
    @Override
    public ResultTable<AgentBaseInfoListVO> getBaseInfoList(AgentBaseInfoParam param) {
        PageHelper.startPage(param.getPage(), param.getLimit());
        List<AgentBaseInfoListVO> vos = agentMapper.getBaseInfoList(param);
        if(CollUtil.isEmpty(vos)){
            return ResultTable.resultTableOk(new PageInfo<AgentBaseInfoListVO>(vos));
        }
        String userIds = vos.stream().map(AgentBaseInfoListVO::getUserId).collect(Collectors.joining(","));
        //查询企业用户是否存在授权的包，存在则显示重置密码
        List<YtPlatformUserApp> apps =  appMapper.getAppListByUserIds(userIds);
        Map<String, List<YtPlatformUserApp>> userAppMap = apps.stream().collect(Collectors.groupingBy(YtPlatformUserApp::getUserId));
        for (AgentBaseInfoListVO vo : vos) {
            vo.setShowResetPwd(CollUtil.isNotEmpty(userAppMap.get(vo.getUserId())));
        }
        return ResultTable.resultTableOk(new PageInfo<AgentBaseInfoListVO>(vos));
    }

    /**
     * 新增渠道商
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> addOne(AgentForm form) {
        //根据企业信用代码查询公司是否已存在
        YtMiddleEnterprise old = enterpriseMapper.getByCode(form.getCreditCode());
        if(Objects.nonNull(old)) {
            return Result.resultErr(RepMessage.OBJECT_ALREADY_EXIST);
        }
        String accountId = IDUtil.generateFlowID("yt_agent_");
        generateLoginAccount(form,accountId);
        addEnterprise(form,accountId);
        //根据企业类型创建缴费单
        generatePayment(form,accountId);
        return Result.resultOk(RepMessage.ADD_SUCCESS);
    }

    /**
     * 生成企业缴费单信息
     * 1、默认生成流量费 1200
     * 2、默认生成软著费用 400
     */
    private void generatePayment(AgentForm form, String accountId) {
        String paymentId = IDUtil.generateFlowID("bill_");
        BigDecimal totalAmount = BigDecimal.ZERO;
        
        List<FinancePaymentItemVO> vos = financeMapper.findByItemIds(Arrays.asList(agentAppAmountItemId,agentAppSoftItemId,agentAppDataItemId,agentAppSoftFastItemId));
        Map<String, FinancePaymentItemVO> itemMap = vos.stream().collect(Collectors.toMap(s -> s.getItemId(), o -> o));
        //缴费单生产未缴费记录
        YtFinancePaymentRecord record = new YtFinancePaymentRecord();
        //加急或普通软著费
        FinancePaymentItemVO vo = itemMap.get(form.getHasFast() == 1?agentAppSoftFastItemId:agentAppSoftItemId);
        record.setPaymentId(paymentId);
        record.setUserId(accountId);
        record.setItemId(vo.getItemId());
        record.setShouldAmount(vo.getItemAmount());
        record.setRecordId(IdUtil.fastSimpleUUID());
        financeMapper.addPaymentRecord(record);
        totalAmount = totalAmount.add(record.getShouldAmount());
        //1200流量费
        vo = itemMap.get(agentAppDataItemId);
        record = new YtFinancePaymentRecord();
        record.setPaymentId(paymentId);
        record.setUserId(accountId);
        record.setItemId(vo.getItemId());
        record.setShouldAmount(vo.getItemAmount());
        record.setRecordId(IdUtil.fastSimpleUUID());
        financeMapper.addPaymentRecord(record);
        totalAmount = totalAmount.add(record.getShouldAmount());
        //APP售价
        vo = itemMap.get(agentAppAmountItemId);
        record = new YtFinancePaymentRecord();
        record.setPaymentId(paymentId);
        record.setUserId(accountId);
        record.setItemId(vo.getItemId());
        record.setShouldAmount(vo.getItemAmount());
        record.setRecordId(IdUtil.fastSimpleUUID());
        financeMapper.addPaymentRecord(record);
        totalAmount = totalAmount.add(record.getShouldAmount());
        //生成缴费单
        YtFinancePayment payment = new YtFinancePayment();
        payment.setPaymentId(paymentId);
        payment.setPaymentNo(redisUtil.generateOrderNo("payment_"));
        payment.setTotalAmount(totalAmount);
        payment.setPaymentType(1);
        payment.setUserId(accountId);
        payment.setDefaultParam(form.getCreateUserId());
        financeMapper.addPayment(payment);
    }

    /**
     * 修改代理商
     */
    @Override
    public Result<String> updateOne(AgentForm form) {
        YtMiddleEnterprise old = enterpriseMapper.getByCode(form.getCreditCode());
        if(Objects.isNull(old)) {
            return Result.resultOk(RepMessage.OBJECT_NOT_EXIST);
        }
        YtMiddleEnterprise enterprise = new YtMiddleEnterprise();
        BeanUtil.copyProperties(form, enterprise);
        enterpriseMapper.updateById(enterprise);
        return Result.resultOk(RepMessage.MODIFY_SUCCESS);
    }

    /**
     * 启用或禁用
     */
    @Override
    public Result<String> enabled(String creditCode, String userId) {
        YtMiddleEnterprise old = enterpriseMapper.getByCode(creditCode);
        if(Objects.isNull(old)) {
            return Result.resultOk(RepMessage.OBJECT_NOT_EXIST);
        }
        YtMiddleEnterprise enterprise = new YtMiddleEnterprise();
        enterprise.setEnterpriseId(old.getEnterpriseId());
        enterprise.setAvailable(old.getAvailable()==1?0:1);
        enterprise.setUpdateParam(userId);
        enterpriseMapper.updateById(enterprise);
        return Result.resultOk(RepMessage.MODIFY_SUCCESS);
    }
    /**
     * 重置密码
     */
    @Override
    public Result<String> resetPwd(String creditCode) {
        YtMiddleEnterprise old = enterpriseMapper.getByCode(creditCode);
        if(Objects.isNull(old)) {
            return Result.resultOk(RepMessage.OBJECT_NOT_EXIST);
        }
        String generatedPassword = RandomPasswordGenerator.generatePassword(8);
        System.err.println("您申请的密码重置已通过，您新的密码为："+generatedPassword);
        agentMapper.resetPwd(old.getUserId(),new BCryptPasswordEncoder().encode(generatedPassword));
        //短信通知企业负责人重置后的密码
        try {
            smsUtil.sendLoginPwd(old.getConcatPhone(), generatedPassword,resetTemplateId);
        } catch (TencentCloudSDKException e) {
            throw new CustomerException(e.getMessage());
        }
        return Result.resultOk(RepMessage.RESET_SUCCESS);
    }

    /**
     * 企业信息新增操作
     */
    private void addEnterprise(AgentForm form, String accountId) {
        YtMiddleEnterprise enterprise = new YtMiddleEnterprise();
        BeanUtil.copyProperties(form, enterprise);
        enterprise.setUserId(accountId);
        enterprise.setCreateTime(new Date());
        enterprise.setCreateUserId(form.getCreateUserId());
        enterprise.setAvailable(1);
        enterpriseMapper.insertOne(enterprise);
    }

    /**
     * 生成登录账号
     */
    private void generateLoginAccount(AgentForm form, String accountId) {
        //根据登录名生成登录账号
        YtPlatformUser user = new YtPlatformUser();
        user.setNickName(form.getEnterpriseName());
        user.setLoginName(form.getLoginName());
        String generatedPassword = RandomPasswordGenerator.generatePassword(8);
        log.error("创建用户成功，您本次的登录密码为：{}", generatedPassword);
        user.setEncryptPwd(new BCryptPasswordEncoder().encode(generatedPassword));
        user.setPhone(form.getConcatPhone());
        user.setLastLoginTime(new Date());
        user.setUserType(form.getUserType());
        user.setRegistryTime(new Date());
        user.setUserId(accountId);
        user.setAccountStatus(1);
        agentMapper.addOneUser(user);
        //缓存企业负责人电话：账号密码
        redisUtil.setTimeOutMinutesStr(form.getConcatPhone(), generatedPassword, 30);
//        try {
//            smsUtil.sendLoginPwd(form.getConcatPhone(), generatedPassword,registryTemplateId);
//        } catch (TencentCloudSDKException e) {
//            throw new CustomerException(e.getMessage());
//        }
    }
}
