package com.xinelu.manage.service.servicepackage.impl;

import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.PageServiceUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.servicepackage.ServicePackage;
import com.xinelu.manage.domain.servicepackagecontent.ServicePackageContent;
import com.xinelu.manage.dto.servicepackage.ServicePackageAddDTO;
import com.xinelu.manage.dto.servicepackage.ServicePackageDto;
import com.xinelu.manage.mapper.servicepackage.ServicePackageMapper;
import com.xinelu.manage.mapper.servicepackagecontent.ServicePackageContentMapper;
import com.xinelu.manage.service.servicepackage.IServicePackageService;
import com.xinelu.manage.vo.servicepackage.ServicePackageDetailVO;
import com.xinelu.manage.vo.servicepackage.ServicePackageVO;
import com.xinelu.manage.vo.servicepackagecontent.ServicePackageContentVO;
import java.time.LocalDateTime;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 服务包基础信息Service业务层处理
 *
 * @author xinelu
 * @date 2024-03-03
 */
@Service
public class ServicePackageServiceImpl implements IServicePackageService {
    @Resource
    private ServicePackageMapper servicePackageMapper;

    @Resource
    private ServicePackageContentMapper servicePackageContentMapper;

    @Resource
    private PageServiceUtil pageServiceUtil;

    @Resource
    private GenerateSystemCodeUtil systemCodeUtil;

    /**
     * 查询服务包基础信息
     *
     * @param id 服务包基础信息主键
     * @return 服务包基础信息
     */
    @Override
    public ServicePackageDetailVO selectServicePackageById(Long id) {
        // 根据服务包id查询服务包基础信息
        ServicePackageDetailVO servicePackageDetailVO = servicePackageMapper.selectServicePackagesById(id);
        servicePackageDetailVO.setPackageTermAndUnit(servicePackageDetailVO.getPackageTerm() + servicePackageDetailVO.getPackageTermUnit());
        // 根据服务包id查询服务包内容
        List<ServicePackageContentVO> voList = servicePackageMapper.selectServicePackageVoListById(id);
        servicePackageDetailVO.setVoList(voList);
        return servicePackageDetailVO;
    }

    /**
     * 查询服务包基础信息
     *
     * @param id 服务包基础信息主键
     * @return 服务包基础信息
     */
    @Override
    public ServicePackageVO getById(Long id) {
        ServicePackageDetailVO servicePackageDetailVo = servicePackageMapper.selectServicePackagesById(id);
        if (ObjectUtils.isEmpty(servicePackageDetailVo)) {
            throw new ServiceException("数据传输错误");
        }
        ServicePackageVO servicePackageVO = new ServicePackageVO();
        BeanUtils.copyBeanProp(servicePackageVO, servicePackageDetailVo);
        return servicePackageVO;
    }

    /**
     * 查询服务包基础信息列表
     *
     * @param servicePackage 服务包基础信息
     * @return 服务包基础信息
     */
    @DataScope(agencyAlias = "d", deptAlias = "sp")
    @Override
    public TableDataInfo selectServicePackageList(ServicePackageDto servicePackage) {
        pageServiceUtil.startPage();
        List<ServicePackageVO> voList = servicePackageMapper.selectServicePackageLists(servicePackage);
        return pageServiceUtil.getDataTable(voList);
    }

    @Override
    public List<ServicePackageVO> selectList(ServicePackageDto servicePackage) {
        return servicePackageMapper.selectServicePackageLists(servicePackage);
    }

    /**
     * 新增服务包基础信息
     *
     * @param servicePackageAddDTO 服务包基础信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertServicePackage(ServicePackageAddDTO servicePackageAddDTO) {
        // 判断所属科室下服务包名称是否存在
        int existNameCount = servicePackageMapper.existNameCount(servicePackageAddDTO.getDepartmentId(), servicePackageAddDTO.getPackageName());
        if (existNameCount > 0) {
            throw new ServiceException("当前科室下服务包名称已存在");
        }
        String username = SecurityUtils.getUsername();
        LocalDateTime nowDate = LocalDateTime.now();
        // 初始化ServicePackage，将servicePackageAddDTO赋值给ServicePackage，新增服务包
        ServicePackage servicePackage = new ServicePackage();
        BeanUtils.copyProperties(servicePackageAddDTO, servicePackage);
        servicePackage.setCreateBy(username);
        servicePackage.setCreateTime(nowDate);
        if (servicePackageMapper.insertServicePackage(servicePackage) <= 0) {
            throw new ServiceException("新增服务包失败");
        }
        // 新增服务内容
        for (ServicePackageContentVO vo : servicePackageAddDTO.getVoList()) {
            Long serviceWayId = createServiceWay(servicePackage, vo, username, nowDate);
            Long serviceContentId = createServiceContent(servicePackage, vo, serviceWayId, username, nowDate);
            createServiceFrequency(servicePackage, vo, serviceContentId, username, nowDate);
        }
        return 1;
    }

    /**
     * 修改服务包基础信息
     *
     * @param servicePackageAddDTO 服务包基础信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateServicePackage(ServicePackageAddDTO servicePackageAddDTO) {
        // 检查除当前记录之外是否存在同名的服务包名称
        if (servicePackageMapper.countByPackageNameExcludingId(servicePackageAddDTO.getId(), servicePackageAddDTO.getDepartmentId(), servicePackageAddDTO.getPackageName()) > 0) {
            throw new ServiceException("当前科室下服务包名称已存在");
        }
        String username = SecurityUtils.getUsername();
        LocalDateTime nowDate = LocalDateTime.now();
        // 初始化ServicePackage，将servicePackageAddDTO赋值给ServicePackage，更新服务包
        ServicePackage servicePackage = new ServicePackage();
        BeanUtils.copyProperties(servicePackageAddDTO, servicePackage);
        //修改取消发布
        servicePackage.setWhetherRelease(0);
        servicePackage.setUpdateBy(username);
        servicePackage.setUpdateTime(nowDate);
        if (servicePackageMapper.updateServicePackage(servicePackage) <= 0) {
            throw new ServiceException("修改服务包失败");
        }
        // 根据服务包id先删除服务包内容
        if (servicePackageContentMapper.deleteServicePackageContentByPackageId(servicePackageAddDTO.getId()) <= 0) {
            throw new ServiceException("删除服务包内容失败");
        }
        // 新增服务内容
        for (ServicePackageContentVO vo : servicePackageAddDTO.getVoList()) {
            Long serviceWayId = createServiceWay(servicePackage, vo, username, nowDate);
            Long serviceContentId = createServiceContent(servicePackage, vo, serviceWayId, username, nowDate);
            createServiceFrequency(servicePackage, vo, serviceContentId, username, nowDate);
        }
        return 1;
    }

    /**
     * 新增服务包方式
     */
    private Long createServiceWay(ServicePackage servicePackage, ServicePackageContentVO vo, String username, LocalDateTime nowDate) {
        Long serviceWayId = servicePackageContentMapper.countByPackageIdAndServiceWayName(servicePackage.getId(), vo.getServiceWayName());
        if (serviceWayId == null) {
            ServicePackageContent serviceWay = new ServicePackageContent();
            serviceWay.setServiceWayCode(Constants.SERVICE_MODE_ENCODING + systemCodeUtil.generateDepartCode(Constants.SERVICE_MODE_ENCODING));
            serviceWay.setServicePackageId(servicePackage.getId());
            serviceWay.setServiceWayName(vo.getServiceWayName());
            serviceWay.setCreateBy(username);
            serviceWay.setCreateTime(nowDate);
            if (servicePackageContentMapper.insertServicePackageContent(serviceWay) <= 0) {
                throw new ServiceException("新增服务包服务方式失败");
            }
            return serviceWay.getId();
        }
        return serviceWayId;
    }

    /**
     * 新增服务包内容
     */
    private Long createServiceContent(ServicePackage servicePackage, ServicePackageContentVO vo, Long serviceWayId, String username, LocalDateTime nowDate) {
        Long serviceContentId = servicePackageContentMapper.countByServiceWayIdAndServiceContent(serviceWayId, vo.getServiceContent());
        if (serviceContentId == null) {
            ServicePackageContent serviceContent = new ServicePackageContent();
            serviceContent.setServicePackageId(servicePackage.getId());
            serviceContent.setServiceWayId(serviceWayId);
            serviceContent.setServiceContent(vo.getServiceContent());
            serviceContent.setCreateBy(username);
            serviceContent.setCreateTime(nowDate);
            if (servicePackageContentMapper.insertServicePackageContent(serviceContent) <= 0) {
                throw new ServiceException("新增服务包服务内容失败");
            }
            return serviceContent.getId();
        }
        return serviceContentId;
    }

    /**
     * 新增服务包频次
     */
    private void createServiceFrequency(ServicePackage servicePackage, ServicePackageContentVO vo, Long serviceContentId, String username, LocalDateTime nowDate) {
        if (servicePackageContentMapper.countByServiceContentIdAndServiceFrequency(serviceContentId, vo) > 0) {
            throw new ServiceException("不能重复添加服务包内容");
        }
        ServicePackageContent serviceFrequency = new ServicePackageContent();
        serviceFrequency.setServicePackageId(servicePackage.getId());
        serviceFrequency.setServiceContentId(serviceContentId);
        serviceFrequency.setServiceFrequencyText(vo.getServiceFrequencyText());
        serviceFrequency.setServiceFrequencyStart(vo.getServiceFrequencyStart());
        serviceFrequency.setServiceFrequencyEnd(vo.getServiceFrequencyEnd());
        serviceFrequency.setCreateBy(username);
        serviceFrequency.setCreateTime(nowDate);
        if (servicePackageContentMapper.insertServicePackageContent(serviceFrequency) <= 0) {
            throw new ServiceException("新增服务包服务频次失败");
        }
    }

    /**
     * 批量删除服务包基础信息
     *
     * @param ids 需要删除的服务包基础信息主键
     * @return 结果
     */
    @Override
    public int deleteServicePackageByIds(Long[] ids) {
        // 删除服务包基础信息
        if (servicePackageMapper.deleteServicePackageByIds(ids) <= 0) {
            throw new ServiceException("删除服务包失败");
        }
        // 删除服务包内容
        if (servicePackageContentMapper.deleteServicePackageContentByPackageIds(ids) <= 0) {
            throw new ServiceException("删除服务包内容失败");
        }
        return 1;

    }

    /**
     * 删除服务包基础信息信息
     *
     * @param id 服务包基础信息主键
     * @return 结果
     */
    @Override
    public int deleteServicePackageById(Long id) {
        return servicePackageMapper.deleteServicePackageById(id);
    }

    /**
     * 修改服务包发布状态
     */
    @Override
    public int editReleaseStatus(Long id, Integer whetherRelease) {
        return servicePackageMapper.editReleaseStatus(id, whetherRelease);
    }
}
