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

import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.department.Department;
import com.xinelu.manage.dto.department.DepartmentDTO;
import com.xinelu.manage.mapper.department.DepartmentMapper;
import com.xinelu.manage.service.department.IDepartmentService;
import com.xinelu.manage.vo.department.DepartmentListVO;
import com.xinelu.manage.vo.department.DepartmentVO;
import com.xinelu.system.mapper.SysUserMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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


/**
 * 科室信息Service业务层处理
 *
 * @author xinelu
 * @date 2024-02-26
 */
@Service
public class DepartmentServiceImpl implements IDepartmentService {
    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 查询科室信息
     *
     * @param id 科室信息主键
     * @return 科室信息
     */
    @Override
    public DepartmentListVO selectDepartmentById(Long id) {
        return departmentMapper.selectDepartment(id);
    }

    /**
     * 查询科室信息列表
     *
     * @param department 科室信息
     * @return 科室信息
     */
    @Override
    public List<Department> selectDepartmentList(Department department) {
        return departmentMapper.selectDepartmentList(department);
    }

    /**
     * 查询科室信息列表 问卷使用
     *
     * @return 科室信息集合
     */
    @Override
    public AjaxResult selectUserDepartment() {
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        List<Department> departments = new ArrayList<>();
        if (Objects.nonNull(sysUser) && Objects.nonNull(sysUser.getAgencyId())) {
            Department department = new Department();
            department.setAgencyId(sysUser.getAgencyId());
            departments = departmentMapper.selectDepartmentList(department);
        }
        return AjaxResult.success(departments);
    }

    /**
     * 查询科室或病区信息列表 不分页
     *
     * @param department 科室信息
     * @return 科室信息
     */
    @Override
    public AjaxResult selectDepartmentByAgencyIdList(Department department) {
        if (Objects.isNull(department) || (Objects.isNull(department.getAgencyId()) && Objects.isNull(department.getParentDepartmentId()))) {
            return AjaxResult.success();
        }
        return AjaxResult.success(departmentMapper.selectDepartmentList(department));
    }

    /**
     * 新增科室信息
     *
     * @param department 科室信息
     * @return 结果
     */
    @Override
    public int insertDepartment(Department department) {
        if (Objects.isNull(department.getParentDepartmentId())) {
            department.setParentDepartmentId(0L);
        }
        department.setCreateTime(LocalDateTime.now());
        department.setCreateBy(SecurityUtils.getUsername());
        return departmentMapper.insertDepartment(department);
    }

    /**
     * 修改科室信息
     *
     * @param department 科室信息
     * @return 结果
     */
    @Override
    public int updateDepartment(Department department) {
        department.setUpdateBy(SecurityUtils.getUsername());
        department.setUpdateTime(LocalDateTime.now());
        return departmentMapper.updateDepartmentById(department);
    }

    /**
     * 批量删除科室信息
     *
     * @param ids 需要删除的科室信息主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteDepartmentByIds(Long[] ids) {
        int size = departmentMapper.selectDepartmentByParentId(ids).size();
        if (size > 0) {
            return AjaxResult.error("该科室存在下级科室，请先删除其下级科室！");
        }
        return AjaxResult.success(departmentMapper.deleteDepartmentByIds(ids));
    }

    /**
     * 删除科室信息信息
     *
     * @param id 科室信息主键
     * @return 结果
     */
    @Override
    public int deleteDepartmentById(Long id) {
        return departmentMapper.deleteDepartmentById(id);
    }

    /**
     * 查询科室信息列表及包含话术数量
     *
     * @param departmentDto 科室信息
     * @return 结果
     */
    @Override
    public List<DepartmentVO> selectDepartmentListScriptNum(DepartmentDTO departmentDto) {
        return departmentMapper.selectDepartmentListScriptNum(departmentDto);
    }

    /**
     * 查询科室信息列表及包含手术数量
     *
     * @param departmentDto 科室信息
     * @return 结果
     */
    @Override
    public List<DepartmentVO> selectDepartmentListOperationNum(DepartmentDTO departmentDto) {
        return departmentMapper.selectDepartmentListOperationNum(departmentDto);
    }

    /**
     * 查询科室信息列表及包含微信库数量
     *
     * @param departmentDto 科室信息
     * @return 结果
     */
    @Override
    public List<DepartmentVO> selectDepartmentListWechatTemplateNum(DepartmentDTO departmentDto) {
        return departmentMapper.selectDepartmentListWechatTemplateNum(departmentDto);
    }

    /**
     * 查询科室信息列表及包含短信库数量
     *
     * @param departmentDto 科室信息
     * @return 结果
     */
    @Override
    public List<DepartmentVO> selectDepartmentListMessageNum(DepartmentDTO departmentDto) {
        return departmentMapper.selectDepartmentListMessageNum(departmentDto);
    }

    /**
     * 科室信息导入
     *
     * @param departmentList 科室信息
     * @return 结果
     */

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertDepartmentList(List<Department> departmentList) {
        //判断添加的数据是否为空
        if (CollectionUtils.isEmpty(departmentList)) {
            return AjaxResult.error("请添加科室导入信息！");
        }
        //根据护理站名称做去除处理
        List<Department> importDataList = departmentList.stream().filter(item -> StringUtils.isNotBlank(item.getDepartmentName())).distinct().collect(Collectors.toList());
        //校验联系电话格式是否正确
        Department department = importDataList.stream().filter(item -> StringUtils.isNotBlank(item.getDepartmentPhone())).filter(item -> BooleanUtils.isFalse(regexUtil.regexPhone(item.getDepartmentPhone()))).findFirst().orElse(new Department());
        if (StringUtils.isNotBlank(department.getDepartmentPhone())) {
            return AjaxResult.error("当前科室电话：" + department.getDepartmentPhone() + " 格式不正确，请重新录入！");
        }
        List<String> departmentName = importDataList.stream().filter(item -> StringUtils.isNotBlank(item.getDepartmentName())).map(Department::getDepartmentName).distinct().collect(Collectors.toList());
        //根据名称查询护理站基本信息
        List<Department> allDepartment = departmentMapper.getAllDepartmentInfo(departmentName);
        //做差集，去除数据库中已经存在的护理站信息
        List<Department> subtractList = new ArrayList<>(CollectionUtils.subtract(importDataList, allDepartment));
        if (CollectionUtils.isEmpty(subtractList)) {
            return AjaxResult.success();
        }
        List<Department> saveDepartmentList = new ArrayList<>();
        for (Department item : subtractList) {
            if (Objects.isNull(item.getParentDepartmentId())) {
                item.setParentDepartmentId(0L);
            }
            item.setCreateBy(SecurityUtils.getUsername());
            item.setCreateTime(LocalDateTime.now());
            Department newDepartment = new Department();
            BeanUtils.copyProperties(item, newDepartment);
            saveDepartmentList.add(newDepartment);
        }
        int insertCount = departmentMapper.insertDepartmentList(saveDepartmentList);
        if (insertCount <= 0) {
            throw new ServiceException("导入科室信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 查询科室信息列表及包含服务包数量
     *
     * @param departmentDto 科室
     * @return 结果
     */
    @Override
    public List<DepartmentVO> selectListServicePackageNum(DepartmentDTO departmentDto) {
        return departmentMapper.selectListServicePackageNum(departmentDto);
    }
}
