package com.ywt.outpatient.controllers.taihe;

import com.ywt.biz.common.enums.SexEnum;
import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.third.taihe.*;
import com.ywt.gapi.user.*;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.core.utils.BankCardUtil;
import com.ywt.outpatient.core.utils.BizUtil;
import com.ywt.outpatient.core.utils.CheckUtil;
import com.ywt.outpatient.domain.models.enums.LastChoiceEnum;
import com.ywt.outpatient.service.web.MedicalCardService;
import com.ywt.outpatient.service.web.UserSrv;
import com.ywt.outpatient.service.web.taihe.TaiheUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController("/taihe/medicalRecord")
@RequestMapping({"/taihe/medicalRecord"})
public class MedicalRecordController {
    private static Logger logger = LoggerFactory.getLogger(MedicalRecordController.class);

    @Autowired
    private TaiheUserService userService;

    @DubboReference
    private UserService userServiceBlockingStub;

    @DubboReference
    private TaiheService taiheServiceBlockingStub;

    @Autowired
    private UserSrv userSrv;

    @Autowired
    private MedicalCardService medicalCardService;

    /**
     * 得到患者添加的患者病历详情
     *
     * @param recordId
     * @return
     */
    @RequestMapping({"/getMedicalRecordDetail"})
    public @ResponseBody
    BaseResponse getMedicalRecordDetail(@RequestParam(name = "recordId") int recordId) {
        BaseResponse response = new BaseResponse();

        try {
            GetMedicalRecordsDetailRequest req = GetMedicalRecordsDetailRequest.newBuilder().setRecordId(recordId).build();
            GetMedicalRecordsDetailResponse resp = userServiceBlockingStub.getMedicalRecordsDetail(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                MedicalRecordsDetail detail = resp.getDetail();

                if (detail.getUserId() != userService.getCurrentUserIdWrapped()) {
                    return response.failed(BaseResponse.PARAMETER_ERROR, "病历不存在");
                }

                Map<String, Object> map = new HashMap<>();
                map.put("recordId", detail.getRecordId());
                map.put("userId", detail.getUserId());
                map.put("sex", detail.getSex());
                map.put("strSex", SexEnum.getSexDisplayName(detail.getSex()));
                map.put("age", detail.getAge());
                map.put("mobile", detail.getMobile());
                map.put("desc", detail.getDesc());
                map.put("patientName", detail.getPatientName());
                map.put("imageUrls", detail.getImageUrlList());

                return response.succeed(map);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getMedicalRecordDetail({}): {}", recordId, e.getMessage(), e);
            return response.failed(BaseResponse.APP_EXCEPTION, e.getMessage());
        }
    }

    /**
     * 选择的患者病历列表
     *
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @RequestMapping({"/getMedicalRecordList"})
    public @ResponseBody
    BaseResponse getMedicalRecordList(@RequestParam(name = "pageIndex", required = false) Integer pageIndex,
                                      @RequestParam(name = "pageSize", required = false) Integer pageSize) {
        BaseResponse response = new BaseResponse();

        if (pageIndex == null) {
            pageIndex = 1;
        }

        if (pageSize == null) {
            pageSize = 1000;
        }

        try {
            GetMedicalRecordListByUserIdRequest req = GetMedicalRecordListByUserIdRequest.newBuilder()
                    .setUserId(userService.getCurrentUserIdWrapped())
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize)
                    .build();
            GetMedicalRecordListByUserIdResponse resp = userServiceBlockingStub.getMedicalRecordListByUserId(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                List<Map<String, Object>> lst = new LinkedList<>();
                List<MedicalRecordsDetail> list = resp.getDetailList();

                for (MedicalRecordsDetail detail : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("recordId", detail.getRecordId());
                    map.put("sex", detail.getSex());
                    map.put("strSex", SexEnum.getSexDisplayName(detail.getSex()));
                    map.put("age", detail.getAge());
                    map.put("patientName", detail.getPatientName());

                    lst.add(map);
                }

                Map<String, Object> data = new HashMap<>();
                data.put("list", lst);
                data.put("count", resp.getCount());
                data.put("totalPages", resp.getTotalPages());

                return response.succeed(data);
            }

            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getMedicalRecordList({}, {}): {}", pageIndex, pageSize, e.getMessage(), e);
            return response.failed(BaseResponse.APP_EXCEPTION, e.getMessage());
        }
    }

    /**
     * 根据患者ID得到日清单列表(住院服务)
     * <p>
     * hisPatientId his患者ID
     * billDate     就诊日期
     *
     * @return {@link BaseResponse}
     */
    @RequestMapping(value = {"/getDayFeeList"}, method = RequestMethod.POST)
    public BaseResponse getDayFeeList(@RequestBody Map<String, Object> mapData) {
        String hisPatientId = (String) mapData.getOrDefault("hisPatientId", "");
        String billDate = (String) mapData.getOrDefault("billDate", "");
        String admNo = (String) mapData.getOrDefault("admNo", "");
        BaseResponse response = new BaseResponse();
        if (Checker.isNone(hisPatientId)) {
            MedicalCard medicalCard = getMedicalCardByHisPatientId();
            if (!Checker.isNone(medicalCard)) {
                hisPatientId = medicalCard.getHisPatientId();
            }
        }
        if (Checker.isNone(hisPatientId)) {
            return response.failedWithParameterError("没有诊疗卡");
        }
        GetDayFeeListRequest req = GetDayFeeListRequest.newBuilder()
                .setPatientId(hisPatientId)
                .setBillDate(billDate)
                .setHospitalId(BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped()))
                .setAdmNo(admNo)
                .build();
        GetDayFeeListResponse resp = taiheServiceBlockingStub.getDayFeeList(req);
        if (resp.getCode() == BaseResponse.SUCCEED) {
            List<Map<String, Object>> lst = new LinkedList<>();
            List<DayFeeListItem> list = resp.getListList();
            for (DayFeeListItem item : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("serialNo", item.getSerialNo());
                map.put("category", item.getCategory());
                map.put("itemName", item.getItemName());
                map.put("quantity", item.getQuantity());
                map.put("unit", item.getUnit());
                map.put("price", String.format("%.2f", item.getPrice() / 100d));
                map.put("totalAmt", String.format("%.2f", item.getTotalAmt() / 100d));
                map.put("billDate", item.getBillDate());
                map.put("billTime", item.getBillTime());
                map.put("insuClass", item.getInsuClass());
                map.put("itemChargeBasis", item.getItemChargeBasis());
                lst.add(map);
            }
            Map<String, Object> data = new HashMap<>();
            data.put("list", lst);
            data.put("patientId", resp.getPatientId());
            data.put("patientName", resp.getPatientName());
            data.put("sex", resp.getSex());
            data.put("age", resp.getAge());
            data.put("admReason", resp.getAdmReason());
            data.put("deptName", resp.getDeptName());
            data.put("ward", resp.getWard());
            data.put("bedNo", resp.getBedNo());
            data.put("patFee", resp.getPatFee());
            data.put("deposit", resp.getDeposit());
            data.put("visitStatus", resp.getVisitStatus());
            data.put("printFlag", resp.getPrintFlag());
            data.put("printTimes", resp.getPrintTimes());
            return response.succeed(data);
        }
        return response.failed(BaseResponse.APP_ERROR, resp.getMsg());
    }


    /**
     * 根据用户ID获取用户诊疗卡信息（选择上一次选择的诊疗卡，或者是第一张）
     *
     * @return {@link MedicalCard}
     */
    private MedicalCard getMedicalCardByHisPatientId() {
        MedicalCard medicalCard = null;
        // 则获取当前用户的第一张诊疗卡，或者是上一次选择的诊疗卡（优先）
        GetMedicalCardListRequest getMedicalCardListRequest = GetMedicalCardListRequest.newBuilder()
                .setUserId(userService.getCurrentUserIdWrapped())
                .build();
        GetMedicalCardListResponse getMedicalCardListResponse = userServiceBlockingStub.getMedicalCardList(getMedicalCardListRequest);
        Result result = getMedicalCardListResponse.getResult();
        if (result.getCode() == ResultCode.SUCCEED) {
            List<MedicalCard> cardList = getMedicalCardListResponse.getMedicalCardsList();
            if (!Checker.isNone(cardList)) {
                medicalCard = cardList.stream().filter(p -> p.getLastChoice() == LastChoiceEnum.True.getValue()).findFirst().orElse(null);
                if (Checker.isNone(medicalCard)) {
                    medicalCard = cardList.get(0);
                }
            }
        }
        return medicalCard;
    }


    /**
     * 根据患者ID得到充值记录（住院押金）
     * <p>
     * hisPatientId his患者ID，每张诊疗卡号都对应一个hisPatientId
     * admNo        住院就诊号
     *
     * @return {@link BaseResponse}
     */
    @RequestMapping(value = {"/getCashList"}, method = RequestMethod.POST)
    public BaseResponse getCashList(@RequestBody Map<String, Object> mapData) {
        BaseResponse response = new BaseResponse();
        try {
            String hisPatientId = (String) mapData.getOrDefault("hisPatientId", "");
            String admNo = (String) mapData.getOrDefault("admNo", "");
            if (Checker.isNone(hisPatientId)) {
                MedicalCard medicalCard = getMedicalCardByHisPatientId();
                if (!Checker.isNone(medicalCard)) {
                    hisPatientId = medicalCard.getHisPatientId();
                }
            }
            if (Checker.isNone(hisPatientId)) {
                return response.failedWithParameterError("没有诊疗卡");
            }
            int userId = userSrv.getCurrentUserIdWrapped();
            if (userId <= 0) {
                CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            }
            int hospitalId = BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped());
            medicalCardService.verifyMedicalCard(userId, hospitalId, hisPatientId, 0);
            GetCashListRequest req = GetCashListRequest.newBuilder()
                    .setPatientId(hisPatientId)
                    .setAdmNo(admNo)
                    .setHospitalId(hospitalId)
                    .build();
            GetCashListResponse resp = taiheServiceBlockingStub.getCashList(req);
            if (resp.getCode() == BaseResponse.SUCCEED) {
                List<Map<String, Object>> lst = new LinkedList<>();
                List<CashListItem> list = resp.getListList();
                for (int size = list.size(), i = 0; i < size; i++) {
                    CashListItem item = list.get(size - i - 1);
                    Map<String, Object> map = new HashMap<>();
                    map.put("payDate", item.getPayDate());
                    map.put("payTime", item.getPayTime());
                    String showTime = item.getPayDate() + " " + item.getPayTime();
                    Date date = DateUtil.stringToDate(showTime, DateUtil.DADE_FROMAT_YMDHMS);
                    showTime = DateUtil.formatDate(date, DateUtil.DADE_FROMAT_CYMDHM);
                    map.put("showTime", showTime);
                    map.put("payAmout", String.format("%.2f", item.getPayAmout() / 100d));
                    map.put("payMode", item.getPayMode());
                    map.put("payFlag", item.getPayFlag());
                    map.put("receiptNo", item.getReceiptNo());
                    map.put("payUserCode", item.getPayUserCode());
                    map.put("payUserName", item.getPayUserName());
                    map.put("payDept", item.getPayDept());
                    map.put("payWard", item.getPayWard());
                    map.put("remark", item.getRemark());
                    lst.add(map);
                }
                Map<String, Object> data = new HashMap<>();
                data.put("list", lst);
                return response.succeed(data);
            }
            return response.failed(BaseResponse.APP_ERROR, resp.getMsg());
        } catch (Exception e) {
            logger.error("MedicalRecordController#(): getCashList{}", e.getMessage(), e);
            return response.error(e.getMessage());
        }
    }

    /**
     * 根据hisPatientId获取患者的住院服务信息
     * <p>
     * hisPatientId his患者ID
     *
     * @return {@link BaseResponse}
     */
    @RequestMapping(value = {"/getInPatInfo"}, method = RequestMethod.POST)
    public BaseResponse getInPatInfo(@RequestBody Map<String, Object> mapData) {
        BaseResponse response = new BaseResponse();
        try {
            String hisPatientId = (String) mapData.getOrDefault("hisPatientId", "");
            if (Checker.isNone(hisPatientId)) {
                MedicalCard medicalCard = getMedicalCardByHisPatientId();
                if (!Checker.isNone(medicalCard)) {
                    hisPatientId = medicalCard.getHisPatientId();
                }
            }
            if (Checker.isNone(hisPatientId)) {
                return response.failedWithParameterError("没有诊疗卡");
            }
            int userId = userSrv.getCurrentUserIdWrapped();
            if (userId <= 0) {
                CheckUtil.ensureLargerThanZero(userId, "请登录后操作");
            }
            int hospitalId = BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped());
            medicalCardService.verifyMedicalCard(userId, hospitalId, hisPatientId, 0);
            GetInPatInfoRequest req = GetInPatInfoRequest.newBuilder()
                    .setPatientId(hisPatientId)
                    .setHospitalId(hospitalId)
                    .build();
            GetInPatInfoResponse resp = taiheServiceBlockingStub.getInPatInfo(req);
            if (resp.getCode() == BaseResponse.SUCCEED) {
                Map<String, Object> data = new HashMap<>();
                data.put("patientId", resp.getPatientId());
                data.put("patientName", resp.getPatientName());
                data.put("sex", resp.getSex());
                data.put("dOB", resp.getDOB());
                data.put("medical", resp.getMedical());
                data.put("credType", resp.getCredType());
                // 进行脱敏处理
                data.put("credNo", BankCardUtil.getDesensitizationCardNo(resp.getCredNo()));
                data.put("admNo", resp.getAdmNo());
                String admDate = resp.getAdmDate();
                data.put("admDate", admDate);
                List dateList = new ArrayList();
                int num = (int) DateUtil.getCurrentDay(admDate);
                if (num > 0) {

                    for (int i = num; i >= 0; i--) {
                        Map<String, String> map = new HashMap();
                        Date date = DateUtil.getChangeDayOfDate(admDate, i, DateUtil.DADE_FROMAT_YMD);
                        String showDate = DateUtil.formatDate(date, DateUtil.DADE_FROMAT_CYMD);
                        String hideDate = DateUtil.formatDate(date, DateUtil.DADE_FROMAT_YMD);
                        map.put("showDate", showDate);
                        map.put("hideDate", hideDate);
                        dateList.add(map);
                    }
                }
                data.put("dateList", dateList);
                data.put("admDept", resp.getAdmDept());
                data.put("billNo", resp.getBillNo());
                data.put("admReason", resp.getAdmReason());
                data.put("nationalCode", resp.getNationalCode());
                data.put("totalAmount", String.format("%.2f", resp.getTotalAmount() / 100d));
                data.put("depositAmount", String.format("%.2f", resp.getDepositAmount() / 100d));
                data.put("depositBalance", String.format("%.2f", resp.getDepositBalance() / 100d));
                return response.succeed(data);
            }
            return response.failed(BaseResponse.APP_ERROR, resp.getMsg());
        } catch (Exception e) {
            logger.error("MedicalRecordController#(): getInPatInfo{}", e.getMessage(), e);
            return response.error(e.getMessage());
        }
    }


}
