package com.openhis.web.inventorymanage.appservice.impl;

import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.administration.domain.ChangePriceRecord;
import com.openhis.administration.domain.ChargeItemDefDetail;
import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.dto.ChangePriceDataDto;
import com.openhis.administration.service.IChangePriceRecordService;
import com.openhis.administration.service.IChargeItemDefDetailService;
import com.openhis.administration.service.IChargeItemDefinitionService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.enums.ConditionCode;
import com.openhis.common.enums.DelFlag;
import com.openhis.common.enums.SupplyStatus;
import com.openhis.common.enums.SupplyType;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.common.utils.RedisKeys;
import com.openhis.common.utils.RedisUtil;
import com.openhis.web.adjustprice.dto.AdjustPriceManagerSearchParam;
import com.openhis.web.adjustprice.dto.ChangePricePageDto;
import com.openhis.web.inventorymanage.appservice.IInventoryAdjustPriceService;
import com.openhis.web.inventorymanage.dto.ReceiptApprovalSearchParam;
import com.openhis.web.inventorymanage.dto.ReceiptInitDto;
import com.openhis.web.inventorymanage.mapper.InventoryAdjustPriceMapper;

/**
 * @ClassName IInventoryAdjustPriceServiceImpl
 * @Description TODO
 * @Author raymond
 * @Date 2025/10/23 14:57
 * @Version 1.0
 **/
@Service
public class IInventoryAdjustPriceServiceImpl implements IInventoryAdjustPriceService {
    @Resource
    private IChargeItemDefinitionService chargeItemDefinitionService;
    @Resource
    private IChargeItemDefDetailService chargeItemDefDetailService;
    @Resource
    private InventoryAdjustPriceMapper inventoryAdjustPriceMapper;
    @Resource
    private IChangePriceRecordService changePriceRecordService;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public R<?> getPageByExamineList(AdjustPriceManagerSearchParam adjustPriceManagerSearchParam, Integer pageNo,
        Integer pageSize, String searchKey, HttpServletRequest request) {
        // 设置模糊查询的字段名
        HashSet<String> searchFields = new HashSet<>();
        searchFields.add(CommonConstants.FieldName.SupplyBusNo);

        QueryWrapper<ReceiptApprovalSearchParam> queryWrapper =
            HisQueryUtils.buildQueryWrapper(adjustPriceManagerSearchParam, searchKey, searchFields, request);
        // 查询单据分页列表
        Page<ChangePricePageDto> receiptPage = inventoryAdjustPriceMapper.searchPageByExamine(
            new Page<>(pageNo, pageSize), queryWrapper, SupplyStatus.APPROVAL.getValue(), SupplyStatus.AGREE.getValue(),
            SupplyStatus.REJECT.getValue(), SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue(),
            SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue(), SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue(),
            SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue());

        receiptPage.getRecords().forEach(e -> {
            e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
            // 调价类型
            e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getItemCategoryEnum()));
        });
        return R.ok(receiptPage);
    }

    @Override
    public R<?> updateExamineByRejected(String busNo) {
        List<ChangePriceRecord> changePriceRecordList =
            this.changePriceRecordService.searchChangePriceDataForBusNo(busNo);
        if (changePriceRecordList.isEmpty()) {
            return R.fail();
        }
        // 循环将数据进行填充
        for (ChangePriceRecord data : changePriceRecordList) {
            if (this.redisUtil.hasKey(RedisKeys.getProductsKey(data.getItemId().toString()))) {
                this.redisUtil.del(RedisKeys.getProductsKey(data.getItemId().toString()));
            }
        }
        this.changePriceRecordService.rejectRequest(busNo);

        return R.ok();
    }

    @Override
    public R<?> adjustPriceInit() {
        ReceiptInitDto initDto = new ReceiptInitDto();
        // 审批状态
        List<ReceiptInitDto.supplyStatusOption> supplyStatusOptions = Stream.of(SupplyStatus.values())
            .map(supplyStatus -> new ReceiptInitDto.supplyStatusOption(supplyStatus.getValue(), supplyStatus.getInfo()))
            .collect(Collectors.toList());
        initDto.setSupplyStatusOptions(supplyStatusOptions);
        return R.ok(initDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<?> updateExamineByApproved(String busNo) {
        List<ChangePriceRecord> changePriceRecordList =
            this.changePriceRecordService.searchChangePriceDataForBusNo(busNo);
        if (changePriceRecordList.isEmpty()) {
            return R.fail();
        }
        // 循环将数据进行填充
        for (ChangePriceRecord data : changePriceRecordList) {
            if (this.redisUtil.hasKey(RedisKeys.getProductsKey(data.getItemId().toString()))) {
                this.redisUtil.del(RedisKeys.getProductsKey(data.getItemId().toString()));
            }
        }
        this.executeBusiness(busNo);
        this.changePriceRecordService.agreeRequest(busNo, new Date());
        return R.ok();
    }

    /**
     * Desc: 处理审核通过后改价业务
     *
     * @Author raymond
     * @Date 22:16 2025/10/18
     * @return com.core.common.core.domain.R<?>
     **/
    public void executeBusiness(String busNo) {
        List<ChangePriceDataDto> changePriceDataDtoList =
            this.changePriceRecordService.searchChangePriceRecordDataByBusNo(busNo, SupplyStatus.APPROVAL.getValue());
        // 零售价
        List<ChargeItemDefDetail> itemDefDetailRetailList = new LinkedList<>();
        // 进货价
        List<ChargeItemDefDetail> itemDefDetailBuyingList = new LinkedList<>();
        // 进货价
        List<ChargeItemDefDetail> itemDefDetailPurchaseList = new LinkedList<>();
        for (ChangePriceDataDto data : changePriceDataDtoList) {
            // 更新价格主表信息
            ChargeItemDefinition chargeItemDefinition = this.chargeItemDefinitionService.getById(data.getChargeId());
            chargeItemDefinition.setPrice(data.getNewRetailPrice());
            this.chargeItemDefinitionService.updateById(chargeItemDefinition);
            // 零售价
            List<ChargeItemDefDetail> defDetailRetailList =
                this.chargeItemDefDetailService.searchChargeItemDefDetailByIds(chargeItemDefinition.getId(),
                    ConditionCode.LOT_NUMBER_PRICE.getCode(), data.getLotNumber());
            // 进货价
            List<ChargeItemDefDetail> defDetailBuyingList =
                this.chargeItemDefDetailService.searchChargeItemDefDetailByIds(chargeItemDefinition.getId(),
                    ConditionCode.LOT_NUMBER_COST.getCode(), data.getLotNumber());
            // 采购价
            List<ChargeItemDefDetail> purchasePriceList = this.chargeItemDefDetailService
                .searchChargeItemDefDetailByIds(chargeItemDefinition.getId(), ConditionCode.PURCHASE.getCode(), null);
            if (!defDetailRetailList.isEmpty()) {
                for (ChargeItemDefDetail detail : defDetailRetailList) {
                    detail.setDeleteFlag(DelFlag.YES.getCode());
                    this.chargeItemDefDetailService.deleteChargeItemDefApp(detail.getId());
                }
                ChargeItemDefDetail chargeItemDefDetail = new ChargeItemDefDetail();
                chargeItemDefDetail.setDefinitionId(data.getChargeId());
                chargeItemDefDetail.setConditionCode(ConditionCode.LOT_NUMBER_PRICE.getCode());
                chargeItemDefDetail.setConditionValue(data.getLotNumber());
                chargeItemDefDetail.setAmount(data.getNewRetailPrice());
                itemDefDetailRetailList.add(chargeItemDefDetail);
            }
            if (!defDetailBuyingList.isEmpty()) {
                for (ChargeItemDefDetail detail : defDetailBuyingList) {
                    detail.setDeleteFlag(DelFlag.YES.getCode());
                    this.chargeItemDefDetailService.deleteChargeItemDefApp(detail.getId());
                }
                ChargeItemDefDetail chargeItemDefDetail = new ChargeItemDefDetail();
                chargeItemDefDetail.setDefinitionId(data.getChargeId());
                chargeItemDefDetail.setConditionCode(ConditionCode.LOT_NUMBER_COST.getCode());
                chargeItemDefDetail.setConditionValue(data.getLotNumber());
                chargeItemDefDetail.setAmount(data.getNewBuyingPrice());
                itemDefDetailBuyingList.add(chargeItemDefDetail);
            }
            if (!purchasePriceList.isEmpty()) {
                for (ChargeItemDefDetail detail : purchasePriceList) {
                    detail.setDeleteFlag(DelFlag.YES.getCode());
                    this.chargeItemDefDetailService.deleteChargeItemDefApp(detail.getId());
                }
                ChargeItemDefDetail chargeItemDefDetail = new ChargeItemDefDetail();
                chargeItemDefDetail.setDefinitionId(data.getChargeId());
                chargeItemDefDetail.setConditionCode(ConditionCode.PURCHASE.getCode());
                chargeItemDefDetail.setAmount(data.getNewBuyingPrice());
                itemDefDetailPurchaseList.add(chargeItemDefDetail);
            }
        }
        // 批量插入价格子表
        this.chargeItemDefDetailService.saveOrUpdateBatch(itemDefDetailRetailList);
        this.chargeItemDefDetailService.saveOrUpdateBatch(itemDefDetailBuyingList);
        this.chargeItemDefDetailService.saveOrUpdateBatch(itemDefDetailPurchaseList);
    }

}
