package com.fs.company.service.impl;

import cn.hutool.json.JSONUtil;
import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.fs.company.domain.*;
import com.fs.company.mapper.*;
import com.fs.company.param.CompanyParam;
import com.fs.company.service.ICompanyService;
import com.fs.company.vo.CompanyCrmVO;
import com.fs.company.vo.CompanyNameVO;
import com.fs.company.vo.CompanyVO;
import com.fs.company.vo.DeptDataVO;
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
import com.fs.his.vo.OptionsVO;
import com.fs.store.config.StoreConfig;
import com.fs.store.domain.FsStoreOrder;
import com.fs.store.domain.FsStorePayment;
import com.fs.store.mapper.FsStoreOrderMapper;
import com.fs.system.service.ISysConfigService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企业Service业务层处理
 *
 * @author fs
 * @date 2021-10-04
 */
@Service
public class CompanyServiceImpl implements ICompanyService
{
    Logger logger= LoggerFactory.getLogger(getClass());
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private CompanyDeptMapper deptMapper;

    @Autowired
    private CompanyRoleMapper roleMapper;
    @Autowired
    private CompanyPostMapper postMapper;
    @Autowired
    private CompanyUserMapper userMapper;
    @Autowired
    private CompanyUserRoleMapper userRoleMapper;
    @Autowired
    private CompanyUserPostMapper userPostMapper;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private CompanyMoneyLogsMapper moneyLogsMapper;
    @Autowired
    private FsStoreOrderMapper storeOrderMapper;
    @Autowired
    private FsCourseRedPacketLogMapper courseRedPacketLogMapper;

    @Autowired
    private CompanyDeptMapper companyDeptMapper;

    @Autowired
    private CompanyUserMapper companyUserMapper;


    @Override
    public List<OptionsVO> selectAllCompanyList() {
        return companyMapper.selectAllCompanyList();
    }
    /**
     * 查询企业
     *
     * @param companyId 企业ID
     * @return 企业
     */
    @Override
    public Company selectCompanyById(Long companyId)
    {
        return companyMapper.selectCompanyById(companyId);
    }

    /**
     * 查询企业列表
     *
     * @param company 企业
     * @return 企业
     */
    @Override
    public List<Company> selectCompanyList(Company company)
    {
        return companyMapper.selectCompanyList(company);
    }

    /**
     * 新增企业
     *
     * @param company 企业
     * @return 结果
     */
    @Override
    @Transactional
    public R insertCompany(Company company)
    {
        //帐号是否存在
        if(userMapper.checkUserName(company.getUserName())>0){
            return R.error("帐号已存在");
        }
        company.setCreateTime(DateUtils.getNowDate());
        if(companyMapper.insertCompany(company)>0){
            //写入帐号信息
            //创建部门
            CompanyDept dept=new CompanyDept();
            dept.setCompanyId(company.getCompanyId());
            dept.setParentId(0l);
            dept.setAncestors("0");
            dept.setStatus("0");
            dept.setCreateTime(new Date());
            dept.setDeptName(company.getCompanyName());
            deptMapper.insertCompanyDept(dept);

            // 创建默认部门
            CompanyDept defaultDept = new CompanyDept();
            defaultDept.setCompanyId(company.getCompanyId());
            defaultDept.setParentId(dept.getDeptId());
            defaultDept.setAncestors("0," + dept.getDeptId());
            defaultDept.setStatus("0");
            defaultDept.setCreateTime(new Date());
            defaultDept.setDeptName("默认");
            deptMapper.insertCompanyDept(defaultDept);

            //创建岗位
            CompanyPost post=new CompanyPost();
            post.setCompanyId(company.getCompanyId());
            post.setPostCode("manager");
            post.setPostName("管理员");
            post.setPostSort(0);
            post.setStatus("0");
            postMapper.insertCompanyPost(post);
            //创建角色
            CompanyRole role=new CompanyRole();
            role.setCompanyId(company.getCompanyId());
            role.setRoleName("管理员");
            role.setRoleKey("admin");
            role.setRoleSort(0);
            role.setStatus("0");
            roleMapper.insertCompanyRole(role);
            //添加用户
            CompanyUser user=new CompanyUser();
            user.setCompanyId(company.getCompanyId());
            user.setNickName("管理员");

            user.setPassword(company.getPassword());
            user.setUserName(company.getUserName());

            user.setDeptId(dept.getDeptId());
            user.setUserType("00");
            user.setPhonenumber(company.getCompanyMobile());
            user.setSex("0");
            user.setStatus("0");
            user.setIsDel(0);
            user.setIsAudit(1);
            userMapper.insertCompanyUser(user);
            //添加用户角色表
            CompanyUserRole userRole=new CompanyUserRole();
            userRole.setRoleId(role.getRoleId());
            userRole.setUserId(user.getUserId());
            userRoleMapper.insertCompanyUserRole(userRole);
            //添加用户岗位表
            CompanyUserPost userPost=new CompanyUserPost();
            userPost.setPostId(post.getPostId());
            userPost.setUserId(user.getUserId());
            userPostMapper.insertCompanyUserPost(userPost);
            company.setUserId(user.getUserId());
            companyMapper.updateCompany(company);

            return R.ok();
        }
        else
        {
            return R.error("操作失败");
        }
    }

    /**
     * 修改企业
     *
     * @param company 企业
     * @return 结果
     */
    @Override
    public int updateCompany(Company company)
    {
        company.setUpdateTime(DateUtils.getNowDate());
        return companyMapper.updateCompany(company);
    }

    /**
     * 批量删除企业
     *
     * @param companyIds 需要删除的企业ID
     * @return 结果
     */
    @Override
    public int deleteCompanyByIds(Long[] companyIds)
    {
        return companyMapper.deleteCompanyByIds(companyIds);
    }

    /**
     * 删除企业信息
     *
     * @param companyId 企业ID
     * @return 结果
     */
    @Override
    public int deleteCompanyById(Long companyId)
    {
        return companyMapper.deleteCompanyById(companyId);
    }

    @Override
    public List<CompanyVO> selectCompanyVOList(CompanyParam param) {
        return companyMapper.selectCompanyVOList(param);
    }

    @Override
    public List<CompanyNameVO> selectCompanyNameVOList(CompanyParam param) {
        return companyMapper.selectCompanyNameVOList(param);
    }

    @Override
    public List<CompanyCrmVO> selectCompanyCrmDayCountList(CompanyParam param) {
        return companyMapper.selectCompanyCrmDayCountList(param);
    }

    @Override
    public Integer selectCompanyCount() {
        return companyMapper.selectCompanyCount();
    }

    @Override
    @Transactional
    public void addCompanyTuiMoney(FsStoreOrder order) {
        if(order.getCompanyId()!=null&&order.getCompanyId()>0){
            Company company=companyMapper.selectCompanyByIdForUpdate(order.getCompanyId());
            if(company!=null){
                String json =configService.selectConfigByKey("store.config");
                StoreConfig config= JSONUtil.toBean(json,StoreConfig.class);
                //支付金额-（订单金额*rate%）
                Double rate=config.getTuiMoneyRate()/100d;
                BigDecimal tuiMoney=order.getPayPrice().subtract(order.getTotalPrice().multiply(new BigDecimal(rate)));
                logger.info("写入公司推广佣金:"+tuiMoney);
                company.setTuiMoney(company.getTuiMoney().add(tuiMoney));
                companyMapper.updateCompany(company);
                FsStoreOrder storeOrderMap=new FsStoreOrder();
                storeOrderMap.setId(order.getId());
                storeOrderMap.setTuiMoney(tuiMoney);
                storeOrderMapper.updateFsStoreOrder(storeOrderMap);
            }
        }
    }

    @Override
    @Transactional
    public void addCompanyMoney(FsStoreOrder order) {
        if(order.getCompanyId()>0){
            Company company=companyMapper.selectCompanyByIdForUpdate(order.getCompanyId());
            if(company!=null){
                FsStoreOrder orderMap=new FsStoreOrder();
                orderMap.setId(order.getId());
                orderMap.setTuiMoneyStatus(1);
                storeOrderMapper.updateFsStoreOrder(orderMap);
                String json =configService.selectConfigByKey("store.config");
                StoreConfig config= JSONUtil.toBean(json,StoreConfig.class);
                //支付金额-（订单金额*rate%）
                Double rate=config.getTuiMoneyRate()/100d;
                BigDecimal tuiMoney=order.getPayPrice().subtract(order.getTotalPrice().multiply(new BigDecimal(rate)));
                company.setMoney(company.getMoney().add(tuiMoney));
                companyMapper.updateCompany(company);
                //companyMapper.updateCompanyMoney(company.getCompanyId(),tuiMoney);
                //写入日志
                CompanyMoneyLogs log=new CompanyMoneyLogs();
                log.setCompanyId(order.getCompanyId());
                log.setRemark("订单佣金入帐");
                log.setMoney(tuiMoney);
                log.setLogsType(4);
                log.setBalance(company.getMoney());
                log.setCreateTime(new Date());
                log.setBusinessId(order.getId().toString());
                moneyLogsMapper.insertCompanyMoneyLogs(log);
            }
        }
    }

    @Override
    @Transactional
    public void subCompanyMoney(FsStoreOrder order) {
        if(order.getCompanyId()>0){
            Company company=companyMapper.selectCompanyByIdForUpdate(order.getCompanyId());
            if(company!=null){
                company.setMoney(company.getMoney().subtract(order.getTuiMoney()));
                company.setTuiMoney(company.getTuiMoney().subtract(order.getTuiMoney()));
                companyMapper.updateCompany(company);
                //写入日志
                CompanyMoneyLogs log=new CompanyMoneyLogs();
                log.setCompanyId(order.getCompanyId());
                log.setRemark("订单佣金退款");
                log.setMoney(order.getTuiMoney().multiply(new BigDecimal(-1)));
                log.setLogsType(5);
                log.setBalance(company.getMoney());
                log.setCreateTime(new Date());
                log.setBusinessId(order.getId().toString());
                moneyLogsMapper.insertCompanyMoneyLogs(log);
            }
        }
    }

    @Override
    public Company selectCompanyByAppId(String appId) {
        return companyMapper.selectCompanyByAppId(appId);
    }

    @Override
    @Async
    public void resetMoney(Long companyId) {
//        Company company=companyMapper.selectCompanyById(companyId);
//        company.setMoney(new BigDecimal(0));
//        company.setTuiMoney(new BigDecimal(0));
//        //删除公司的提现记录
//        companyProfitService.deleteCompanyProfitByCompanyId(companyId);
//        //删除公司的金额记录
//        moneyLogsMapper.deleteCompanyMoneyLogsByCompanyId(companyId);
//        //重新计算金额
//        Integer pageNum=1;
//        while (true){
//            PageHelper.startPage(pageNum, 10);
//            List<FsStoreOrder> list=storeOrderMapper.selectFsStoreOrderByCompanyId(companyId);
//            pageNum++;
//            if(list!=null&&list.size()>0){
//                for(FsStoreOrder order:list){
//                    //已签收
//                    if(order.getStatus()==3&&order.getTuiMoney()!=null&&order.getTuiMoney().compareTo(new BigDecimal(0))==1){
////                        String json =configService.selectConfigByKey("store.config");
////                        StoreConfig config= JSONUtil.toBean(json,StoreConfig.class);
////                        Double rate=config.getTuiMoneyRate()/100d;
////                        BigDecimal tuiMoney=order.getPayPrice().subtract(order.getTotalPrice().multiply(new BigDecimal(rate)));
//                        company.setMoney(company.getMoney().add(order.getTuiMoney()));
//                        company.setTuiMoney(company.getTuiMoney().add(order.getTuiMoney()));
//                        companyMapper.updateCompany(company);
//                        //写入日志
//                        CompanyMoneyLogs log=new CompanyMoneyLogs();
//                        log.setCompanyId(order.getCompanyId());
//                        log.setRemark("订单佣金入帐");
//                        log.setMoney(order.getTuiMoney());
//                        log.setLogsType(4);
//                        log.setBalance(company.getMoney());
//                        log.setCreateTime(new Date());
//                        log.setBusinessId(order.getId().toString());
//                        moneyLogsMapper.insertCompanyMoneyLogs(log);
//                    }
//                }
//            }
//            else{
//                break;
//            }
//        }
        //计算所有的收款记录，写入

//        company.setMoney(company.getMoney().add(order.getTuiMoney()));
//        company.setTuiMoney(company.getTuiMoney().add(order.getTuiMoney()));
//        companyMapper.updateCompany(company);
    }

    @Override
    @Transactional
    public void addCompanyPaymentMoney(FsStorePayment storePayment) {
        Company company=companyMapper.selectCompanyByIdForUpdate(storePayment.getCompanyId());
        if(company!=null){
            company.setMoney(company.getMoney().add(storePayment.getPayMoney()));
            company.setTuiMoney(company.getTuiMoney().add(storePayment.getPayMoney()));
            companyMapper.updateCompany(company);
            //写入日志
            CompanyMoneyLogs log=new CompanyMoneyLogs();
            log.setCompanyId(storePayment.getCompanyId());
            log.setRemark("收款佣金入帐");
            log.setMoney(storePayment.getPayMoney());
            log.setLogsType(8);
            log.setBalance(company.getMoney());
            log.setCreateTime(new Date());
            log.setBusinessId(storePayment.getPaymentId().toString());
            moneyLogsMapper.insertCompanyMoneyLogs(log);
        }

    }

    @Override
    @Transactional
    public void subCompanyPaymentMoney(FsStorePayment payment) {
        Company company=companyMapper.selectCompanyByIdForUpdate(payment.getCompanyId());
        if(company!=null){
            company.setMoney(company.getMoney().subtract(payment.getRefundMoney()));
            company.setTuiMoney(company.getTuiMoney().subtract(payment.getRefundMoney()));
            companyMapper.updateCompany(company);
            //写入日志
            CompanyMoneyLogs log=new CompanyMoneyLogs();
            log.setCompanyId(payment.getCompanyId());
            log.setRemark("收款佣金退款");
            log.setMoney(payment.getRefundMoney().multiply(new BigDecimal(-1)));
            log.setLogsType(9);
            log.setBalance(company.getMoney());
            log.setCreateTime(new Date());
            log.setBusinessId(payment.getPaymentId().toString());
            moneyLogsMapper.insertCompanyMoneyLogs(log);
        }
    }

    @Override
    public String selectOmsCodeByCompanyId(Long companyId) {
        return companyMapper.selectOmsCodeByCompanyId(companyId);
    }

    @Override
    public void updateOmsCodeByCompanyIds(List<Long> companyIds, String omsCode) {
        for (Long companyId : companyIds){
            companyMapper.updateOmsCodeByCompanyIds(companyId,omsCode);
        }
    }

    @Override
    public List<Long> selectCompanyByOmsCode(String omsCode) {
        return companyMapper.selectCompanyByOmsCode(omsCode);
    }

    @Override
    public Company selectCompanyByIdForUpdate(Long companyId) {
        return companyMapper.selectCompanyByIdForUpdate(companyId);
    }

    @Override
    public void updateMoney(Long companyId, BigDecimal money) {
        Company company = selectCompanyById(companyId);
        companyMapper.updateMoney(companyId, company.getRedPackageMoney().add(money));
    }

    @Override
    public void configUserCheck(Long companyId, Integer userIsDefaultBlack) {
        Company company = companyMapper.selectCompanyById(companyId);
        if(company != null) {
            company.setFsUserIsDefaultBlack(userIsDefaultBlack);
            companyMapper.updateCompany(company);
        }
    }

    /**
     * 根据条件查询公司选项列表
     * @param params    参数
     * @return list
     */
    @Override
    public List<OptionsVO> selectCompanyListByMap(Map<String, Object> params) {
        return companyMapper.selectCompanyListByMap(params);
    }

    @Override
    @Transactional
    public void subtractCompanyMoney(BigDecimal money, Long companyId) {
        if(companyId!=null&&companyId>0){
            Company company=companyMapper.selectCompanyByIdForUpdate(companyId);
            if(company!=null){
                logger.info("扣除红包金额:"+money);
                company.setMoney(company.getMoney().subtract(money));
                companyMapper.updateCompany(company);
                CompanyMoneyLogs log=new CompanyMoneyLogs();
                log.setCompanyId(company.getCompanyId());
                log.setRemark("扣除昨日红包金额");
                log.setMoney(money.multiply(new BigDecimal(-1)));
                log.setLogsType(15);
                log.setBalance(company.getMoney());
                log.setCreateTime(new Date());
                moneyLogsMapper.insertCompanyMoneyLogs(log);
            }
        }
    }

    @Override
    public List<DeptDataVO> getDeptData(Long companyId) {
        List<DeptDataVO> result = new ArrayList<>();

        if (companyId != null) {
            Company company = companyMapper.selectCompanyById(companyId);
            if (company != null) {
                DeptDataVO companyNode = buildCompanyNode(company);
                result.add(companyNode);
            }
        } else {
            List<Company> companies = companyMapper.selectCompanyAllList();

            if (companies != null && !companies.isEmpty()) {
                for (Company company : companies) {
                    DeptDataVO companyNode = buildCompanyNode(company);
                    result.add(companyNode);
                }
            }
        }

        return result.stream().filter(e -> CollectionUtils.isNotEmpty(e.getChildren())).collect(Collectors.toList());
    }
    /**
     * 构建公司节点，包含其下属部门和用户
     * @param company 公司对象
     * @return 公司节点
     */
    private DeptDataVO buildCompanyNode(Company company) {
        DeptDataVO companyNode = new DeptDataVO();
        companyNode.setLabel(company.getCompanyName());
        companyNode.setId(company.getCompanyId());

        List<DeptDataVO> deptDataList = getCompanyDeptUserData(company.getCompanyId());

        companyNode.setChildren(deptDataList.isEmpty() ? null : deptDataList);

        return companyNode;
    }
    /**
     * 获取公司，以及公司部门、部门下面的销售数据
     * @return
     */
    private List<DeptDataVO> getCompanyDeptUserData(Long companyId){
        List<CompanyDept> companyDepts = companyDeptMapper.selectDeptDataByCompanyId(companyId);

        if (companyDepts == null || companyDepts.isEmpty()) {
            return new ArrayList<>();
        }

        List<DeptDataVO> result = new ArrayList<>();

        for (CompanyDept companyDept : companyDepts) {
            DeptDataVO deptNode = new DeptDataVO();
            deptNode.setLabel(companyDept.getDeptName());
            deptNode.setId(companyDept.getDeptId());

            List<CompanyUser> companyUsers =
                    companyUserMapper.selectCompanyUserByDeptId(companyDept.getDeptId());

            List<DeptDataVO> userNodes = new ArrayList<>();

            if (companyUsers != null && !companyUsers.isEmpty()) {
                for (CompanyUser companyUser : companyUsers) {
                    DeptDataVO userNode = new DeptDataVO();
                    userNode.setLabel(companyUser.getUserName());
                    userNode.setId(companyUser.getUserId());
                    userNode.setChildren(null);

                    userNodes.add(userNode);
                }
            }

            deptNode.setChildren(userNodes.isEmpty() ? null : userNodes);

            result.add(deptNode);
        }

        return result;
    }


}
