package com.eitc.patient.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eitc.common.utils.bean.BeanUtils;
import com.eitc.patient.domain.CollectCostPatients;
import com.eitc.patient.domain.CollectCostPatientsDetails;
import com.eitc.patient.domain.MedicalRecord;
import com.eitc.patient.mapper.CollectCostPatientsDetailsMapper;
import com.eitc.patient.service.ICollectCostPatientsDetailsService;
import com.eitc.patient.service.ICollectCostPatientsService;
import com.eitc.patient.service.IMedicalRecordService;
import com.eitc.patient.vo.CollectCostDetailsVO;
import com.eitc.patient.vo.CollectCostPatientsDetailsListVO;
import com.eitc.patient.vo.CollectCostPatientsDetailsVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * CollectCostPatientsDetailsServiceImpl
 *
 * @author mtx
 * @date: 2024/05/17 15:39
 */
@Service
public class CollectCostPatientsDetailsServiceImpl extends ServiceImpl<CollectCostPatientsDetailsMapper, CollectCostPatientsDetails> implements ICollectCostPatientsDetailsService {

    @Resource
    private ICollectCostPatientsService collectCostPatientsService;
    @Resource
    private IMedicalRecordService medicalRecordService;


    /**
     * 编辑医疗费用患者详情的接口方法。
     * 该方法旨在更新已存在的医疗费用患者详情信息。通过接收一个CollectCostPatientsDetailsVO类型的对象，
     * 对象中包含了需要更新的所有细节信息，实现对数据库中相应患者详情的修改。
     *
     * @param vo CollectCostPatientsDetailsVO类型的参数，包含了需要更新的患者详情信息。
     * @author mtx
     * @date 2024/7/22 14:30
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void edit(CollectCostPatientsDetailsVO vo) {
        BigDecimal receivableCost = new BigDecimal(0);
        BigDecimal amountCost = new BigDecimal(0);

        String collectCostPatientsId = vo.getCollectCostPatientsId();
        // 保存患者收费详情
        List<CollectCostPatientsDetails> detailsList = new ArrayList<>();
        List<CollectCostPatientsDetailsListVO> listVO = vo.getListVO();
        if (CollectionUtils.isEmpty(listVO)) {
            throw new RuntimeException("请选择收费项目");
        }
        for (CollectCostPatientsDetailsListVO collectCostPatientsDetailsListVO : listVO) {
            String toothPosition = collectCostPatientsDetailsListVO.getToothPosition();
            List<CollectCostDetailsVO> voList = collectCostPatientsDetailsListVO.getCollectCostDetailsVOList();
            if (CollectionUtils.isEmpty(voList)) {
                throw new RuntimeException("请选择收费项目");
            }
            for (CollectCostDetailsVO details : voList) {
                CollectCostPatientsDetails patientsDetails = new CollectCostPatientsDetails();
                BeanUtils.copyProperties(details, patientsDetails);
                patientsDetails.setCollectCostPatientsId(collectCostPatientsId);
                patientsDetails.setToothPosition(toothPosition);
                patientsDetails.setId(null);
                detailsList.add(patientsDetails);

                // 计算应收费用 单价*数量
                BigDecimal preferentialPrice = details.getPreferentialPrice().multiply(new BigDecimal(details.getTotal()));
                receivableCost = receivableCost.add(preferentialPrice);

                BigDecimal total = details.getUnitPrice().multiply(new BigDecimal(details.getTotal()));
                amountCost = amountCost.add(total);
            }

        }
        this.saveDetailsByCollectCostPatientsId(collectCostPatientsId, detailsList);

        CollectCostPatients costPatients = collectCostPatientsService.getById(collectCostPatientsId);
        String medicalRecordId = costPatients.getMedicalRecordId();

        CollectCostPatients collectCostPatients = new CollectCostPatients();
        collectCostPatients.setId(collectCostPatientsId);
        collectCostPatients.setCostStatus(1);
        collectCostPatients.setAmountCost(amountCost);
        collectCostPatients.setReceivableCost(receivableCost);
        collectCostPatients.setNetReceiptsCost(vo.getNetReceiptsCost());
        collectCostPatientsService.updateById(collectCostPatients);

        // 修改病历中的收费信息
        MedicalRecord mr = new MedicalRecord();
        mr.setCost(receivableCost);
        mr.setId(medicalRecordId);
        medicalRecordService.updateById(mr);
    }

    /**
     * 根据采集费用患者ID保存或更新费用采集患者详情列表。
     * 此方法首先删除已存在的与给定患者ID相关的费用采集详情，然后批量保存新的费用采集详情列表。
     * 这样做的目的是确保数据的更新准确性，避免旧数据的干扰。
     *
     * @param collectCostPatientsId          患者采集费用的唯一标识ID。此ID用于关联费用采集患者详情。
     * @param collectCostPatientsDetailsList 费用采集患者详情的列表。这些详情将被保存或更新。
     * @author mtx
     * @date 2024/7/22 14:56
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void saveDetailsByCollectCostPatientsId(String collectCostPatientsId, List<CollectCostPatientsDetails> collectCostPatientsDetailsList) {
        // 删除已存在的与给定患者ID相关的费用采集详情
        this.remove(Wrappers.<CollectCostPatientsDetails>lambdaQuery().eq(CollectCostPatientsDetails::getCollectCostPatientsId, collectCostPatientsId));

        // 批量保存新的费用采集详情列表
        this.saveBatch(collectCostPatientsDetailsList);
    }

}
