/*
 * Copyright ©2023 CJB-CNIT Team. All rights reserved
 */
package com.openhis.web.reportmanage.appservice.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSONObject;
import com.core.common.utils.AgeCalculatorUtil;
import com.core.common.utils.SecurityUtils;
import com.openhis.administration.service.IEncounterService;
import com.openhis.administration.service.IPractitionerService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.web.reportmanage.appservice.InpatientMedicalRecordHomePageCollectionAppService;
import com.openhis.web.reportmanage.dto.InpatientMedicalRecordHomePageCollectionDto;
import com.openhis.web.reportmanage.dto.InpatientMedicalRecordHomePageMakeDto;
import com.openhis.web.reportmanage.mapper.InpatientMedicalRecordHomePageCollectionMapper;
import com.openhis.web.reportmanage.utils.CsvFillerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.core.common.core.domain.R;
import java.util.stream.Collectors;

/**
 * 住院病案首页采集 impl
 *
 * @author yuxj
 * @date 2025-08-25
 */
@Service
public class InpatientMedicalRecordHomePageCollectionAppServiceImpl
    implements InpatientMedicalRecordHomePageCollectionAppService {

    @Autowired
    private InpatientMedicalRecordHomePageCollectionMapper inpatientMedicalRecordHomePageCollectionMapper;
    @Resource
    IPractitionerService practitionerService;
    @Resource
    IEncounterService encounterService;

    /**
     * 住院病案csv做成
     *
     * @param encounterIdList 就诊idList
     * @return 执行结果
     */
    @Override
    public R<?> makeCsvFile(List<Long> encounterIdList, HttpServletResponse response) {

        // // 格式 (7,2)：最大整数位 7，固定小数位 2
        // DecimalFormat df7_2 = new DecimalFormat();
        // df7_2.setMaximumIntegerDigits(7); // 最大整数位 7
        // df7_2.setMinimumFractionDigits(2); // 最小小数位 2（不足补 0）
        // df7_2.setMaximumFractionDigits(2); // 最大小数位 2（超出四舍五入）
        // 格式 (4,1)：最大整数位 4，固定小数位 1
        DecimalFormat df4_1 = new DecimalFormat();
        df4_1.setMaximumIntegerDigits(4);
        df4_1.setMinimumFractionDigits(1);
        df4_1.setMaximumFractionDigits(1);
        // 格式 (8,2)：最大整数位 8，固定小数位 2
        DecimalFormat df8_2 = new DecimalFormat();
        df8_2.setMaximumIntegerDigits(8);
        df8_2.setMinimumFractionDigits(2);
        df8_2.setMaximumFractionDigits(2);
        // 格式 (11,2)：最大整数位 11，固定小数位 2
        DecimalFormat df11_2 = new DecimalFormat();
        df11_2.setMaximumIntegerDigits(11);
        df11_2.setMinimumFractionDigits(2);
        df11_2.setMaximumFractionDigits(2);
        // 格式 (10,2)：最大整数位 10，固定小数位 2
        DecimalFormat df10_2 = new DecimalFormat();
        df10_2.setMaximumIntegerDigits(10);
        df10_2.setMinimumFractionDigits(2);
        df10_2.setMaximumFractionDigits(2);

        // // 获取当前登陆用户信息
        // LoginUser loginUser = SecurityUtils.getLoginUser();
        // Practitioner user = practitionerService.getPractitionerByUserId(loginUser.getUserId());

        // 获取系统信息
        JSONObject optionJson = SecurityUtils.getLoginUser().getOptionJson();

        // 住院病案csv参数
        InpatientMedicalRecordHomePageCollectionDto medicalRecordHomePage =
            new InpatientMedicalRecordHomePageCollectionDto();
        List<InpatientMedicalRecordHomePageCollectionDto> medicalRecordHomePageList = new ArrayList<>();
        // 搜索csv所需数据  todo sql没写完  csv出力需要确认好不好使
        List<InpatientMedicalRecordHomePageMakeDto> medicalRecordHomePageMakeList =
            inpatientMedicalRecordHomePageCollectionMapper.getInfo(encounterIdList);

        for (InpatientMedicalRecordHomePageMakeDto item : medicalRecordHomePageMakeList) {
            // 组织机构代码 字符 30 必填
            medicalRecordHomePage.setA01(optionJson.getString(CommonConstants.Option.FIXMEDINS_CODE));
            // 医疗机构名称 A02 字符 80 必填
            medicalRecordHomePage.setA02(optionJson.getString(CommonConstants.Option.FIXMEDINS_NAME));
            // 病案号 A48 字符 50 必填
            medicalRecordHomePage.setA48(item.getA48());
            // 住院次数 A49 数字 4 必填
            medicalRecordHomePage.setA49(item.getA49() == null ? 0 : item.getA49());
            // 入院时间 B12 日期时间 必填
            medicalRecordHomePage.setB12(item.getB12());
            // 出院时间 B15 日期时间 必填
            medicalRecordHomePage.setB15(item.getB15());
            // 医疗付费方式 A46C 字符 3 必填
            medicalRecordHomePage.setA46C(item.getA46C());
            // 姓名 A11 字符 40 必填
            medicalRecordHomePage.setA11(item.getA11());
            // 性别 A12C 数字 1 必填 未查询到时：9 - 未说明的性别
            medicalRecordHomePage.setA12C(item.getA12C() == null ? 9 : item.getA12C());
            // 出生日期 A13 日期 10 必填
            medicalRecordHomePage.setA13(item.getA13());
            // 年龄（岁） A14 数字 3 必填
            medicalRecordHomePage.setA14(AgeCalculatorUtil.calculateAge(medicalRecordHomePage.getA13()));
            // 国籍 A15C 字符 40 必填
            medicalRecordHomePage.setA15C(item.getA15C());
            // 婚姻 A21C 字符 1 必填
            medicalRecordHomePage.setA21C(item.getA21C());
            // 职业 A38C 字符 2 必填
            medicalRecordHomePage.setA38C(item.getA38C());
            // 民族 A19C 字符 2 必填
            medicalRecordHomePage.setA19C(item.getA19C());
            // 证件类别 A20N 字符 1 必填  1：居民身份证  todo 是否
            medicalRecordHomePage.setA20N("1");
            // 证件号码 A20 字符 18 必填
            medicalRecordHomePage.setA20(item.getA20());
            // 出生地址 A22 字符 200 必填
            medicalRecordHomePage.setA22(item.getA22()== null ? CommonConstants.Common.DASH:item.getA22());
            // 籍贯省（自治区、直辖市） A23C 字符 50 必填
            medicalRecordHomePage.setA23C(item.getA23C());
            // 户口地址 A24 字符 200 必填
            medicalRecordHomePage.setA24(item.getA24()== null ? CommonConstants.Common.DASH:item.getA24());
            // 户口地址邮政编码 A25C 字符 6 必填
            medicalRecordHomePage.setA25C(item.getA25C());
            // 现住址 A26 字符 200 必填
            medicalRecordHomePage.setA26(item.getA26()== null ? CommonConstants.Common.DASH:item.getA26());
            // 现住址电话 A27 字符 40 必填
            medicalRecordHomePage.setA27(item.getA27()== null ? CommonConstants.Common.DASH:item.getA27());
            // 现住址邮政编码 A28C 字符 6 必填
            medicalRecordHomePage.setA28C(item.getA28C());
            // 工作单位及地址 A29 字符 200 必填
            medicalRecordHomePage.setA29(item.getA29()== null ? CommonConstants.Common.DASH:item.getA29());
            // 工作单位电话 A30 字符 20 必填
            medicalRecordHomePage.setA30(item.getA30()== null ? CommonConstants.Common.DASH:item.getA30());
            // 工作单位邮政编码 A31C 字符 6 必填
            medicalRecordHomePage.setA31C(item.getA31C());
            // 联系人姓名 A32 字符 40 必填
            medicalRecordHomePage.setA32(item.getA32());
            // 联系人关系 A33C 字符 1 必填
            medicalRecordHomePage.setA33C(item.getA33C());
            // 联系人地址 A34 字符 200 必填
            medicalRecordHomePage.setA34(item.getA34()== null ? CommonConstants.Common.DASH:item.getA34());
            // 联系人电话 A35 字符 40 必填
            medicalRecordHomePage.setA35(item.getA35());
            // 是否为日间手术 B38 字符 1 必填
            medicalRecordHomePage.setB38(item.getB38());
            // 入院途径 B11C 字符 1 必填
            medicalRecordHomePage.setB11C(item.getB11C());
            // 入院科别 B13C 字符 6 必填
            medicalRecordHomePage.setB13C(item.getB13C());
            // 入院病房 B14 字符 30 必填
            medicalRecordHomePage.setB14(item.getB14());
            // 转科科别 B21C 集合 可以多选 必填
            medicalRecordHomePage.setB21C(String.join(CommonConstants.Common.COMMA, item.getB21C()));
            // 出院科别 B16C 字符 6 必填
            medicalRecordHomePage.setB16C(item.getB16C());
            // 出院病房 B17 字符 30 必填
            medicalRecordHomePage.setB17(item.getB17());
            // 实际住院（天） B20 数字 6 必填
            medicalRecordHomePage.setB20(item.getB20() == null ? 0 : item.getB20());
            // 门（急）诊诊断编码 C01C 字符 20 必填
            medicalRecordHomePage.setC01C(item.getC01C());
            // 门（急）诊诊断名称 C02N 字符 100 必填
            medicalRecordHomePage.setC02N(item.getC02N());
            // 出院主要诊断编码 C03C 字符 20 必填
            medicalRecordHomePage.setC03C(item.getC03C());
            // 出院主要诊断名称 C04N 字符 100 必填
            medicalRecordHomePage.setC04N(item.getC04N());
            // 出院主要诊断入院病情 C05C 字符 1 必填
            medicalRecordHomePage.setC05C(item.getC05C());
            String c03c = medicalRecordHomePage.getC03C();
            if (c03c != null && !c03c.isEmpty()) {
                char firstChar = c03c.charAt(0);
                // 主要诊断ICD编码首字母为C或D00-D48时必填。
                if (firstChar == 'C' || (c03c.length() >= 3 && c03c.matches("D(0[0-9]|[1-3][0-9]|4[0-8]).*"))) {
                    // 病理诊断编码 C09C 字符 20 条件必填
                    medicalRecordHomePage.setC09C(item.getC09C());
                    // 病理诊断名称 C10N 字符 100 条件必填
                    medicalRecordHomePage.setC10N(item.getC10N());
                    // 病理号 C11 字符 50 条件必填
                    medicalRecordHomePage.setC11(item.getC11());
                }
                // 主要诊断ICD编码首字母为S或T时必填
                if (firstChar == 'S' || firstChar == 'T') {
                    // 损伤、中毒外部原因编码 C12C 字符 20 条件必填
                    medicalRecordHomePage.setC12C(item.getC12C());
                    // 损伤、中毒外部原因名称 C13N 字符 100 条件必填
                    medicalRecordHomePage.setC13N(item.getC13N());
                }
            }
            // 有无药物过敏 C24C 字符 1 必填
            medicalRecordHomePage.setC24C(item.getC24C());
            // “有无药物过敏”为“有”时必填；多种药物用英文逗号进行分隔
            if (medicalRecordHomePage.getC24C().equals("2")) {
                // 过敏药物名称 C25 字符 200 条件必填
                medicalRecordHomePage.setC25(item.getC25());
            }
            // 科主任编码 B22C 字符 30 必填
            medicalRecordHomePage.setB22C(item.getB22C());
            // 科主任 B22 字符 40 必填
            medicalRecordHomePage.setB22(item.getB22());
            // 主（副主）任医师编码 B23C 字符 30 必填
            medicalRecordHomePage.setB23C(item.getB23C());
            // 主（副主）任医师 B23 字符 40 必填
            medicalRecordHomePage.setB23(item.getB23());
            // 主治医师编码 B24C 字符 30 必填
            medicalRecordHomePage.setB24C(item.getB24C());
            // 主治医师 B24 字符 40 必填
            medicalRecordHomePage.setB24(item.getB24());
            // 住院医师编码 B25C 字符 30 必填
            medicalRecordHomePage.setB25C(item.getB25C());
            // 住院医师 B25 字符 40 必填
            medicalRecordHomePage.setB25(item.getB25());
            // 责任护士编码 B26C 字符 30 必填
            medicalRecordHomePage.setB26C(item.getB26C());
            // 责任护士 B26 字符 40 必填
            medicalRecordHomePage.setB26(item.getB26());
            // 编码员 B29 字符 40 必填
            medicalRecordHomePage.setB29(item.getB29());
            // ABO血型 C26C 字符 1 必填
            medicalRecordHomePage.setC26C(item.getC26C());
            // Rh血型 C27C 字符 1 必填
            medicalRecordHomePage.setC27C(item.getC27C());
            // 主要手术操作编码 C14x01C 字符 20 必填
            medicalRecordHomePage.setC14x01C(item.getC14x01C());
            // 主要手术操作名称 C15x01N 字符 100 必填
            medicalRecordHomePage.setC15x01N(item.getC15x01N());
            // 主要手术操作日期 C16x01 日期时间 必填
            medicalRecordHomePage.setC16x01(item.getC16x01());
            // 手术操作编码属性为手术或介入治疗代码时必填 todo 手术或介入治疗代码
            if (medicalRecordHomePage.getC14x01C().equals("") || medicalRecordHomePage.getC14x01C().equals("")) {
                // 主要手术操作级别 C17x01 字符 1 条件必填
                medicalRecordHomePage.setC17x01(item.getC17x01());
                // 主要手术操作术者 C18x01 字符 40 条件必填
                medicalRecordHomePage.setC18x01(item.getC18x01());
                // 主要手术操作Ⅰ助 C19x01 字符 40 条件必填
                medicalRecordHomePage.setC19x01(item.getC19x01());
                // 主要手术操作Ⅱ助 C20x01 字符 40 条件必填
                medicalRecordHomePage.setC20x01(item.getC20x01());
                // 手术编码属性为手术时必填 todo 手术代码
                if (medicalRecordHomePage.getC14x01C().equals("")) {
                    // 主要手术操作切口愈合等级 C21x01C 字符 2 条件必填
                    medicalRecordHomePage.setC21x01C(item.getC21x01C());
                    // 主要手术操作麻醉方式 C22x01C 字符 6 条件必填
                    medicalRecordHomePage.setC22x01C(item.getC22x01C());
                    // 主要手术操作麻醉医师 C23x01 字符 40 条件必填
                    medicalRecordHomePage.setC23x01(item.getC23x01());
                }
            }

            // 16.血费 D26 数字 (10,2)
            medicalRecordHomePage.setD26(item.getD26() == null ? BigDecimal.ZERO : item.getD26());
            // 血费>0,则必填，没有可以填0或英文横杠”-”
            if (medicalRecordHomePage.getD26().compareTo(BigDecimal.ZERO) > 0) {
                // 输血反应 F21 数字 1 条件必填
                medicalRecordHomePage.setF21(item.getF21() == null ? 0 : item.getF21());
                // 红细胞 F22 数字 (4,1) 条件必填
                medicalRecordHomePage.setF22(item.getF22() == null ? BigDecimal.ZERO : item.getF22());
                // 血小板 F23 数字 (4,1) 条件必填
                medicalRecordHomePage.setF23(item.getF23() == null ? BigDecimal.ZERO : item.getF23());
                // 血浆 F24 数字 (8,2) 条件必填
                medicalRecordHomePage.setF24(item.getF24() == null ? BigDecimal.ZERO : item.getF24());
                // 全血 F25 数字 (8,2) 条件必填
                medicalRecordHomePage.setF25(item.getF25() == null ? BigDecimal.ZERO : item.getF25());
                // 自体血回输 F26 数字 (4,1) 条件必填
                medicalRecordHomePage.setF26(item.getF26() == null ? BigDecimal.ZERO : item.getF26());
            } else {
                // 输血反应 F21 数字 1 条件必填
                medicalRecordHomePage.setF21(0);
                // 红细胞 F22 数字 (4,1) 条件必填
                medicalRecordHomePage.setF22(BigDecimal.ZERO);
                // 血小板 F23 数字 (4,1) 条件必填
                medicalRecordHomePage.setF23(BigDecimal.ZERO);
                // 血浆 F24 数字 (8,2) 条件必填
                medicalRecordHomePage.setF24(BigDecimal.ZERO);
                // 全血 F25 数字 (8,2) 条件必填
                medicalRecordHomePage.setF25(BigDecimal.ZERO);
                // 自体血回输 F26 数字 (4,1) 条件必填
                medicalRecordHomePage.setF26(BigDecimal.ZERO);
            }
            if (medicalRecordHomePage.getA14().equals(0)) {
                // 年龄不足1周岁的年龄（天） A16 数字 3 条件必填②
                medicalRecordHomePage.setA16(item.getA16() == null ? 0 : item.getA16());
            }
            // 产妇和新生儿病案填写 todo 产妇怎么判断
            // if(){
            // 新生儿出生体重（克） A18x01 数字 6 条件必填②
            medicalRecordHomePage.setA18x01(item.getA18x01() == null ? 0 : item.getA18x01());
            // }
            // “新生儿入院体重”与“年龄不足1周岁的年龄（天）”互为逻辑校验项，小于等于28天的新生儿必填。
            if (medicalRecordHomePage.getA16() != null && medicalRecordHomePage.getA16() <= 28) {
                // 新生儿入院体重（克） A17 数字 6 条件必填②
                medicalRecordHomePage.setA17(item.getA17() == null ? 0 : item.getA17());
            }
            // 颅脑损伤患者入院前昏迷时间（天） C28 数字 5 必填
            medicalRecordHomePage.setC28(item.getC28() == null ? 0 : item.getC28());
            // 颅脑损伤患者入院前昏迷时间（小时） C29 数字 2 必填
            medicalRecordHomePage.setC29(item.getC29() == null ? 0 : item.getC29());
            // 颅脑损伤患者入院前昏迷时间（分钟） C30 数字 2 必填
            medicalRecordHomePage.setC30(item.getC30() == null ? 0 : item.getC30());
            // 颅脑损伤患者入院后昏迷时间（天） C31 数字 5 必填
            medicalRecordHomePage.setC31(item.getC31() == null ? 0 : item.getC31());
            // 颅脑损伤患者入院后昏迷时间（小时） C32 数字 2 必填
            medicalRecordHomePage.setC32(item.getC32() == null ? 0 : item.getC32());
            // 颅脑损伤患者入院后昏迷时间（分钟） C33 数字 2 必填
            medicalRecordHomePage.setC33(item.getC33() == null ? 0 : item.getC33());
            // 是否有出院31日内再住院计划 B36C 数字 1 必填
            medicalRecordHomePage.setB36C(item.getB36C() == null ? 0 : item.getB36C());
            // 是否有出院31日内再住院计划填“有”时必填。
            if (medicalRecordHomePage.getB36C().equals(2)) {
                // 出院31天再住院计划目的 B37 字符 100 条件必填
                medicalRecordHomePage.setB37(item.getB37());
            }
            // 离院方式 B34C 字符 1 必填
            medicalRecordHomePage.setB34C(item.getB34C());
            // 离院方式为医嘱转院或医嘱转社区患者必填
            if (medicalRecordHomePage.getB34C().equals("2") || medicalRecordHomePage.getB34C().equals("3")) {
                // 医嘱转院、转社区卫生服务机构/乡镇卫生院名称 B35 字符 100 条件必填
                medicalRecordHomePage.setB35(item.getB35());
            }
            // 住院总费用 D01 数字 (11,2) 必填
            medicalRecordHomePage.setD01(item.getD01() == null ? BigDecimal.ZERO : item.getD01());
            // 住院总费用其中自付金额 D09 数字 (10,2) 必填
            medicalRecordHomePage.setD09(item.getD09() == null ? BigDecimal.ZERO : item.getD09());

            medicalRecordHomePageList.add(medicalRecordHomePage);
        }
        try {
            // 做成csv文件
             CsvFillerUtil.makeCsvFile(response, medicalRecordHomePageList);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("写入csv时发生错误：" + e.getMessage());
            return R.fail("写入csv时发生错误：" + e.getMessage());
        }

        return R.ok();
    }
}
