package com.fs.app.controller;

import com.fs.app.utils.JwtUtils;
import com.fs.common.annotation.Log;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.core.page.TableDataInfo;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.enums.BusinessType;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.SecurityUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.his.domain.*;
import com.fs.his.dto.FsPrescribeRecordRejectDto;
import com.fs.his.dto.PrescribeRejectDTO;
import com.fs.his.mapper.FsPatientMapper;
import com.fs.his.param.FsPrescribeParam;
import com.fs.his.param.WaitPrescribeParam;
import com.fs.his.service.IFsDoctorService;
import com.fs.his.service.IFsExportTaskService;
import com.fs.his.service.IFsPrescribeRecordService;
import com.fs.his.service.IFsPrescribeService;
import com.fs.his.vo.FsPrescribeListVO;
import com.fs.his.vo.FsPrescribeRecordRejectVo;
import com.fs.his.vo.FsPrescribeVO;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 处方Controller
 *
 * @author fs
 * @date 2023-06-13
 */
@RestController
@RequestMapping("/his/prescribe")
public class FsPrescribeController extends BaseController
{
    @Autowired
    private IFsPrescribeService fsPrescribeService;

    @Autowired
    private IFsExportTaskService exportTaskService;
    @Autowired
    private FsPatientMapper fsPatientMapper;

    @Autowired
    private IFsPrescribeRecordService prescribeRecordService;

    @Autowired
    private IFsDoctorService doctorService;

    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    RedisCache redisCache;
    /**
     * 确认处方
     * @param param 处方
     * @return AjaxResult
     */
    @PostMapping("/confirmPrescribe")
    public AjaxResult confirmPrescribe(FsPrescribeParam param){
        fsPrescribeService.confirmPrescribe(param);
        return AjaxResult.success();
    }
    /**
     * 医生拒方
     */
    @PutMapping("/handleReject")
    public R handleReject(@RequestBody PrescribeRejectDTO rejectDTO){
        try {
            rejectDTO.setTerminatedBy(Long.valueOf(getDoctorId())); //这里似乎获取不到用户信息
        } catch (CustomException e){
            logger.error("获取拒访医生信息失败");
        }
        fsPrescribeService.handleReject(rejectDTO);
        return R.ok();
    }
    /**
     * 查询处方列表
     */
    @GetMapping("/list")
    public TableDataInfo list(FsPrescribeParam fsPrescribe)
    {
        //前后端时间参数命名不一致 这里统一处理
        if (fsPrescribe.getBeginCreateTime()!=null&&fsPrescribe.getEndCreateTime()!=null){
            fsPrescribe.setSTime(fsPrescribe.getBeginCreateTime());
            fsPrescribe.setETime(fsPrescribe.getEndCreateTime());
        }
        if (fsPrescribe.getBeginAuditTime()!=null&&fsPrescribe.getEndAuditTime()!=null){
            fsPrescribe.setAuditSTime(fsPrescribe.getBeginAuditTime());
            fsPrescribe.setAuditETime(fsPrescribe.getEndAuditTime());
        }
        startPage();
        List<FsPrescribeListVO> list = fsPrescribeService.selectFsPrescribeListVOWithConfirm(fsPrescribe);
        for (FsPrescribeListVO vo : list){
            vo.setRefuseCount(prescribeRecordService.selectRefuseCount(vo.getPrescribeId()));
            if (vo.getPatientTel()!=null){
                vo.setPatientTel(vo.getPatientTel().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
            }
            if (vo.getOperateTime() != null) {
                int totalSeconds = Integer.parseInt(vo.getOperateTime());
                long minutes = TimeUnit.SECONDS.toMinutes(totalSeconds);
                long seconds = totalSeconds - TimeUnit.MINUTES.toSeconds(minutes);
                vo.setOperateTime(minutes + "分" + seconds + "秒");
            } else {
                vo.setOperateTime("-");
            }
        }
        return getDataTable(list);
    }
    /**
     * 统计拒方数量
     * */
    @PostMapping("/rejectCount")
    public R refuseCount(@RequestBody FsPrescribeRecordRejectDto rejectDto){
        FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
        if (doctor==null){
            return R.error("用户不存在");
        }
        //获取当前用户(药师id)
        rejectDto.setDrugDoctorId(doctor.getDoctorId());
        PageInfo<FsPrescribeRecordRejectVo> fsPrescribeRecordRejectVoPageInfo = prescribeRecordService.calculateRejectCount(rejectDto);
        return R.ok().put("data", fsPrescribeRecordRejectVoPageInfo);
    }

    /**
     * 导出处方列表
     */
    @PreAuthorize("@ss.hasPermi('his:prescribe:export')")
    @Log(title = "处方", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(FsPrescribeParam fsPrescribe)
    {
        Integer exportType1 = exportTaskService.isExportType1(SecurityUtils.getUserId());
        if (exportType1>0){
            return AjaxResult.error("你已经有正在导出的任务");
        }
        if (fsPrescribeService.isEntityNull(fsPrescribe)){
            return AjaxResult.error("请筛选数据导出");
        }
        logger.info("tc>\n【导出处方】：{}", SecurityUtils.getUserId());
        Long count = fsPrescribeService.selectFsPrescribeExcelListVOCount(fsPrescribe);
        if (count>30000){
            return AjaxResult.error("导出数据不可超过3w条");
        }
        FsExportTask task=new FsExportTask();
        task.setTaskType(5);
        task.setStatus(0);
        task.setStartTime(new Date());
        task.setRemark("处方单导出");
        task.setSysType(1);
        task.setUserId(SecurityUtils.getUserId());
        exportTaskService.insertFsExportTask(task);
        fsPrescribe.setTaskId(task.getTaskId());
        fsPrescribeService.exportData(fsPrescribe);
        return new AjaxResult(200,"后台正在导出,请等待...任务ID:"+task.getTaskId(),task.getTaskId());

    }

    /**
     * 导出医疗信息反馈单
     */
    @PreAuthorize("@ss.hasPermi('his:prescribe:messageFeedbackExport')")
    @Log(title = "医疗信息反馈单", businessType = BusinessType.EXPORT)
    @GetMapping("/messageFeedbackExport")
    public AjaxResult messageFeedbackExport(FsPrescribeParam fsPrescribe)
    {
        logger.info("tc>\n【导出医疗信息反馈单】：{}", SecurityUtils.getUserId());
        if (fsPrescribeService.isEntityNull(fsPrescribe)){
            return AjaxResult.error("请筛选数据导出");
        }
        Integer exportType1 = exportTaskService.isExportType1(SecurityUtils.getUserId());
        if (exportType1>0){
            return AjaxResult.error("你已经有正在导出的任务");
        }

        FsExportTask task=new FsExportTask();
        task.setTaskType(6);
        task.setStatus(0);
        task.setStartTime(new Date());
        task.setRemark("处方医疗反馈清单导出");
        task.setSysType(1);
        task.setUserId(SecurityUtils.getUserId());
        exportTaskService.insertFsExportTask(task);
        fsPrescribe.setTaskId(task.getTaskId());
        fsPrescribeService.exportMessageFeedback(fsPrescribe);
        return new AjaxResult(200,"后台正在导出,请等待...任务ID:"+task.getTaskId(),task.getTaskId());
    }

    /**
     * 获取处方详细信息
     */
    @Transactional(rollbackFor = Exception.class)
    @GetMapping(value = "/{prescribeId}")
    public AjaxResult getInfo(@PathVariable("prescribeId") Long prescribeId)
    {

        FsPrescribeVO fsPrescribe = fsPrescribeService.selectFsPrescribeByPrescribeIdVO(prescribeId);
        if (fsPrescribe.getPatientTel()!=null){
            fsPrescribe.setPatientTel(fsPrescribe.getPatientTel().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
        }
        FsPatient fsPatient = fsPatientMapper.selectFsPatientByPatientId(fsPrescribe.getPatientId());
        if (fsPatient!=null&&fsPatient.getIdCard()!=null){
            fsPrescribe.setIdCard(fsPatient.getIdCard().replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1**********$2"));
        }
        return AjaxResult.success(fsPrescribe);
    }

    /**
     * 获取处方详细信息
     */

    @GetMapping("/Drug/{prescribeId}")
    public AjaxResult getDrugInfo(@PathVariable("prescribeId") Long prescribeId)
    {
        return AjaxResult.success(fsPrescribeService.selectFsPrescribeDrugByPrescribeIdVO(prescribeId));
    }

    /**
     * 新增处方
     */
    @Log(title = "新增处方", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FsPrescribe fsPrescribe)
    {
        return toAjax(fsPrescribeService.insertFsPrescribe(fsPrescribe));
    }

    /**
     * 修改处方
     */
    @Log(title = "修改处方", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FsPrescribe fsPrescribe)
    {
        int i = fsPrescribeService.updateFsPrescribe(fsPrescribe);
        fsPrescribeService.delUrl(fsPrescribe.getPrescribeId());
        exportTaskService.updateFsExportTaskByPrescribeId(fsPrescribe.getPrescribeId());
        return toAjax(i);
    }

    /**
     * 删除处方
     */
    @Log(title = "删除处方", businessType = BusinessType.DELETE)
	@DeleteMapping("/{prescribeIds}")
    public AjaxResult remove(@PathVariable Long[] prescribeIds)
    {
        return toAjax(fsPrescribeService.deleteFsPrescribeByPrescribeIds(prescribeIds));
    }

    //获取审核记录数据
    @GetMapping(value = "/recordList/{prescribeId}")
    public AjaxResult selectRecordListByPrescribeId(@PathVariable("prescribeId") Long prescribeId){
        return AjaxResult.success(prescribeRecordService.selectRecordListByPrescribeId(prescribeId));
    }

    //查询医生待开方列表--个微后付款版
    @PostMapping("/waitPrescribeAfterPaymentList")
    public TableDataInfo waitPrescribeList(@RequestBody WaitPrescribeParam waitPrescribeParam) {
        startPage();
        List<FsPrescribeListVO> list = fsPrescribeService.selectWaitPrescribeList(waitPrescribeParam);
        for (FsPrescribeListVO vo : list){
            vo.setRefuseCount(prescribeRecordService.selectRefuseCount(vo.getPrescribeId()));
            if (vo.getPatientTel()!=null){
                vo.setPatientTel(vo.getPatientTel().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
            }
        }
        return getDataTable(list);
    }

    /**
     * 医生确认处方--个微后付款版
     * @param param 处方
     * @return AjaxResult
     */
    @PostMapping("/confirmPrescribeAfterPayment")
    public AjaxResult confirmPrescriptionMicroPayment(@RequestBody FsPrescribeParam param){
        fsPrescribeService.confirmPrescribeAfterPayment(param);
        return AjaxResult.success();
    }

    public String getDoctorId()
    {
        String headValue =  ServletUtils.getRequest().getHeader("APPToken");
        Claims claims=jwtUtils.getClaimByToken(headValue);
        String doctorId = claims.getSubject().toString();
        return doctorId;
    }

}
