package org.dromara.business.controller;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.business.domain.vo.CaseBaseInfoVo;
import org.dromara.business.domain.vo.DoctorUserVo;
import org.dromara.business.domain.vo.DoctorVolunteerVo;
import org.dromara.business.domain.vo.VolunteerUserVo;
import org.dromara.business.service.ICaseBaseInfoService;
import org.dromara.business.utils.SmsUtils;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.SmsConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.system.domain.SysSmsConfig;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.CaseMessageBo;
import org.dromara.system.domain.bo.SysDoctorVolunteerBo;
import org.dromara.system.domain.vo.SysDoctorVolunteerVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ICaseMessageService;
import org.dromara.system.service.ISysDoctorVolunteerService;
import org.dromara.system.service.ISysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 医生志愿者关联
 *
 * @author wuzhigang
 * @date 2023-12-21
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/doctorVolunteer")
public class DoctorVolunteerController extends BaseController {

    private final ISysDoctorVolunteerService sysDoctorVolunteerService;
    private final ISysUserService userService;
    private final ICaseBaseInfoService caseBaseInfoService;
    private final ICaseMessageService caseMessageService;

    /**
     * 查询医生志愿者关联列表
     */
    @GetMapping("/list")
    public TableDataInfo<SysDoctorVolunteerVo> list(SysDoctorVolunteerBo bo, PageQuery pageQuery) {
        return sysDoctorVolunteerService.queryPageList(bo, pageQuery);
    }

    /**
     * 医生获取已绑定志愿者列表
     */
    @GetMapping("/volunteerList")
    public R<List<DoctorVolunteerVo>> volunteerList() {
        List<DoctorVolunteerVo> result = new ArrayList<>();
        // 医生ID
        Long doctorUserId = LoginHelper.getUserId();
        // 绑定志愿者列表
        List<SysDoctorVolunteerVo> sysDoctorVolunteerVoList = sysDoctorVolunteerService.volunteerList(doctorUserId);
        if (sysDoctorVolunteerVoList != null && sysDoctorVolunteerVoList.size() > 0) {
            // 自愿者userId列表
            List<Long> volunteerUserIds = sysDoctorVolunteerVoList.stream().map(SysDoctorVolunteerVo::getVolunteerUserId).collect(Collectors.toList());
            // 获取志愿者用户信息
            List<SysUser> sysUserVoList = userService.selectUserListByIds(volunteerUserIds);
            // 根据志愿者userIds,医生userId查询志愿者上传病例列表
            List<CaseBaseInfoVo> caseBaseInfoVoList = caseBaseInfoService.selectCaseListByVolunteerUserIds(volunteerUserIds, doctorUserId);
            // 根据志愿者userId分组
            Map<Long, List<CaseBaseInfoVo>> groupByUploadUserIdMap =
                caseBaseInfoVoList.stream().collect(Collectors.groupingBy(CaseBaseInfoVo::getUploadUserId));

            if (sysUserVoList != null && sysUserVoList.size() > 0) {
                for (SysDoctorVolunteerVo vo : sysDoctorVolunteerVoList
                ) {
                    DoctorVolunteerVo doctorVolunteerVo = new DoctorVolunteerVo();
                    doctorVolunteerVo.setId(vo.getId());
                    doctorVolunteerVo.setDoctorUserId(vo.getDoctorUserId());
                    doctorVolunteerVo.setVolunteerUserId(vo.getVolunteerUserId());
                    // 根据志愿者userId获取用户信息
                    SysUser sysUser = sysUserVoList.stream().filter(o -> o.getUserId().equals(vo.getVolunteerUserId())).findFirst().get();
                    doctorVolunteerVo.setVolunteerUser(sysUser);
                    // 获取单一志愿者上传病例列表
                    List<CaseBaseInfoVo> voList = groupByUploadUserIdMap.get(vo.getVolunteerUserId());
                    if (voList != null && voList.size() > 0) {
                        doctorVolunteerVo.setCaseNumber(voList.size());
                        doctorVolunteerVo.setCaseBaseInfoVoList(voList);
                    } else {
                        doctorVolunteerVo.setCaseNumber(0);
                    }

                    result.add(doctorVolunteerVo);
                }
            }

        }

        return R.ok(result);
    }

    /**
     * 志愿者获取已绑定医生列表
     */
    @GetMapping("/doctorList")
    public R<List<DoctorVolunteerVo>> doctorList() {
        List<DoctorVolunteerVo> result = new ArrayList<>();
        // 志愿者ID
        Long volunteerUserId = LoginHelper.getUserId();
        // 绑定医生列表
        List<SysDoctorVolunteerVo> sysDoctorVolunteerVoList = sysDoctorVolunteerService.doctorList(volunteerUserId);
        if (sysDoctorVolunteerVoList != null && sysDoctorVolunteerVoList.size() > 0) {
            // 医生userId列表
            List<Long> doctorUserIds = sysDoctorVolunteerVoList.stream().map(SysDoctorVolunteerVo::getDoctorUserId).collect(Collectors.toList());
            // 获取医生用户信息
            List<SysUser> sysUserVoList = userService.selectUserListByIds(doctorUserIds);
            // 根据医生userIds查询志愿者上传病例列表
            List<CaseBaseInfoVo> caseBaseInfoVoList = caseBaseInfoService.selectCaseListByDoctorUserIds(doctorUserIds, volunteerUserId);
            // 根据医生userId分组
            Map<Long, List<CaseBaseInfoVo>> groupByUploadUserIdMap =
                caseBaseInfoVoList.stream().collect(Collectors.groupingBy(CaseBaseInfoVo::getUserId));

            if (sysUserVoList != null && sysUserVoList.size() > 0) {
                for (SysDoctorVolunteerVo vo : sysDoctorVolunteerVoList
                ) {
                    DoctorVolunteerVo doctorVolunteerVo = new DoctorVolunteerVo();
                    doctorVolunteerVo.setId(vo.getId());
                    doctorVolunteerVo.setDoctorUserId(vo.getDoctorUserId());
                    doctorVolunteerVo.setVolunteerUserId(vo.getVolunteerUserId());
                    // 根据医生userId获取用户信息
                    SysUser sysUser = sysUserVoList.stream().filter(o -> o.getUserId().equals(vo.getDoctorUserId())).findFirst().get();
                    doctorVolunteerVo.setDoctorUser(sysUser);
                    // 获取志愿者上传病例列表
                    List<CaseBaseInfoVo> voList = groupByUploadUserIdMap.get(vo.getDoctorUserId());
                    if (voList != null && voList.size() > 0) {
                        doctorVolunteerVo.setCaseNumber(voList.size());
                        doctorVolunteerVo.setCaseBaseInfoVoList(voList);
                    } else {
                        doctorVolunteerVo.setCaseNumber(0);
                    }

                    result.add(doctorVolunteerVo);
                }
            }

        }

        return R.ok(result);
    }


    /**
     * 已绑定志愿者下拉列表
     */
    @GetMapping("/volunteerSelectList")
    public R<List<VolunteerUserVo>> volunteerSelectList() {
        List<VolunteerUserVo> result = new ArrayList<>();
        // 绑定志愿者列表
        List<SysDoctorVolunteerVo> sysDoctorVolunteerVoList = sysDoctorVolunteerService.volunteerList(LoginHelper.getUserId());
        if (sysDoctorVolunteerVoList != null && sysDoctorVolunteerVoList.size() > 0) {
            // 自愿者userId列表
            List<Long> volunteerUserIds = sysDoctorVolunteerVoList.stream().map(SysDoctorVolunteerVo::getVolunteerUserId).collect(Collectors.toList());
            // 获取志愿者用户信息
            List<SysUser> sysUserVoList = userService.selectUserListByIds(volunteerUserIds);
            // 志愿者用户不为空
            if (sysUserVoList != null && sysUserVoList.size() > 0) {
                for (Long volunteerUserId : volunteerUserIds
                ) {
                    VolunteerUserVo volunteerUserVo = new VolunteerUserVo();
                    volunteerUserVo.setVolunteerUserId(volunteerUserId);
                    // 根据志愿者userId获取用户信息
                    SysUser sysUser = sysUserVoList.stream().filter(o -> o.getUserId().equals(volunteerUserId)).findFirst().get();
                    volunteerUserVo.setVolunteerUserName(sysUser.getNickName());
                    result.add(volunteerUserVo);
                }
            }
        }

        return R.ok(result);
    }

    /**
     * 已绑定医生下拉列表
     */
    @GetMapping("/doctorSelectList")
    public R<List<DoctorUserVo>> doctorSelectList() {
        List<DoctorUserVo> result = new ArrayList<>();
        // 绑定医生列表
        List<SysDoctorVolunteerVo> sysDoctorVolunteerVoList = sysDoctorVolunteerService.doctorList(LoginHelper.getUserId());
        if (sysDoctorVolunteerVoList != null && sysDoctorVolunteerVoList.size() > 0) {
            // 医生userId列表
            List<Long> doctorUserIds = sysDoctorVolunteerVoList.stream().map(SysDoctorVolunteerVo::getDoctorUserId).collect(Collectors.toList());
            // 获取医生用户信息
            List<SysUser> sysUserVoList = userService.selectUserListByIds(doctorUserIds);
            // 医生用户不为空
            if (sysUserVoList != null && sysUserVoList.size() > 0) {
                for (Long doctorUserId : doctorUserIds
                ) {
                    DoctorUserVo doctorUserVo = new DoctorUserVo();
                    doctorUserVo.setDoctorUserId(doctorUserId);
                    // 根据志愿者userId获取用户信息
                    SysUser sysUser = sysUserVoList.stream().filter(o -> o.getUserId().equals(doctorUserId)).findFirst().get();
                    doctorUserVo.setDoctorUserName(sysUser.getNickName());
                    result.add(doctorUserVo);
                }
            }

        }

        return R.ok(result);
    }


    /**
     * 获取医生志愿者关联详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<SysDoctorVolunteerVo> getInfo(@NotNull(message = "主键不能为空")
                                           @PathVariable Long id) {
        return R.ok(sysDoctorVolunteerService.queryById(id));
    }

    /**
     * 新增医生志愿者关联
     */
    @Log(title = "医生志愿者关联", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysDoctorVolunteerBo bo) {
        return toAjax(sysDoctorVolunteerService.insertByBo(bo));
    }

    /**
     * 医生绑定志愿者
     */
    @Log(title = "医生绑定志愿者", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/bindVolunteer")
    public R<Void> bindVolunteer(@RequestBody SysDoctorVolunteerBo bo) {

        SysUser user = sysDoctorVolunteerService.bindVolunteer(bo);

        if (user != null) {

            // 获取缓存SMS短信配置
            String json = CacheUtils.get(CacheNames.SYS_SMS_CONFIG, SmsConstants.DOCTORS_BIND_VOLUNTEERS);
            SysSmsConfig sysSmsConfig = JsonUtils.parseObject(json, SysSmsConfig.class);
            if (sysSmsConfig.getStatus().equals(SmsConstants.SMS_ENABLE)) {
                LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
                // 医生姓名
                map.put("name", LoginHelper.getNickname());
                // 志愿者短信通知
                SmsResponse smsResponse = SmsUtils.sendAlibabaMessage(user.getPhonenumber(), SmsConstants.DOCTORS_BIND_VOLUNTEERS, map);
                if (!"OK".equals(smsResponse.getCode())) {
                    log.error("医生绑定志愿者通知短信发送异常 => {}", smsResponse);
                    return R.fail(smsResponse.getMessage());
                }
            }

            // 志愿者消息
            CaseMessageBo userMessageBo = new CaseMessageBo();
            userMessageBo.setMessageContent("医生" + LoginHelper.getNickname() + "已和您");
            userMessageBo.setMessageType("1");
            userMessageBo.setUserId(user.getUserId());
            userMessageBo.setBusinessStatus("3");
            caseMessageService.insertByBo(userMessageBo);

        }
        return R.ok();
    }

    /**
     * 志愿者绑定医生
     */
    @Log(title = "志愿者绑定医生", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/bindDoctor")
    public R<Void> bindDoctor(@RequestBody SysDoctorVolunteerBo bo) {
        SysUser user = sysDoctorVolunteerService.bindDoctor(bo);

        if (user != null) {
            // 获取缓存SMS短信配置
            String json = CacheUtils.get(CacheNames.SYS_SMS_CONFIG, SmsConstants.VOLUNTEERS_BIND_DOCTORS);
            SysSmsConfig sysSmsConfig = JsonUtils.parseObject(json, SysSmsConfig.class);
            if (sysSmsConfig.getStatus().equals(SmsConstants.SMS_ENABLE)) {
                LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
                // 志愿者姓名
                map.put("name", LoginHelper.getNickname());
                // 医生短信通知
                SmsResponse smsResponse = SmsUtils.sendAlibabaMessage(user.getPhonenumber(), SmsConstants.VOLUNTEERS_BIND_DOCTORS, map);
                if (!"OK".equals(smsResponse.getCode())) {
                    log.error("志愿者绑定医生通知短信发送异常 => {}", smsResponse);
                    return R.fail(smsResponse.getMessage());
                }
            }

            // 医生消息
            CaseMessageBo userMessageBo = new CaseMessageBo();
            userMessageBo.setMessageContent("志愿者" + LoginHelper.getNickname() + "已和您");
            userMessageBo.setMessageType("1");
            userMessageBo.setUserId(user.getUserId());
            userMessageBo.setBusinessStatus("3");
            caseMessageService.insertByBo(userMessageBo);
        }
        return R.ok();
    }

    /**
     * 修改医生志愿者关联
     */
    @Log(title = "医生志愿者关联", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysDoctorVolunteerBo bo) {
        return toAjax(sysDoctorVolunteerService.updateByBo(bo));
    }

    /**
     * 删除医生志愿者关联
     *
     * @param ids 主键串
     */
    @Log(title = "医生志愿者关联", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        // 医生志愿者关联信息
        SysDoctorVolunteerVo sysDoctorVolunteerVo = sysDoctorVolunteerService.queryById(ids[0]);
        boolean result = sysDoctorVolunteerService.deleteWithValidByIds(List.of(ids), true);
        if (result) {

            // 医生信息
            SysUserVo doctor = userService.selectUserById(sysDoctorVolunteerVo.getDoctorUserId());
            // 志愿者信息
            SysUserVo volunteer = userService.selectUserById(sysDoctorVolunteerVo.getVolunteerUserId());

            // 获取缓存SMS短信配置
            String json = CacheUtils.get(CacheNames.SYS_SMS_CONFIG, SmsConstants.DOCTOR_VOLUNTEERS_UNBIND);
            SysSmsConfig sysSmsConfig = JsonUtils.parseObject(json, SysSmsConfig.class);
            if (sysSmsConfig.getStatus().equals(SmsConstants.SMS_ENABLE)) {
                LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
                // 当前登录人身份-医生
                if (sysDoctorVolunteerVo.getDoctorUserId().equals(LoginHelper.getUserId())) {

                    // 医生姓名
                    map.put("name", doctor.getNickName());
                    // 志愿者短信通知
                    SmsResponse smsResponse = SmsUtils.sendAlibabaMessage(volunteer.getPhonenumber(), SmsConstants.DOCTOR_VOLUNTEERS_UNBIND, map);
                    if (!"OK".equals(smsResponse.getCode())) {
                        log.error("医生解绑志愿者通知短信发送异常 => {}", smsResponse);
                        return R.fail(smsResponse.getMessage());
                    }

                    // 志愿者消息
                    CaseMessageBo userMessageBo = new CaseMessageBo();
                    userMessageBo.setMessageContent("医生" + doctor.getNickName() + "已和您");
                    userMessageBo.setMessageType("1");
                    userMessageBo.setUserId(sysDoctorVolunteerVo.getVolunteerUserId());
                    userMessageBo.setBusinessStatus("4");
                    caseMessageService.insertByBo(userMessageBo);
                }

                // 当前登录人身份-志愿者
                if (sysDoctorVolunteerVo.getVolunteerUserId().equals(LoginHelper.getUserId())) {
                    // 志愿者姓名
                    map.put("name", volunteer.getNickName());
                    // 医生短信通知
                    SmsResponse smsResponse = SmsUtils.sendAlibabaMessage(doctor.getPhonenumber(), SmsConstants.DOCTOR_VOLUNTEERS_UNBIND, map);
                    if (!"OK".equals(smsResponse.getCode())) {
                        log.error("志愿者解绑医生通知短信发送异常 => {}", smsResponse);
                        return R.fail(smsResponse.getMessage());
                    }

                    // 医生消息
                    CaseMessageBo userMessageBo = new CaseMessageBo();
                    userMessageBo.setMessageContent("志愿者" + volunteer.getNickName() + "已和您");
                    userMessageBo.setMessageType("1");
                    userMessageBo.setUserId(sysDoctorVolunteerVo.getDoctorUserId());
                    userMessageBo.setBusinessStatus("4");
                    caseMessageService.insertByBo(userMessageBo);
                }

            }


        }
        return toAjax(result);
    }
}
