package com.fs.hospital.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.fs.hospital.domain.*;
import com.fs.hospital.mapper.*;
import com.fs.hospital.param.HospitalOutpatientOrderFinishParam;
import com.fs.hospital.param.HospitalOutpatientOrderParam;
import com.fs.hospital.service.IHospitalOutpatientOrderLogsService;
import com.fs.hospital.vo.HospitalOrderItemListHVO;
import com.fs.hospital.vo.HospitalOutpatientOrderCountHVO;
import com.fs.hospital.vo.HospitalOutpatientOrderHVO;
import com.fs.hospital.vo.HospitalPharmacyOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.hospital.service.IHospitalOutpatientOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 门诊单Service业务层处理
 *
 * @author fs
 * @date 2024-03-22
 */
@Service
public class HospitalOutpatientOrderServiceImpl implements IHospitalOutpatientOrderService
{
    @Autowired
    private HospitalOutpatientOrderMapper hospitalOutpatientOrderMapper;

    @Autowired
    private HospitalPatientMapper hospitalPatientMapper;

    @Autowired
    private IHospitalOutpatientOrderLogsService hospitalOutpatientOrderLogsService;

    @Autowired
    private HospitalOrderMapper hospitalOrderMapper;

    @Autowired
    private HospitalOrderItemMapper hospitalOrderItemMapper;

    @Autowired
    private HospitalTreatOrderMapper treatOrderMapper;

    @Autowired
    private HospitalExamItemMapper examItemMapper;

    @Autowired
    private HospitalInspectItemMapper inspectItemMapper;

    @Autowired
    private HospitalTreatItemMapper treatItemMapper;

    @Autowired
    private HospitalProductMapper productMapper;



    /**
     * 查询门诊单
     *
     * @param orderId 门诊单主键
     * @return 门诊单
     */
    @Override
    public HospitalOutpatientOrder selectHospitalOutpatientOrderByOrderId(Long orderId)
    {
        return hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderByOrderId(orderId);
    }

    /**
     * 查询门诊单列表
     *
     * @param hospitalOutpatientOrder 门诊单
     * @return 门诊单
     */
    @Override
    public List<HospitalOutpatientOrder> selectHospitalOutpatientOrderList(HospitalOutpatientOrder hospitalOutpatientOrder)
    {
        return hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderList(hospitalOutpatientOrder);
    }

    /**
     * 新增门诊单
     *
     * @param hospitalOutpatientOrder 门诊单
     * @return 结果
     */
    @Override
    @Transactional
    public R insertHospitalOutpatientOrder(HospitalOutpatientOrder hospitalOutpatientOrder)
    {

        if (hospitalOutpatientOrder.getIsYuyue()==0){
            hospitalOutpatientOrder.setYuyueTime(new Date());
        }
        String orderCode = "MZ"+ IdUtil.getSnowflake(0, 0).nextIdStr();
        hospitalOutpatientOrder.setOrderCode(orderCode);
        hospitalOutpatientOrder.setStatus(1);
        hospitalOutpatientOrder.setCreateTime(new Date());
        hospitalOutpatientOrder.setIsPay(0);
        HospitalPatient patient = hospitalPatientMapper.selectHospitalPatientByPatientId(hospitalOutpatientOrder.getPatientId());
        if (patient!=null){
            hospitalOutpatientOrder.setPatientJson(JSON.toJSONString(patient));
            if (patient.getMemberId()!=null){
                hospitalOutpatientOrder.setMemberId(patient.getMemberId());
            }
        }
        if (hospitalOutpatientOrderMapper.insertHospitalOutpatientOrder(hospitalOutpatientOrder)>0){
            HospitalOrderItem orderItem = new HospitalOrderItem();
            orderItem.setHospitalId(hospitalOutpatientOrder.getHospitalId());
            orderItem.setOutpatientOrderId(hospitalOutpatientOrder.getOrderId());
            orderItem.setItemType(0); //0代表挂号收费
            orderItem.setCount(1L);
            orderItem.setPrice(hospitalOutpatientOrder.getMoney());
            orderItem.setPayStatus(1);
            //生成一条挂号的支付明细
            hospitalOrderItemMapper.insertHospitalOrderItem(orderItem);
            //生成挂号单的日志
            HospitalOutpatientOrderLogs logs = new HospitalOutpatientOrderLogs();
            logs.setHospitalId(hospitalOutpatientOrder.getHospitalId());
            logs.setUserId(hospitalOutpatientOrder.getUserId());
            logs.setOrderId(hospitalOutpatientOrder.getOrderId());
            logs.setLogsType(1);
            logs.setLogsJson(JSON.toJSONString(hospitalOutpatientOrder));
            hospitalOutpatientOrderLogsService.insertHospitalOutpatientOrderLogs(logs);
            return R.ok().put("data",hospitalOutpatientOrder).put("orderItem",orderItem);
        }
        return R.error();
    }

    /**
     * 修改门诊单
     *
     * @param hospitalOutpatientOrder 门诊单
     * @return 结果
     */
    @Override
    public int updateHospitalOutpatientOrder(HospitalOutpatientOrder hospitalOutpatientOrder)
    {
        hospitalOutpatientOrder.setUpdateTime(DateUtils.getNowDate());
        return hospitalOutpatientOrderMapper.updateHospitalOutpatientOrder(hospitalOutpatientOrder);
    }

    /**
     * 批量删除门诊单
     *
     * @param orderIds 需要删除的门诊单主键
     * @return 结果
     */
    @Override
    public int deleteHospitalOutpatientOrderByOrderIds(Long[] orderIds)
    {
        return hospitalOutpatientOrderMapper.deleteHospitalOutpatientOrderByOrderIds(orderIds);
    }

    /**
     * 删除门诊单信息
     *
     * @param orderId 门诊单主键
     * @return 结果
     */
    @Override
    public int deleteHospitalOutpatientOrderByOrderId(Long orderId)
    {
        return hospitalOutpatientOrderMapper.deleteHospitalOutpatientOrderByOrderId(orderId);
    }

    @Override
    public List<HospitalOutpatientOrderHVO> selectHospitalOutpatientOrderListHVO(HospitalOutpatientOrderParam param) {
        return hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderListHVO(param);
    }

    @Override
    public List<HospitalOutpatientOrderCountHVO> selectHospitalOutpatientOrderCountListHVO(HospitalOutpatientOrderParam param) {
        return hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderCountListHVO(param);
    }

    @Override
    public HospitalOutpatientOrderCountHVO selectHospitalOutpatientOrderAllCountByTime(HospitalOutpatientOrderParam param) {
        HospitalOutpatientOrderCountHVO countHVO = hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderAllCountByTime(param);
        if (countHVO.getWaitCount()==null){
            countHVO.setWaitCount(0L);
        }
        countHVO.setDoctorName("全部医生");
        return countHVO;
    }

    @Override
    public R createOutpatientOrder(HospitalOutpatientOrder hospitalOutpatientOrder) {
        hospitalOutpatientOrder.setYuyueTime(new Date());
        hospitalOutpatientOrder.setIsPay(0);
        String orderCode = "MZ"+ IdUtil.getSnowflake(0, 0).nextIdStr();
        hospitalOutpatientOrder.setOrderCode(orderCode);
        hospitalOutpatientOrder.setCreateTime(new Date());
        hospitalOutpatientOrder.setIsYuyue(0);
        if (hospitalOutpatientOrderMapper.insertHospitalOutpatientOrder(hospitalOutpatientOrder)>0){
            return R.ok();
        }
        return R.error();
    }

    @Override
    public List<HospitalOutpatientOrderHVO> selectAllOutpatientOrderListHVO(HospitalOutpatientOrderParam param) {
        if (param.getYuyueTime()==null){
            LocalDate currentDate = LocalDate.now();
            Date currentDateFormatted = Date.from(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
            param.setYuyueTime(currentDateFormatted);
        }
        return hospitalOutpatientOrderMapper.selectAllOutpatientOrderListHVO(param);
    }

    @Override
    @Transactional
    public R finishOutpatientOrder(HospitalOutpatientOrderFinishParam param) {

        //查看是否有这个门诊单（应对匿名患者）
        HospitalOutpatientOrder outpatientOrder = hospitalOutpatientOrderMapper.selectHospitalOutpatientOrderByOrderId(param.getOrderId());
        if (outpatientOrder!=null){
            if (outpatientOrder.getPatientId()==null&&outpatientOrder.getUserId()==null){
                outpatientOrder.setPatientId(param.getPatientId());
                HospitalPatient patient = hospitalPatientMapper.selectHospitalPatientByPatientId(param.getPatientId());
                if (patient!=null){
                    outpatientOrder.setPatientJson(JSON.toJSONString(patient));
                    if (patient.getMemberId()!=null){
                        outpatientOrder.setMemberId(patient.getMemberId());
                    }
                }
            }
            //更新门诊就诊明细
            outpatientOrder.setStatus(2);
            outpatientOrder.setUserId(param.getUserId());
            outpatientOrder.setOrderType(param.getOrderType());
            outpatientOrder.setMoney(param.getMoney());
            outpatientOrder.setTitle(param.getTitle());
            outpatientOrder.setNowIllness(param.getNowIllness());
            outpatientOrder.setHistoryIllness(param.getHistoryIllness());
            outpatientOrder.setHistoryAllergic(param.getHistoryAllergic());
            outpatientOrder.setPhysicalExamination(param.getPhysicalExamination());
            outpatientOrder.setDiagnose(param.getDiagnose());
            outpatientOrder.setAdvice(param.getAdvice());
            if (hospitalOutpatientOrderMapper.updateHospitalOutpatientOrder(outpatientOrder)>0){
                //生成诊疗项目-收费单
                HospitalOrder hospitalOrder = new HospitalOrder();
                hospitalOrder.setOrderCode(IdUtil.getSnowflake(0, 0).nextIdStr());
                hospitalOrder.setHospitalId(outpatientOrder.getHospitalId());
                hospitalOrder.setOutpatientOrderId(outpatientOrder.getOrderId());
                hospitalOrder.setPatientId(outpatientOrder.getPatientId());
                hospitalOrder.setPatientJson(outpatientOrder.getPatientJson());
                hospitalOrder.setOrderType(1);
                hospitalOrder.setStatus(1);
                hospitalOrder.setUserId(outpatientOrder.getUserId());
                hospitalOrder.setCreateTime(new Date());
                hospitalOrder.setTotalMoney(param.getTotalMoney());
                if (hospitalOrderMapper.insertHospitalOrder(hospitalOrder)>0){
                    //列出治疗项目清单
                    List<HospitalOrderItemListHVO> list = param.getOrderItems();
                    HospitalTreatOrder treatOrder = new HospitalTreatOrder();
                    if(list.size()>0&&list!=null) {

                        //计算出治疗项目的总费用
                        BigDecimal treatTotalMoney = list.stream()
                                .map(item -> item.getPrice() != null ? item.getPrice() : BigDecimal.ZERO)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);

                        treatOrder.setOrderCode("ZX"+IdUtil.getSnowflake(0, 0).nextIdStr());
                        treatOrder.setTitle(outpatientOrder.getTitle());
                        treatOrder.setPatientId(outpatientOrder.getPatientId());
                        treatOrder.setHospitalId(outpatientOrder.getHospitalId());
                        treatOrder.setOutpatientOrderId(outpatientOrder.getOrderId());
                        treatOrder.setOrderType(1);
                        treatOrder.setUserId(outpatientOrder.getUserId());
                        treatOrder.setPatientJson(outpatientOrder.getPatientJson());
                        treatOrder.setCreateTime(new Date());
                        treatOrder.setStatus(2);
                        treatOrder.setIsPay(0);
                        treatOrder.setMoney(treatTotalMoney);
                        //生成总费用单
                        treatOrderMapper.insertHospitalTreatOrder(treatOrder);
                        hospitalOrder.setTreatOrderId(treatOrder.getOrderId());
                        //更新-关联诊疗订单
                        hospitalOrderMapper.updateHospitalOrder(hospitalOrder);
                    }

                    //遍历orderItem（治疗项目清单）生成治疗单，检查单，检验单的订单详情
                    for (HospitalOrderItemListHVO item : list) {
                        HospitalOrderItem hospitalOrderItem = new HospitalOrderItem();
                        hospitalOrderItem.setOrderId(hospitalOrder.getOrderId());
                        if (treatOrder.getOrderId()!=null){
                            hospitalOrderItem.setTreatOrderId(treatOrder.getOrderId());
                        }
//                        //原先是记录上所有的绑定到诊疗订单上，现在只关联类型为3（治疗类型）的
//                        if (item.getType()==3&&treatOrder.getOrderId()!=null){
//                            hospitalOrderItem.setTreatOrderId(treatOrder.getOrderId());
//                            hospitalOrderItem.setTreatStatus(0); //治疗待执行
//                            hospitalOrderItem.setRemainCount(item.getCount());
//                        }

                        if (item.getType()==3){
                            hospitalOrderItem.setTreatStatus(0); //治疗待执行
                            hospitalOrderItem.setRemainCount(item.getCount());
                        }
                        hospitalOrderItem.setHospitalId(hospitalOrder.getHospitalId());
                        hospitalOrderItem.setOutpatientOrderId(hospitalOrder.getOutpatientOrderId());
                        hospitalOrderItem.setItemType(item.getType());
                        hospitalOrderItem.setBusinessId(item.getId());
                        //判断类型存项目json
                        processItem(hospitalOrderItem, item);
                        hospitalOrderItem.setCount(item.getCount());
                        hospitalOrderItem.setPrice(item.getPrice());
                        hospitalOrderItem.setPayStatus(1);
                        //将选择的诊疗项目清单记录
                        hospitalOrderItemMapper.insertHospitalOrderItem(hospitalOrderItem);


                    }

                    return R.ok();
                }

            }

        }
        return R.error();
    }

    @Override
    public R getOutpatientOrder(Long orderId) {
        HospitalOutpatientOrder hospitalOutpatientOrder = this.selectHospitalOutpatientOrderByOrderId(orderId);
        if (hospitalOutpatientOrder != null) {

            //当前患者的诊疗项目单
            List<HospitalOrderItem> orderItems = hospitalOrderItemMapper.selectHospitalOrderItemByOutpatientOrder(orderId);
            List<HospitalOrderItemListHVO> list = getOrderItemList(orderItems);
            return R.ok().put("order",hospitalOutpatientOrder).put("list",list);
        }
        return R.error("查询失败");
    }

    @Override
    public R getOutpatientOrderHistory(Long orderId) {
        HospitalOutpatientOrder hospitalOutpatientOrder = this.selectHospitalOutpatientOrderByOrderId(orderId);
        if (hospitalOutpatientOrder != null) {
            if (hospitalOutpatientOrder.getPatientId() != null) {

                //获取到当前患者的历史诊断
                List<HospitalPharmacyOrderVO> hospitalPharmacyHistoryList = hospitalOutpatientOrderMapper.selectOutpatientOrderHistoryList(hospitalOutpatientOrder.getPatientId());

                hospitalPharmacyHistoryList.stream().forEach(list->{
                    //获取患者的历史诊疗项目单
                    List<HospitalOrderItem> orderItemsHistory = hospitalOrderItemMapper.selectHospitalOrderItemByOutpatientOrder(list.getOrderId());
                    //将诊疗项目单存入各次记录中
                    list.setList(getOrderItemList(orderItemsHistory));

                });

                return R.ok().put("historyList",hospitalPharmacyHistoryList);
            }else {
                return R.ok().put("historyList","");
            }

        }
        return R.error("查询失败");
    }

    //查询类型和id对应的项目详情
    public void processItem(HospitalOrderItem hospitalOrderItem, HospitalOrderItemListHVO item) {
        Object itemObject = null;

        switch (item.getType()) {
            case 1:
                itemObject = examItemMapper.selectHospitalExamItemByExamId(item.getId());
                break;
            case 2:
                itemObject = inspectItemMapper.selectHospitalInspectItemByInspectId(item.getId());
                break;
            case 3:
                itemObject = treatItemMapper.selectHospitalTreatItemByTreatId(item.getId());
                break;
            case 4:
                itemObject = productMapper.selectHospitalProductByProductId(item.getId());
                break;
            default:
                break;
        }

        if (itemObject != null) {
            hospitalOrderItem.setItemJson(JSON.toJSONString(itemObject));
        }
    }

    /**
     * 整合区分诊疗项目单详情
     */
    public List<HospitalOrderItemListHVO> getOrderItemList(List<HospitalOrderItem> orderItems){
        List<HospitalOrderItemListHVO> list = new ArrayList<>();
        for (HospitalOrderItem orderItem : orderItems){
            HospitalOrderItemListHVO orderItemListHVO = new HospitalOrderItemListHVO();
            orderItemListHVO.setItemId(orderItem.getItemId());
            orderItemListHVO.setPayMoney(orderItem.getPayMoney());
            orderItemListHVO.setPayStatus(orderItem.getPayStatus());
            orderItemListHVO.setTreatStatus(orderItem.getTreatStatus());
//            //预计检查数-实际检查数=执行检查数
//            orderItemListHVO.setExecuteCount(orderItem.getCount()-orderItem.getRemainCount());
            switch (orderItem.getItemType()) {
                case 1:
                    HospitalExamItem examItem = JSONObject.parseObject(orderItem.getItemJson(), HospitalExamItem.class);
                    orderItemListHVO.setId(examItem.getExamId());
                    orderItemListHVO.setCount(orderItem.getCount());
                    orderItemListHVO.setName(examItem.getExamName());
                    orderItemListHVO.setPrice(orderItem.getPrice());
                    orderItemListHVO.setType(1);
                    orderItemListHVO.setUnit(examItem.getUnit());
                    break;
                case 2:
                    HospitalInspectItem inspectItem = JSONObject.parseObject(orderItem.getItemJson(), HospitalInspectItem.class);
                    orderItemListHVO.setId(inspectItem.getInspectId());
                    orderItemListHVO.setCount(orderItem.getCount());
                    orderItemListHVO.setName(inspectItem.getInspectName());
                    orderItemListHVO.setPrice(orderItem.getPrice());
                    orderItemListHVO.setType(2);
                    orderItemListHVO.setUnit(inspectItem.getUnit());
                    break;
                case 3:
                    HospitalTreatItem treatItem = JSONObject.parseObject(orderItem.getItemJson(), HospitalTreatItem.class);
                    orderItemListHVO.setId(treatItem.getTreatId());
                    orderItemListHVO.setCount(orderItem.getCount());
                    orderItemListHVO.setName(treatItem.getTreatName());
                    orderItemListHVO.setPrice(orderItem.getPrice());
                    orderItemListHVO.setType(3);
                    orderItemListHVO.setUnit(treatItem.getUnit());

                    //预计检查数-实际检查数=执行检查数
                    if (orderItem.getCount()==null){
                        orderItem.setCount(0L);
                    }

                    System.out.println("");
                    orderItemListHVO.setExecuteCount(orderItem.getCount()-orderItem.getRemainCount());
                    break;
                case 4:
                    HospitalProduct hospitalProduct = JSONObject.parseObject(orderItem.getItemJson(),HospitalProduct.class);
                    orderItemListHVO.setId(hospitalProduct.getProductId());
                    orderItemListHVO.setCount(orderItem.getCount());
                    orderItemListHVO.setName(hospitalProduct.getProductName());
                    orderItemListHVO.setPrice(orderItem.getPrice());
                    orderItemListHVO.setType(4);
                    orderItemListHVO.setUnit(hospitalProduct.getUnit());
                    break;
                default:
                    break;
            }
            list.add(orderItemListHVO);
        }
        return list;
    }

}
