package cn.iocoder.yudao.module.inspection.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.custom.entity.CustomerMain;
import cn.iocoder.yudao.module.custom.service.CustomerMainService;
import cn.iocoder.yudao.module.inspection.vo.DlInspectionWorkNodeVo;
import cn.iocoder.yudao.module.partner.entity.PartnerCustomerInfo;
import cn.iocoder.yudao.module.partner.service.IPartnerCustomerInfoService;
import cn.iocoder.yudao.module.partner.service.IPartnerWorkerService;
import cn.iocoder.yudao.module.payment.service.IOrderInfoDetailService;
import cn.iocoder.yudao.module.payment.service.OrderInfoService;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.util.SendSmsUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.util.StringUtils;
import cn.iocoder.yudao.module.inspection.entity.*;
import cn.iocoder.yudao.module.inspection.mapper.InspectionInfoMapper;
import cn.iocoder.yudao.module.inspection.service.*;
import cn.iocoder.yudao.module.inspection.utils.PhoneValidator;
import cn.iocoder.yudao.module.partner.entity.PartnerWorker;
import cn.iocoder.yudao.module.payment.entity.OrderInfo;
import cn.iocoder.yudao.module.payment.entity.OrderInfoDetail;
import cn.iocoder.yudao.module.shop.entity.ShopMallPartners;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-13
 */
@Service
public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper, InspectionInfo> implements IInspectionInfoService {
    @Autowired
    private AdminUserService userService;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private IPartnerWorkerService workerService;
    @Autowired
    private IShopInspectionGoodsService goodsService;
    @Autowired
    private InspectionGoodsSkuService skuService;
    @Autowired
    @Lazy
    private AppInspectionPartnerService appInspectionPartnerService;
    @Autowired
    private IPartnerCustomerInfoService customerInfoService;
    @Autowired
    private IOrderInfoDetailService orderInfoDetailService;
    @Autowired
    private IDelOrderInfoService delInspectionOrderService;
    @Autowired
    private IDelInspectionInfoService delInspectionInfoService;
    @Autowired
    private IInspectionWorkNodeService workNodeService;
    @Autowired
    private InspectionStepInfoService inspectionStepInfoService;
    @Resource
    private CustomerMainService customerMainService;
    @Autowired
    private RoleService roleService;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public InspectionInfo selectInspectionInfoById(Long id) {
        return baseMapper.selectInspectionInfoById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param inspectionInfo 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public IPage<InspectionInfo> selectInspectionInfoList(Page<InspectionInfo> page, InspectionInfo inspectionInfo) {
        return baseMapper.selectInspectionInfoList(page, inspectionInfo);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param inspectionInfo 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertInspectionInfo(InspectionInfo inspectionInfo) throws Exception {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        ShopMallPartners partners = appInspectionPartnerService.shopInfo();

        if (ObjectUtils.isEmpty(inspectionInfo.getInspectionWorkNodes())) {
            throw new RuntimeException("请选择检测项目");
        }
        //当前登陆人 就是检测人
        AdminUserDO workerUser = userService.getUser(loginUser.getId());
        String buyName = StringUtils.isNotEmpty(inspectionInfo.getBuyName()) ? inspectionInfo.getBuyName() : "未知客户";
        String buyPhone = StringUtils.isNotEmpty(inspectionInfo.getBuyPhone()) ? inspectionInfo.getBuyPhone() : StringUtils.isNotEmpty(inspectionInfo.getBuyName()) ? inspectionInfo.getBuyName() : "无";
        AdminUserDO user = userService.getUserByMobile(buyPhone);
        if (ObjectUtils.isEmpty(user)) {
            //新增用户
            UserSaveReqVO userSaveReqVO = new UserSaveReqVO();
            userSaveReqVO.setNickname(buyName);
            userSaveReqVO.setUsername(buyPhone);
            userSaveReqVO.setMobile(buyPhone);
            userSaveReqVO.setPassword("123456");
            Long uid = userService.createUser(userSaveReqVO);
            inspectionInfo.setUserId(uid);
            user = new AdminUserDO();
            user.setId(uid);
            user.setNickname(buyName);
            user.setUsername(buyPhone);
            user.setMobile(buyPhone);
        } else {
            inspectionInfo.setUserId(user.getId());
        }
        InspectionGoodsSku sku = skuService.getById(inspectionInfo.getSkuId());
        ShopInspectionGoods goods = goodsService.getById(sku.getGoodsId());
        ShopMallPartners partner = appInspectionPartnerService.getById(goods.getPartnerId());
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setPartnerId(partners.getPartnerId());
        orderInfo.setGoodsId(Long.parseLong(goods.getId().toString()));
        orderInfo.setGoodsTitle(goods.getTitle());
        orderInfo.setGoodsType("jc");
        orderInfo.setGoodNum(1);
        orderInfo.setSkuId(Long.parseLong(sku.getId().toString()));
        orderInfo.setSkuName(sku.getSkuName());
        orderInfo.setGoodsPrice(goods.getPrice());
        orderInfo.setStartTime(new Date());
        orderInfo.setOrderTime(new Date());
        orderInfo.setOrderType("jc");
        orderInfo.setUserId(user.getId());
        orderInfo.setRealName(user.getNickname());
        orderInfo.setIsOnline("0");
        orderInfo.setPhonenumber(user.getMobile());
        orderInfo.setPartnerName(partner.getPartnerName());
        orderInfo.setOrderNo("线下订单-" + System.currentTimeMillis());
        //赊账的情况
        orderInfo.setOrderStatus("0");
        orderInfoService.save(orderInfo);
        inspectionInfo.setInspectionOrderId(orderInfo.getId());
        inspectionInfo.setPartnerId(partners.getPartnerId());
        inspectionInfo.setWorkerName(workerUser.getNickname());
        inspectionInfo.setWorkerPhone(workerUser.getMobile());
        inspectionInfo.setStartTime(new Date());
        inspectionInfo.setCategoryId(goods.getGoodsCategoryId());
        inspectionInfo.setStatus("0");
        inspectionInfo.setWorkId(workerUser.getId());
        inspectionInfo.setYear(DateUtil.format(inspectionInfo.getStartTime(), "yyyy"));
        inspectionInfo.setMonth(DateUtil.format(inspectionInfo.getStartTime(), "yyyy-MM"));
        inspectionInfo.setDay(DateUtil.format(inspectionInfo.getStartTime(), "yyyy-MM-dd"));
        try {
            //开始检测短信发送
            // 获取当前日期和时间
            LocalDateTime currentTime = LocalDateTime.now();

            // 定义指定格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日H:mm分");

            // 将当前时间转换为指定格式
            String formattedTime = currentTime.format(formatter);
            if (PhoneValidator.isValid(orderInfo.getPhonenumber())) {
                SendSmsUtil.sendMsgCommon(new String[]{formattedTime}, orderInfo.getPhonenumber(), "1400852709", "机动车管家小程序", "1961713");
            }
        } catch (Exception ignored) {
            log.error(ignored.getMessage());
        }
        //增加客户信息
        LambdaQueryWrapper<PartnerCustomerInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PartnerCustomerInfo::getPartnerId, inspectionInfo.getPartnerId()).eq(PartnerCustomerInfo::getUserId, orderInfo.getUserId());
        PartnerCustomerInfo customerInfo = customerInfoService.getOne(queryWrapper);
        if (ObjectUtil.isEmpty(customerInfo)) {
            customerInfo = new PartnerCustomerInfo();
            customerInfo.setPartnerId(inspectionInfo.getPartnerId());
            customerInfo.setUserId(user.getId());
            customerInfo.setCustomerPhone(user.getMobile());
            customerInfo.setCustomerName(user.getNickname());
            customerInfo.setSex("0");
            customerInfo.setUserAge(user.getUserAge());
            // 设置客户来源
            try {
                customerInfoService.insertPartnerCustomerInfo(customerInfo);
            } catch (Exception ignored) {

            }

        }
        //追加订单明细记录
        orderInfoDetailService.save(new OrderInfoDetail(orderInfo.getId(), "线下订单创建", new Date(), 0L, "1"));
        //默认当前流程的顺序为1
        inspectionInfo.setNowOrderNum(1);
        //添加检测工单
        baseMapper.insert(inspectionInfo);
        //补充检测流程
        List<InspectionWorkNode> inspectionWorkNodes = inspectionInfo.getInspectionWorkNodes();
        //将检测工单流程补充检测工单id
        inspectionWorkNodes.stream().forEach(inspectionWorkNode -> {
            //检测工单id
            inspectionWorkNode.setInspectionInfoId(inspectionInfo.getId());
            //将节点状态设置为未开始
            inspectionWorkNode.setStatus("0");
        });

        workNodeService.saveBatch(inspectionWorkNodes);

        //检测步骤表插入检测开始
        InspectionStepInfo stepInfo = new InspectionStepInfo();
        stepInfo.setInspectionInfoId(Integer.parseInt(String.valueOf(inspectionInfo.getId())));
        stepInfo.setTitle("检测开始");
        stepInfo.setContent("检测开始");
        boolean save = inspectionStepInfoService.save(stepInfo);
        return save ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settleAccounts(Long InspectionId) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        AdminUserDO user = userService.getUser(loginUser.getId());
        InspectionInfo info = baseMapper.selectById(InspectionId);
        OrderInfo orderInfo = orderInfoService.getById(info.getInspectionOrderId());
        orderInfo.setValidationTime(new Date());
        orderInfo.setValidationUserId(loginUser.getId());
        orderInfo.setValidationRealName(user.getNickname());
        orderInfo.setEndTime(new Date());
        orderInfo.setOrderStatus("2");
        orderInfo.setPayTime(new Date());
        orderInfoService.updateById(orderInfo);
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param inspectionInfo 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateInspectionInfo(InspectionInfo inspectionInfo) throws Exception {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        ShopMallPartners partners = appInspectionPartnerService.shopInfo();
        LambdaQueryWrapper<PartnerWorker> workerQueryWrapper = new LambdaQueryWrapper<>();
        workerQueryWrapper.eq(PartnerWorker::getUserId, loginUser.getId()).eq(PartnerWorker::getPartnerId, partners.getPartnerId());
        PartnerWorker worker = workerService.getOne(workerQueryWrapper);
        AdminUserDO workerUser = userService.getUser(worker.getUserId());
        if (ObjectUtils.isNotEmpty(worker)) {
            inspectionInfo.setWorkId(worker.getId());
        } else {
            throw new Exception("请先将接待员加入员工");
        }
        String buyName = StringUtils.isNotEmpty(inspectionInfo.getBuyName()) ? inspectionInfo.getBuyName() : "未知客户";
        String buyPhone = StringUtils.isNotEmpty(inspectionInfo.getBuyPhone()) ? inspectionInfo.getBuyPhone() : StringUtils.isNotEmpty(inspectionInfo.getBuyName()) ? inspectionInfo.getBuyName() : "无";
        AdminUserDO user = userService.getUserByMobile(buyPhone);
        if (ObjectUtils.isEmpty(user)) {
            //新增用户
            UserSaveReqVO userSaveReqVO = new UserSaveReqVO();
            userSaveReqVO.setNickname(buyName);
            userSaveReqVO.setUsername(buyPhone);
            userSaveReqVO.setMobile(buyPhone);
            userSaveReqVO.setPassword("123456");
            Long uid = userService.createUser(userSaveReqVO);
            inspectionInfo.setUserId(uid);
        } else {
            inspectionInfo.setUserId(user.getId());
        }
        InspectionGoodsSku sku = skuService.getById(inspectionInfo.getSkuId());
        ShopInspectionGoods goods = goodsService.getById(sku.getGoodsId());
        inspectionInfo.setPartnerId(partners.getPartnerId());
        inspectionInfo.setWorkerName(workerUser.getNickname());
        inspectionInfo.setWorkerPhone(workerUser.getMobile());
        inspectionInfo.setCategoryId(goods.getGoodsCategoryId());
        //增加客户信息
        return baseMapper.updateById(inspectionInfo);
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteInspectionInfoByIds(Long id) {
        InspectionInfo info = this.getById(id);
        baseMapper.deleteInspectionInfoById(id);
        OrderInfo orderInfo = orderInfoService.getById(info.getInspectionOrderId());
        orderInfoService.removeById(info.getInspectionOrderId());
        //往回收站插入
        DelInspectionInfo delInspectionInfo = new DelInspectionInfo();
        DelOrderInfo delInspectionOrder = new DelOrderInfo();
        BeanUtils.copyProperties(info, delInspectionInfo);
        BeanUtils.copyProperties(orderInfo, delInspectionOrder);
        delInspectionInfoService.insertDelInspectionInfo(delInspectionInfo);
        delInspectionOrderService.insertDelOrderInfo(delInspectionOrder);
        return 1;
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteInspectionInfoById(Long id) {
        return baseMapper.deleteInspectionInfoById(id);
    }

    @Override
    public List<InspectionInfo> workOrder(Long partnerId, String carNum, String goodsTitle, String customerSource, String payType, String startTime, Long roleId, String endTime) {
        return baseMapper.workOrder(partnerId, carNum, goodsTitle, customerSource, payType, startTime, roleId, endTime);
    }

    @Override
    public IPage<InspectionInfo> pageWorkOrder(Long partnerId, String carNum, String goodsTitle, String customerSource, String payType, String startTime, Long roleId, String endTime, Page<InspectionInfo> page) {
        return baseMapper.pageWorkOrder(partnerId, carNum, goodsTitle, customerSource, payType, startTime, roleId, endTime, page);
    }

    @Override
    public List<InspectionInfo> delworkOrder(Long partnerId, String carNum, String goodsTitle, String customerSource, String payType, String startTime, Long roleId, String endTime) {
        return baseMapper.delworkOrder(partnerId, carNum, goodsTitle, customerSource, payType, startTime, roleId, endTime);
    }

    @Override
    public IPage<InspectionInfo> pageDelWorkOrder(Long partnerId, String carNum, String goodsTitle, String customerSource, String payType, String startTime, Long roleId, String endTime, Page<InspectionInfo> page) {
        return baseMapper.pageDelWorkOrder(partnerId, carNum, goodsTitle, customerSource, payType, startTime, roleId, endTime, page);
    }

    @Override
    public Map<String, Object> workOrderData(Long partnerId, String carNum, String goodsTitle, String customerSource, String payType, String startTime, Long roleId, String endTime) {
        return baseMapper.workOrderData(partnerId, carNum, goodsTitle, customerSource, payType, startTime, roleId, endTime);
    }

    /**
     * 根据当前登陆人获取可以选择的工单
     *
     * @param page
     * @return
     */
    @Override
    public IPage<InspectionInfo> geStelectInspection(IPage page,InspectionInfo inspectionInfo) {
        //获取当前登录人
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        //获取当前登陆人的角色
        List<UserRoleDO> byUserId = roleService.getByUserId(loginUser.getId());
        List<Long> roleIds = byUserId.stream().map(UserRoleDO::getRoleId).collect(Collectors.toList());
        if(!"1".equals(inspectionInfo.getStatus())){
            //进行中 已完成
            inspectionInfo.setDealUserId(loginUser.getId());
        }
        return baseMapper.selectByUser(page,roleIds,inspectionInfo);
    }

    /**
     * 获取工单详情
     *
     * @param id
     * @return
     */
    @Override
    public DlInspectionWorkNodeVo getWorkNode(Integer inspectionId, String workNodeId) {
        //查询工单
        InspectionInfo inspectionInfo = this.getById(inspectionId);
        //根据工单id查询流程节点
        InspectionWorkNode inspectionWorkNode = workNodeService.getById(workNodeId);
        //根据工单id查询步骤
        List<InspectionStepInfo> inspectionStepInfos = inspectionStepInfoService.list(new LambdaQueryWrapper<InspectionStepInfo>()
                .eq(InspectionStepInfo::getInspectionInfoId, inspectionId));

        DlInspectionWorkNodeVo dlInspectionWorkNodeVo = new DlInspectionWorkNodeVo();
        dlInspectionWorkNodeVo.setInspectionInfo(inspectionInfo);
        dlInspectionWorkNodeVo.setNode(inspectionWorkNode);
        dlInspectionWorkNodeVo.setSteps(inspectionStepInfos);
        return dlInspectionWorkNodeVo;
    }

    /**
     * 根据工单id获取工单流程
     *
     * @param inspectionId
     * @return
     */
    @Override
    public List<InspectionWorkNode> getWeorkNodesById(Integer inspectionId) {
        return workNodeService.getWeorkNodesById(inspectionId);
    }
}
