package com.ruoyi.inventory.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.inventory.domain.HealthcareDrugArchive;
import com.ruoyi.inventory.domain.HealthcareDrugFiling;
import com.ruoyi.inventory.domain.HealthcareInventoryDrugentry;
import com.ruoyi.inventory.domain.HealthcareInventoryDrugentryDetails;
import com.ruoyi.inventory.domain.HealthcareInventoryStoreroom;
import com.ruoyi.inventory.mapper.HealthcareDrugArchiveMapper;
import com.ruoyi.inventory.mapper.HealthcareDrugFilingMapper;
import com.ruoyi.inventory.mapper.HealthcareInventoryDrugentryMapper;
import com.ruoyi.inventory.mapper.HealthcareInventoryStoreroomMapper;
import com.ruoyi.inventory.service.IHealthcareDrugFilingService;

import lombok.extern.slf4j.Slf4j;

/**
 * 药品库存Service业务层处理
 *
 * @author 蒋松霖
 * @date 2024-09-24
 */
@Slf4j
@Service
public class HealthcareDrugFilingServiceImpl implements IHealthcareDrugFilingService {

    @Autowired
    private HealthcareDrugFilingMapper healthcareDrugFilingMapper;
    @Autowired
    public HealthcareDrugArchiveMapper healthcareDrugArchiveMapper;

    @Autowired
    public HealthcareInventoryDrugentryMapper healthcareInventoryDrugentryMapper;

    @Autowired
    public HealthcareInventoryStoreroomMapper healthcareInventoryStoreroomMapper;

    /**
     * 查询药品库存
     *
     * @param id 药品库存主键
     * @return 药品库存
     */
    @Override
    public HealthcareDrugFiling selectHealthcareDrugFilingById(Long id) {
        return healthcareDrugFilingMapper.selectHealthcareDrugFilingById(id);
    }

    @Override
    public List<HealthcareDrugFiling> selectHealthcareDrugFilingByArchiveId(Long archiveId) {
        return healthcareDrugFilingMapper.selectHealthcareDrugFilingByArchiveId(archiveId);
    }

    @Override
    public List<HealthcareDrugFiling> selectHealthcareDrugFilingByBatch(@Param("batch") String batch,
            @Param("barcode") String barcode) {
        return healthcareDrugFilingMapper.selectHealthcareDrugFilingByArchiveBatch(batch);
    }

    /**
     * 查询药品库存列表
     *
     * @param healthcareDrugFiling 药品库存
     * @return 药品库存列表
     */
    @Override
    public List<HealthcareDrugFiling> selectHealthcareDrugFilingList(HealthcareDrugFiling healthcareDrugFiling) {

        return healthcareDrugFilingMapper.selectHealthcareDrugFilingList(healthcareDrugFiling);
    }

    /**
     * 新增药品库存
     *
     * @param healthcareDrugFiling 药品库存
     * @return 结果
     */
    @Override
    public int insertHealthcareDrugFiling(HealthcareDrugFiling healthcareDrugFiling) {
        healthcareDrugFiling.setCreateTime(DateUtils.getNowDate());
        return healthcareDrugFilingMapper.insertHealthcareDrugFiling(healthcareDrugFiling);
    }

    /**
     * 修改药品库存
     *
     * @param healthcareDrugFiling 药品库存
     * @return 结果
     */
    @Override
    public int updateHealthcareDrugFiling(HealthcareDrugFiling healthcareDrugFiling) {
        healthcareDrugFiling.setUpdateTime(DateUtils.getNowDate());
        return healthcareDrugFilingMapper.updateHealthcareDrugFiling(healthcareDrugFiling);
    }

    /**
     * 批量删除药品库存
     *
     * @param ids 需要删除的药品库存主键
     * @return 结果
     */
    @Override
    public int deleteHealthcareDrugFilingByIds(Long[] ids) {
        return healthcareDrugFilingMapper.deleteHealthcareDrugFilingByIds(ids);
    }

    /**
     * 删除药品库存信息
     *
     * @param id 药品库存主键
     * @return 结果
     */
    @Override
    public int deleteHealthcareDrugFilingById(Long id) {
        return healthcareDrugFilingMapper.deleteHealthcareDrugFilingById(id);
    }

    private String generateOrderNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 获取当前时间年月日时分秒
        String currentDataTime = simpleDateFormat.format(new Date());
        Random rd = new Random();
        int rdNumber = rd.nextInt(9000) + 1000; // 获取四位随机数
        return currentDataTime + rdNumber;
    };

    @Override
    @Transactional
    public int insertHealthcareInventoryFilings(List<HealthcareDrugFiling> list) {
        if (list == null || list.isEmpty()) {
            throw new IllegalArgumentException("List cannot be null or empty");
        }
        String currentUser = SecurityUtils.getUsername();

        // 计算药品品种数量
        int drugVarietyCount = list.size();

        // 计算药品入库数量
        Long totalQuantity = 0L;
        for (HealthcareDrugFiling item : list) {
            totalQuantity += item.getBoxCount();
        }

        // 计算药品入库金额
        double totalAmount = 0.0;
        for (HealthcareDrugFiling item : list) {
            totalAmount += item.getCountPrice();
        }

        // 生成药品入库单号
        String inboundOrderNumber = generateOrderNo();

        // 创建入库记录
        HealthcareInventoryDrugentry inbound = new HealthcareInventoryDrugentry();
        inbound.setOrderNumber(inboundOrderNumber);
        inbound.setStatus(0); // 入库状态（0）
        inbound.setType("0"); // 入库类型
        inbound.settatolquantity(totalQuantity); // 药品入库数量
        inbound.setAmount(totalAmount); // 药品入库金额
        inbound.setVariety(drugVarietyCount);// 计算药品品种数量
        inbound.setEntryPoint("0"); // 入库点
        inbound.setEntryPerson(currentUser); // 入库操作员
        inbound.setCreateTime(DateUtils.getNowDate());
        inbound.setUpdateTime(DateUtils.getNowDate());

        // 插入入库记录
        healthcareInventoryDrugentryMapper.insertHealthcareInventoryDrugentry(inbound);

        // 创建一个列表来存储所有的入库详情对象
        List<HealthcareInventoryDrugentryDetails> detailsList = new ArrayList<>();

        // 处理药品入库 知无涯
        for (HealthcareDrugFiling item : list) {
            // 获取或创建药品档案ID
            List<HealthcareDrugArchive> existingArchives = healthcareDrugArchiveMapper
                    .selectHealthcareDrugArchiveByBarcode(item.getBarcode());

            Long archiveId;
            HealthcareDrugArchive drugArchive = null;
            if (existingArchives == null || existingArchives.isEmpty()) {
                // 如果没有建档，则先建档
                drugArchive = new HealthcareDrugArchive();
                drugArchive.setBarcode(item.getBarcode());
                drugArchive.setMedicineName(item.getMedicineName());
                drugArchive.setSpecification(item.getSpecification());
                drugArchive.setManufacturer(item.getManufacturer());
                drugArchive.setIsSplit("N"); // 默认不可拆分
                drugArchive.setMinNumber("1"); // 默认1:1
                drugArchive.setCreateTime(DateUtils.getNowDate());
                drugArchive.setCreateBy(currentUser);
                drugArchive.setUpdateTime(DateUtils.getNowDate());
                drugArchive.setUpdateBy(currentUser);
                healthcareDrugArchiveMapper.insertHealthcareDrugArchive(drugArchive);
                archiveId = drugArchive.getId();
            } else {
                drugArchive = existingArchives.get(0);
                archiveId = drugArchive.getId();
            }

            // 保留2位小数
            double minPrice;
            if ("Y".equalsIgnoreCase(drugArchive.getIsSplit()) && drugArchive.getMinNumber() != null) {
                try {
                    double minNumber = Double.parseDouble(drugArchive.getMinNumber());
                    if (minNumber > 0) {
                        // BigDecimal保证精度，并保留2位小数
                        minPrice = new BigDecimal(item.getRetailPrice())
                                .divide(new BigDecimal(minNumber), 2, RoundingMode.CEILING)
                                .doubleValue();
                    } else {
                        minPrice = item.getRetailPrice();
                    }
                } catch (NumberFormatException e) {
                    minPrice = item.getRetailPrice();
                    log.warn("药品档案minNumber转换失败: {}", drugArchive.getMinNumber());
                }
            } else {
                // 不可拆分药品直接取零售价
                minPrice = new BigDecimal(item.getRetailPrice())
                        .setScale(2, RoundingMode.CEILING)
                        .doubleValue();
            }
            item.setMinPrice(minPrice); // 设置到入库对象

            // 获取或创建库房ID
            HealthcareInventoryStoreroom storeroom = healthcareInventoryStoreroomMapper
                    .selectHealthcareInventoryStoreroomByName(item.getStoreroomName());
            if (storeroom == null) {
                storeroom = new HealthcareInventoryStoreroom();
                storeroom.setStoreroomName(item.getStoreroomName());
                healthcareInventoryStoreroomMapper.insertHealthcareInventoryStoreroom(storeroom);
            }

            // 设置库房ID到当前药品项
            item.setStoreroomId(storeroom.getId());
            item.setMinPrice(minPrice); // 设置计算出的最小单位价格

            // 构建查询条件
            HealthcareDrugFiling filingQuery = new HealthcareDrugFiling();
            filingQuery.setBatch(item.getBatch());
            filingQuery.setBarcode(item.getBarcode());
            filingQuery.setArchiveId(archiveId);
            filingQuery.setStoreroomId(item.getStoreroomId());

            // 查询现有库存记录
            List<HealthcareDrugFiling> existingFilings = healthcareDrugFilingMapper
                    .selectHealthcareDrugFilingByBarcodeAndBatch(filingQuery);

            if (existingFilings == null || existingFilings.isEmpty()) {
                // 插入新的库存记录
                item.setCreateTime(DateUtils.getNowDate());
                item.setCreateBy(currentUser);
                item.setUpdateTime(DateUtils.getNowDate());
                item.setUpdateBy(currentUser);
                item.setInventoryUnit(item.getPackageUnit());
                item.setArchiveId(archiveId);
                item.setMinPrice(minPrice); // 设置最小单位价格
                healthcareDrugFilingMapper.insertHealthcareDrugFiling(item);
            } else {
                // 更新现有库存记录
                for (HealthcareDrugFiling existingItem : existingFilings) {
                    existingItem.setInventoryUnit(item.getPackageUnit());
                    existingItem.setUpdateTime(DateUtils.getNowDate());
                    existingItem.setBoxCount(existingItem.getBoxCount() + item.getBoxCount());
                    existingItem.setMinPrice(minPrice); // 更新最小单位价格
                    healthcareDrugFilingMapper.updateHealthcareDrugFiling(existingItem);
                }
            }

            // 创建入库详情对象
            HealthcareInventoryDrugentryDetails details = new HealthcareInventoryDrugentryDetails();
            details.setEntryRecordId(inbound.getId());
            details.setMedicineName(item.getMedicineName());
            details.setBarcode(item.getBarcode());
            details.setBatch(item.getBatch());
            details.setQuantity(item.getBoxCount());
            details.setPrice(item.getRetailPrice());
            details.setExpiryDate(item.getExpiryDate());
            details.setDetailAmount(item.getCountPrice());
            details.setCreateTime(DateUtils.getNowDate());
            details.setStoreroomId(storeroom.getId());
            details.setDrugArchiveId(archiveId);

            detailsList.add(details);
        }

        // 批量插入入库详情
        healthcareInventoryDrugentryMapper.batchHealthcareInventoryDrugentryDetails(detailsList);
        return list.size();
    }

    @Override
    public void deleteHealthcareDrugArchiveByIds(Long[] ids) {
        healthcareDrugFilingMapper.deleteHealthcareDrugArchiveByIds(ids);
    }

    @Override
    public HealthcareDrugFiling findByBatchAndStoreroomId(HealthcareDrugFiling healthcareDrugFiling) {
        return healthcareDrugFilingMapper.findByBatchAndStoreroomId(healthcareDrugFiling);
    }

    @Override
    public HealthcareDrugFiling selectHealthcareDrugFilingByIdAndStoreroom(HealthcareDrugFiling filing) {
        return healthcareDrugFilingMapper.selectHealthcareDrugFilingByIdAndStoreroom(filing);
    }

}
