package com.pz.merchant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.pz.common.core.domain.R;
import com.pz.common.core.domain.entity.SysUser;
import com.pz.common.core.page.TableDataInfo;
import com.pz.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pz.common.enums.UserType;
import com.pz.common.exception.ServiceException;
import com.pz.common.utils.StringUtils;
import com.pz.common.utils.redis.RedisUtils;
import com.pz.merchant.domain.Company;
import com.pz.merchant.domain.bo.EmployeesListBo;
import com.pz.merchant.domain.bo.OrderBo;
import com.pz.merchant.domain.bo.SetEmployeeWorkingHourBo;
import com.pz.merchant.domain.vo.*;
import com.pz.merchant.mapper.CompanyMapper;
import com.pz.merchant.service.ISonOrderService;
import com.pz.system.domain.Business;
import com.pz.system.domain.TotalOrder;
import com.pz.system.domain.bo.EmployeesCompanyBo;
import com.pz.system.domain.bo.WithdrawDepositBo;
import com.pz.system.domain.vo.BusinessVo;
import com.pz.system.domain.vo.TotalOrderVo;
import com.pz.system.mapper.BusinessMapper;
import com.pz.system.mapper.CityMapper;
import com.pz.system.mapper.SysUserMapper;
import com.pz.system.mapper.TotalOrderMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.pz.merchant.domain.bo.EmployeesBo;
import com.pz.merchant.domain.Employees;
import com.pz.merchant.mapper.EmployeesMapper;
import com.pz.merchant.service.IEmployeesService;

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

/**
 * 陪诊员Service业务层处理
 *
 * @author WangMin
 * @date 2023-09-11
 */
@RequiredArgsConstructor
@Service("merchantEmployeesService")
public class EmployeesServiceImpl implements IEmployeesService {

    private final EmployeesMapper baseMapper;
    private final CompanyMapper companyMapper;
    private final SysUserMapper sysUserMapper;
    private final CityMapper cityMapper;
    private final TotalOrderMapper totalOrderMapper;
    private final SonOrderServiceBuilder sonOrderServiceBuilder;
    private final BusinessMapper businessMapper;

    /**
     * 查询陪诊员
     */
    @Override
    public EmployeesVo queryById(Integer id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询陪诊员列表
     */
    @Override
    public TableDataInfo<EmployeesVo> queryPageList(EmployeesBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Employees> lqw = buildQueryWrapper(bo);
        Page<EmployeesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Optional.ofNullable(result.getRecords()).ifPresent(employeesVos -> {
            employeesVos.forEach(employeesVo -> {
                // 获取商户名称
                Optional.ofNullable(companyMapper.selectVoById(employeesVo.getCompanyId()))
                    .ifPresent(companyVo -> employeesVo.setCompanyName(companyVo.getName()));

                // 获取用户名称
                Optional.ofNullable(sysUserMapper.selectUserById(employeesVo.getUid().longValue())).ifPresent(
                    sysUser -> employeesVo.setUserName(sysUser.getNickName())
                );

                // 获取城市
                Optional.ofNullable(cityMapper.selectVoById(employeesVo.getCityId())).ifPresent(
                    cityVo -> employeesVo.setCityName(cityVo.getName())
                );
            });
        });
        return TableDataInfo.build(result);
    }

    /**
     * 小程序查询陪诊员列表
     */
    @Override
    public TableDataInfo<EmployeesListVo> employeesList(EmployeesListBo bo, PageQuery pageQuery) {
        QueryWrapper<Employees> wrapper = Wrappers.query();
        wrapper.like(StringUtils.isNotEmpty(bo.getEmployeeName()), "employees.name", bo.getEmployeeName())
            .eq(bo.getCompanyId() != null, "employees.company_id", bo.getCompanyId())
            .eq(bo.getEmployeeType() != null, "employees.now_type", bo.getEmployeeType());
        IPage<EmployeesListVo> result = baseMapper.selectEmployeesList(pageQuery.build(), wrapper);
        return TableDataInfo.build(result);
    }


    /**
     * 查询陪诊员列表
     */
    @Override
    public List<EmployeesVo> queryList(EmployeesBo bo) {
        LambdaQueryWrapper<Employees> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Employees> buildQueryWrapper(EmployeesBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Employees> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), Employees::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getStartYear()), Employees::getStartYear, bo.getStartYear());
        lqw.eq(bo.getUid() != null, Employees::getUid, bo.getUid());
        lqw.eq(bo.getStatus() != null, Employees::getStatus, bo.getStatus());
        lqw.eq(bo.getNowType() != null, Employees::getNowType, bo.getNowType());
        return lqw;
    }

    /**
     * 新增陪诊员/商户
     */
    @Override
    public Boolean insertByBo(EmployeesBo bo) {
        Employees add = BeanUtil.toBean(bo, Employees.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    public Boolean insertByEmployeesCompanyBo(EmployeesCompanyBo bo) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(bo.getUid().longValue());

        int res = 0;
        switch (bo.getIdentity()) {
            case 2:
                //陪诊员
                Employees employees = BeanUtil.toBean(bo, Employees.class);
                employees.setNowType(1);
                res = baseMapper.insert(employees);
                break;
            case 3:
                //商户
                Company company = BeanUtil.toBean(bo, Company.class);
                res = companyMapper.insert(company);
                break;

            default:
                // 处理其他身份的情况
                break;
        }
        return res > 0;
    }

    /**
     * 修改陪诊员
     */
    @Override
    public Boolean updateByBo(EmployeesBo bo) {
        Employees update = BeanUtil.toBean(bo, Employees.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 需求广场
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<EmployeesVo> queryPageAppNeed(EmployeesBo bo, PageQuery pageQuery) {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 获取当前年份
        int year = currentDate.getYear();
        Page<EmployeesVo> result = baseMapper.selectEmployees(bo, pageQuery.build());
        Optional.ofNullable(result.getRecords()).ifPresent(EmployeesVo -> {
            EmployeesVo.forEach(t -> {
                List<TotalOrderVo> totalOrder = totalOrderMapper.selectVoList(Wrappers.<TotalOrder>lambdaQuery()
                    .eq(TotalOrder::getEmId, t.getId())
                    .eq(TotalOrder::getIsSatisfaction, 1)
                    .orderByDesc(TotalOrder::getId)
                    .last("LIMIT 1"));
                t.setTotalOrderVo(totalOrder);
                t.setWrokYear(year - Integer.parseInt(t.getStartYear()));
            });
        });
        return TableDataInfo.build(result);
    }

    /**
     * 排行榜
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<EmployeesVo> queryPageAppRanking(EmployeesBo bo, PageQuery pageQuery) {
        Page<EmployeesVo> result = baseMapper.selectEmployees(bo, pageQuery.build());
        Optional.ofNullable(result.getRecords()).ifPresent(EmployeesVo -> {
            EmployeesVo.forEach(t -> {
                List<TotalOrderVo> totalOrder = totalOrderMapper.selectVoList(Wrappers.<TotalOrder>lambdaQuery()
                    .eq(TotalOrder::getEmId, t.getId())
                    .eq(TotalOrder::getIsSatisfaction, 1)
                    .orderByDesc(TotalOrder::getId)
                    .last("LIMIT 1"));
                t.setTotalOrderVo(totalOrder);
            });
        });
        return TableDataInfo.build(result);
    }


    /**
     * 查询陪诊员详情
     */
    @Override
    public EmployeesVo queryByApp(Integer id) {
        EmployeesVo employeesVo = baseMapper.selectEmployeesById(id);
        if(null != employeesVo){
            List<TotalOrderVo> totalOrder = totalOrderMapper.selectVoList(Wrappers.<TotalOrder>lambdaQuery()
                .eq(TotalOrder::getEmId, employeesVo.getId())
                .eq(TotalOrder::getIsSatisfaction, 1)
                .orderByDesc(TotalOrder::getId));
            if(null != totalOrder && totalOrder.size() != 0){
                for (TotalOrderVo order : totalOrder) {
                    BusinessVo businessVo = businessMapper.selectVoOne(new LambdaQueryWrapper<Business>().eq(Business::getId, order.getBusinessId()));
                    if (null != businessVo) {
                        order.setProject(businessVo.getName());
                    }
                }
            }
            employeesVo.setTotalOrderVo(totalOrder);
        }
        return employeesVo;
    }

    /**
     * 切换陪诊员用户身份
     *
     * @param emId 陪诊员Id
     * @return 操作结果
     */
    @Override
    public boolean switchEmployeeIdentity(Integer emId) {
        EmployeesVo employeesVo = baseMapper.selectVoById(emId);
        Objects.requireNonNull(employeesVo, "查无此人");
        Integer identity = employeesVo.getNowType();
        // 切换当前用户身份
        Integer modifyIdentity = identity == 1 ? 2 : 1;
        employeesVo.setNowType(modifyIdentity);
        return baseMapper.updateById(BeanUtil.toBean(employeesVo, Employees.class)) > 0;
    }

    /**
     * 冻结/解冻陪诊员账户
     *
     * @param emId 陪诊员Id
     * @return 操作结果
     */
    @Override
    public boolean disableOrRecover(Integer emId) {
        Employees employees = baseMapper.selectById(emId);
        Objects.requireNonNull(employees, "查无此人");
        Integer status = employees.getStatus();
        if (status == 0) {
            throw new ServiceException("该用户待审核通过,暂无法修改状态");
        }
        int modifyStatus = status == 1 ? 2 : 1;
        // 若切换状态为1(正常),则需清除账户的取消订单次数
        if (modifyStatus == 1) {
            RedisUtils.delCacheMapValue(ISonOrderService.ORDER_CANCEL_CACHE_PREFIX, String.valueOf(emId));
            employees.setKillOrder(0);
        }
        employees.setStatus(modifyStatus);
        return baseMapper.updateById(employees) > 0;
    }

    @Override
    public EmployeesVo queryByUserId(Long userId) {
        EmployeesVo employeesVo = baseMapper.selectVoOne(Wrappers.<Employees>lambdaQuery().eq(Employees::getUid, userId));
        // 获取所属商户
        Optional.ofNullable(companyMapper.selectVoById(employeesVo.getCompanyId()))
            .ifPresent(companyVo -> employeesVo.setCompanyName(companyVo.getName()));

        return employeesVo;
    }

    @Override
    public boolean withdrawDeposit(WithdrawDepositBo bo) {
        Employees employees = baseMapper.selectById(bo.getId());
        Objects.requireNonNull(employees, "未检查到账户");
        BigDecimal money = new BigDecimal(Optional.ofNullable(employees.getBalance()).orElse("0"));
        BigDecimal balance = money.subtract(bo.getAmount());
        if (balance.compareTo(BigDecimal.ZERO) < 0) {
            throw new ServiceException("可用余额不足");
        }
        BigDecimal freeze = new BigDecimal(Optional.ofNullable(employees.getFreezeBalance()).orElse("0"));
        freeze = freeze.add(bo.getAmount());
        LambdaUpdateWrapper<Employees> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(Employees::getBalance, balance)
            .set(Employees::getFreezeBalance, freeze)
            .eq(Employees::getId, employees.getId());
        throw new UnsupportedOperationException("资质不足,无法提现");
        // return baseMapper.update(null, wrapper) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Employees entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除陪诊员
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 设置员工工作时段
     */
    @Override
    public boolean setEmployeesWorkHours(SetEmployeeWorkingHourBo bo) {
        EmployeesVo employees = baseMapper.selectVoById(bo.getEmId());
        Objects.requireNonNull(employees, "查无此人");
        LambdaUpdateWrapper<Employees> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(Employees::getWorkingHours, bo.getWorkingHours())
            .eq(Employees::getId, employees.getId());
        return baseMapper.update(null, updateWrapper) > 0;
    }

    /**
     * 查询员工数据以及今日订单
     *
     * @param emId 员工ID
     * @return 今日订单数据信息
     */
    @Override
    public TodayOrderListVo queryEmployeesInfo(Integer emId) {
        TodayOrderListVo result = baseMapper.selectEmployeesInfoById(emId);
        QueryWrapper<Employees> query = Wrappers.query();
        query.apply(" to_days(current_date) = to_days(total_order.create_time)")// 查询当天数据
            .eq("total_order.em_id", emId)
            .ne("total_order.business_id", 0);  // 排除商城订单
        IPage<OrderInfoVO> page = baseMapper.selectOrder(new PageQuery().build(), query);
        // 根据不同子订单装载就诊人员信息和子订单状态
        List<OrderInfoVO> orders = page.getRecords();
        orders.forEach(suborder -> {
            ISonOrderService orderService = sonOrderServiceBuilder.getSonOrderService(suborder.getBusinessId());
            SonOrderVo orderStatus;
            if (orderService != null && (orderStatus = orderService.getSonOrderSimpleDataByTotalId(suborder.getOrderId())) != null) {
                suborder.setUserName(orderStatus.getUserName());
                suborder.setSonOrderStatus(orderStatus.getOrderStatus());
            }
        });
        result.setTodayOrderList(orders);
        result.setTodayOrderNum(orders.size());
        return result;
    }

    /**
     * 查询所有订单
     *
     * @param bo 查询条件
     * @return 订单列表
     */
    @Override
    public TableDataInfo<OrderInfoVO> queryAllOrder(OrderBo bo, PageQuery pageQuery) {
        QueryWrapper<Employees> query = Wrappers.query();
        query.eq(bo.getEmId() != null, "total_order.em_id", bo.getEmId())
            .eq(bo.getServiceStatus() != null, "total_order.suborder_status", bo.getServiceStatus())
            .between("total_order.business_id", 1, 5)  // 陪诊员只能查询1-5的订单
            .orderByDesc("total_order.id");
        IPage<OrderInfoVO> page = baseMapper.selectOrder(pageQuery.build(), query);
        // 根据不同子订单装载就诊人员信息和子订单状态
        page.getRecords().forEach(suborder -> {
            ISonOrderService orderService = sonOrderServiceBuilder.getSonOrderService(suborder.getBusinessId());
            SonOrderVo orderStatus;
            if (orderService != null && (orderStatus = orderService.getSonOrderSimpleDataByTotalId(suborder.getOrderId())) != null) {
                suborder.setUserName(orderStatus.getUserName());
                suborder.setSonOrderStatus(orderStatus.getOrderStatus());
            }
        });
        return TableDataInfo.build(page);
    }


}