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

import com.xinelu.common.constant.Constants;
import com.xinelu.common.enums.ServiceFrequencyTypeEnum;
import com.xinelu.common.enums.ServiceTypeEnum;
import com.xinelu.common.exception.ServiceException;
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.servicewaycontent.ServiceWayContent;
import com.xinelu.manage.dto.servicefrequency.ServiceFrequencyDTO;
import com.xinelu.manage.dto.servicewaycontent.ServiceWayContentAddDTO;
import com.xinelu.manage.dto.servicewaycontent.ServiceWayContentDTO;
import com.xinelu.manage.dto.servicewaycontent.ServiceWayContentEditDTO;
import com.xinelu.manage.mapper.servicewaycontent.ServiceWayContentMapper;
import com.xinelu.manage.service.servicewaycontent.IServiceWayContentService;
import com.xinelu.manage.vo.servicewaycontent.ServiceWayContentAndFrequencyVO;
import com.xinelu.manage.vo.servicewaycontent.ServiceWayContentAndNumVO;
import com.xinelu.manage.vo.servicewaycontent.ServiceWayContentVO;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 服务方式内容Service业务层处理
 *
 * @author xinelu
 * @date 2024-02-29
 */
@Service
public class ServiceWayContentServiceImpl implements IServiceWayContentService {
    @Resource
    private ServiceWayContentMapper serviceWayContentMapper;

    @Resource
    private GenerateSystemCodeUtil systemCodeUtil;

    /**
     * 查询服务方式内容
     *
     * @param id 服务方式内容主键
     * @return 服务方式内容
     */
    @Override
    public ServiceWayContentAndFrequencyVO selectServiceWayContentById(Long id) {
        return serviceWayContentMapper.selectServiceWayContentDetailByFrequencyId(id);
    }

    /**
     * 查询服务方式内容列表
     *
     * @param serviceWayContentDTO 服务方式内容
     * @return 服务方式内容集合
     */
    @Override
    public List<ServiceWayContentVO> selectServiceWayContentList(ServiceWayContentDTO serviceWayContentDTO) {
        return serviceWayContentMapper.selectServiceWayContentListV1(serviceWayContentDTO);
    }

    /**
     * 新增服务方式内容
     *
     * @param serviceWayContentAddDTO 服务方式内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertServiceWayContent(ServiceWayContentAddDTO serviceWayContentAddDTO) {
        // 判断服务内容在服务内容表中是否存在
        ServiceWayContentVO serviceWayContentVO = serviceWayContentMapper.countByWayIdAndContent(serviceWayContentAddDTO.getServiceWayId(), serviceWayContentAddDTO.getServiceContent());
        String username = SecurityUtils.getUsername();
        ServiceWayContent serviceFrequency = new ServiceWayContent();
        // 如果服务内容在服务内容表中存在
        if (ObjectUtils.isNotEmpty(serviceWayContentVO)) {
            // 判断服务频次是否在服务频次表中是否存在
            ServiceFrequencyDTO serviceFrequencyDTO = new ServiceFrequencyDTO();
            BeanUtils.copyProperties(serviceWayContentAddDTO, serviceFrequencyDTO);
            serviceFrequencyDTO.setServiceContentId(serviceWayContentVO.getId());
            // 如果当前服务内容下服务频次已存在
            if (serviceWayContentMapper.countByServiceFrequencyDTO(serviceFrequencyDTO) > 0) {
                throw new ServiceException("当前服务内容下服务频次已存在");
            }
            // 如果当前服务内容下服务频次不存在，新增服务频次
            serviceFrequency.setServiceType(ServiceTypeEnum.SERVICE_FREQUENCY.toString());
            serviceFrequency.setServiceContentId(serviceWayContentVO.getId());
            serviceFrequency.setServiceFrequencyType(serviceWayContentAddDTO.getServiceFrequencyType());
            serviceFrequency.setServiceFrequencyText(serviceWayContentAddDTO.getServiceFrequencyText());
            serviceFrequency.setServiceFrequencyStart(serviceWayContentAddDTO.getServiceFrequencyStart());
            serviceFrequency.setServiceFrequencyEnd(serviceWayContentAddDTO.getServiceFrequencyEnd());
            serviceFrequency.setCreateBy(username);
            serviceFrequency.setCreateTime(LocalDateTime.now());
            serviceFrequency.setServiceSort(serviceWayContentAddDTO.getServiceSort());
            if (serviceWayContentMapper.insertServiceWayContent(serviceFrequency) <= 0) {
                throw new ServiceException("新增服务频次失败");
            }
        } else {
            // 如果服务内容在服务内容表不存在，新增服务内容，新增服务频次
            // 新增服务内容
            ServiceWayContent serviceContent = new ServiceWayContent();
            serviceContent.setServiceType(ServiceTypeEnum.SERVICE_CONTENT.toString());
            serviceContent.setServiceWayId(serviceWayContentAddDTO.getServiceWayId());
            serviceContent.setServiceContent(serviceWayContentAddDTO.getServiceContent());
            serviceContent.setCreateBy(username);
            serviceContent.setCreateTime(LocalDateTime.now());
            if (serviceWayContentMapper.insertServiceWayContent(serviceContent) <= 0) {
                throw new ServiceException("新增服务内容失败");
            }
            // 新增服务频次
            serviceFrequency.setServiceType(ServiceTypeEnum.SERVICE_FREQUENCY.toString());
            serviceFrequency.setServiceContentId(serviceContent.getId());
            serviceFrequency.setServiceFrequencyType(serviceWayContentAddDTO.getServiceFrequencyType());
            serviceFrequency.setServiceFrequencyText(serviceWayContentAddDTO.getServiceFrequencyText());
            serviceFrequency.setServiceFrequencyStart(serviceWayContentAddDTO.getServiceFrequencyStart());
            serviceFrequency.setServiceFrequencyEnd(serviceWayContentAddDTO.getServiceFrequencyEnd());
            serviceFrequency.setCreateBy(username);
            serviceFrequency.setCreateTime(LocalDateTime.now());
            serviceFrequency.setServiceSort(serviceWayContentAddDTO.getServiceSort());
            serviceFrequency.setServiceSort(serviceWayContentAddDTO.getServiceSort());
            if (serviceWayContentMapper.insertServiceWayContent(serviceFrequency) <= 0) {
                throw new ServiceException("新增服务频次失败");
            }
        }
        return 1;
    }

    /**
     * 修改服务方式内容
     *
     * @param serviceWayContentEditDTO 服务方式内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateServiceWayContent(ServiceWayContentEditDTO serviceWayContentEditDTO) {
        String username = SecurityUtils.getUsername();
        // 获取当前的服务频次记录
        ServiceWayContent currentFrequency = serviceWayContentMapper.selectServiceWayContentById(serviceWayContentEditDTO.getId());
        if (currentFrequency == null) {
            throw new ServiceException("未找到对应的服务频次记录");
        }
        // 获取当前服务内容的详细信息
        ServiceWayContent currentServiceContent = serviceWayContentMapper.selectServiceWayContentById(currentFrequency.getServiceContentId());
        if (currentServiceContent == null) {
            throw new ServiceException("未找到对应的服务内容记录");
        }
        // 检查服务内容名称是否改变
        boolean serviceContentChanged = !currentServiceContent.getServiceContent().equals(serviceWayContentEditDTO.getServiceContent());
        // 如果服务内容名称改变
        if (serviceContentChanged) {
            // 检查新的服务内容名称是否已存在
            int existingServiceContent = serviceWayContentMapper.selectServiceContentByName(serviceWayContentEditDTO.getServiceContent(), serviceWayContentEditDTO.getServiceWayId());
            if (existingServiceContent > 0) {
                // 如果新服务内容名称已存在，提示错误
                throw new ServiceException("修改后的服务内容已存在");
            } else {
                // 如果新服务内容名称不存在，创建新的服务内容
                ServiceWayContent newServiceContent = new ServiceWayContent();
                newServiceContent.setServiceWayId(serviceWayContentEditDTO.getServiceWayId());
                newServiceContent.setServiceContent(serviceWayContentEditDTO.getServiceContent());
                newServiceContent.setServiceType(ServiceTypeEnum.SERVICE_CONTENT.toString());
                newServiceContent.setCreateBy(username);
                newServiceContent.setCreateTime(LocalDateTime.now());
                serviceWayContentMapper.insertServiceWayContent(newServiceContent);
                // 更新当前频次记录的ServiceContentId为新创建的服务内容ID
                currentFrequency.setServiceContentId(newServiceContent.getId());
            }
        }
        // 检查服务频次是否改变
        boolean serviceFrequencyChanged = !Objects.equals(currentFrequency.getServiceFrequencyType(), serviceWayContentEditDTO.getServiceFrequencyType())
                || !Objects.equals(currentFrequency.getServiceFrequencyText(), serviceWayContentEditDTO.getServiceFrequencyText())
                || !Objects.equals(currentFrequency.getServiceFrequencyStart(), serviceWayContentEditDTO.getServiceFrequencyStart())
                || !Objects.equals(currentFrequency.getServiceFrequencyEnd(), serviceWayContentEditDTO.getServiceFrequencyEnd());

        // 如果服务频次改变了，检查新服务频次的重复性
        if (serviceFrequencyChanged) {
            boolean isFrequencyDuplicate = false;
            if (ServiceFrequencyTypeEnum.TEXT.toString().equals(serviceWayContentEditDTO.getServiceFrequencyType())) {
                isFrequencyDuplicate = serviceWayContentMapper.isServiceFrequencyTextDuplicate(serviceWayContentEditDTO);
            } else if (ServiceFrequencyTypeEnum.DIGIT.toString().equals(serviceWayContentEditDTO.getServiceFrequencyType())) {
                isFrequencyDuplicate = serviceWayContentMapper.isServiceFrequencyDigitDuplicate(serviceWayContentEditDTO);
            }
            if (isFrequencyDuplicate) {
                throw new ServiceException("当前服务内容下服务频次已存在");
            }
        }

        // 更新服务频次
        currentFrequency.setServiceFrequencyType(serviceWayContentEditDTO.getServiceFrequencyType());
        currentFrequency.setServiceFrequencyText(serviceWayContentEditDTO.getServiceFrequencyText());
        currentFrequency.setServiceFrequencyStart(serviceWayContentEditDTO.getServiceFrequencyStart());
        currentFrequency.setServiceFrequencyEnd(serviceWayContentEditDTO.getServiceFrequencyEnd());
        currentFrequency.setServiceSort(serviceWayContentEditDTO.getServiceSort());
        currentFrequency.setUpdateBy(username);
        currentFrequency.setUpdateTime(LocalDateTime.now());

        // 执行更新操作
        if (serviceWayContentMapper.updateServiceFrequency(currentFrequency) <= 0) {
            throw new ServiceException("修改服务频次失败");
        }

        return 1;
    }

    /**
     * 批量删除服务方式内容
     *
     * @param ids 需要删除的服务方式内容主键
     * @return 结果
     */
    @Override
    public int deleteServiceWayContentByIds(Long[] ids) {
        return serviceWayContentMapper.deleteServiceWayContentByIds(ids);
    }

    /**
     * 删除服务方式内容信息
     *
     * @param id 服务方式内容主键
     * @return 结果
     */
    @Override
    public int deleteServiceWayContentById(Long id) {
        return serviceWayContentMapper.deleteServiceWayContentById(id);
    }

    /**
     * 查询服务方式列表
     */
    @Override
    public List<ServiceWayContentAndNumVO> selectListNum(String serviceWayName, Long id) {
        return serviceWayContentMapper.selectListNum(serviceWayName, id);
    }

    /**
     * 新增服务方式
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertServiceWay(ServiceWayContent serviceWayContent) {
        // 查询服务方式名称是否存在
        int existNameCount = serviceWayContentMapper.countByServiceName(serviceWayContent.getServiceWayName());
        // 若size >0,则服务名称已存在
        if (existNameCount > 0) {
            throw new ServiceException("服务方式名称已存在");
        }
        // 如果不存在，执行新增功能
        serviceWayContent.setServiceWayCode(Constants.SERVICE_MODE_ENCODING + systemCodeUtil.generateDepartCode(Constants.SERVICE_MODE_ENCODING));
        serviceWayContent.setServiceType(ServiceTypeEnum.SERVICE_WRY.toString());
        serviceWayContent.setCreateBy(SecurityUtils.getUsername());
        serviceWayContent.setCreateTime(LocalDateTime.now());
        return serviceWayContentMapper.insertServiceWayContent(serviceWayContent);
    }

    /**
     * 修改服务方式
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int editServiceWay(ServiceWayContent serviceWayContent) {
        // 查询服务方式名称是否存在
        int existNameCount = serviceWayContentMapper.countByServiceName(serviceWayContent.getServiceWayName());
        // 若size >0,则服务名称已存在
        if (existNameCount > 0) {
            throw new ServiceException("服务方式名称已存在");
        }
        // 如果不存在，执行修改功能
        serviceWayContent.setUpdateBy(SecurityUtils.getUsername());
        serviceWayContent.setUpdateTime(LocalDateTime.now());
        return serviceWayContentMapper.updateServiceWay(serviceWayContent);
    }

    /**
     * 根据id删除服务方式
     */
    @Override
    public int deleteServiceWayById(Long id) {
        // 判断该服务方式下是否有关联记录，如果有且数量不为0，则不能删除
        List<ServiceWayContentAndNumVO> voList = serviceWayContentMapper.selectListNum(null, id);
        boolean hasAssociatedContent = voList.stream()
                .anyMatch(vo -> vo.getServiceContentNum() != null && vo.getServiceContentNum() > 0);

        if (hasAssociatedContent) {
            throw new ServiceException("该服务方式下有服务内容，请先删除服务内容");
        }

        // 如果没有关联记录或数量为0，则可以删除服务方式
        return serviceWayContentMapper.deleteServiceWayById(id);
    }

    /**
     * 根据服务方式id获取服务方式
     */
    @Override
    public String selectServiceWayById(Long id) {
        return serviceWayContentMapper.selectServiceWayById(id);
    }

    /**
     * 根据服务频次id删除服务内容
     */
    @Override
    public int deleteByFrequencyId(Long id) {
        return serviceWayContentMapper.deleteByFrequencyId(id);
    }
}
