package com.ruoyi.web.modules.architecture.service.impl;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.kb.support.KbApiProperties;
import com.ruoyi.web.kb.support.KbMarkdownGenerator;
import com.ruoyi.web.kb.service.KnowledgeBaseClient;
import com.ruoyi.web.modules.architecture.domain.BizDrugIncompatibilityCompanion;
import com.ruoyi.web.modules.architecture.domain.BizDrugIncompatibilityStandard;
import com.ruoyi.web.modules.architecture.mapper.BizDrugIncompatibilityCompanionMapper;
import com.ruoyi.web.modules.architecture.mapper.BizDrugIncompatibilityStandardMapper;
import com.ruoyi.web.modules.architecture.service.IBizDrugIncompatibilityStandardService;
import com.ruoyi.web.modules.architecture.support.DrugIncompatibilityStandardKbMarkdown;
import com.ruoyi.web.modules.architecture.support.DrugIncompatibilityStandardRules;
import com.ruoyi.web.modules.architecture.support.DrugIncompatibilityStandardValidation;

/**
 * 药物禁配标准；同步/移出知识库调用大模型知识库开放 API（方式一：上传生成的 Markdown）。
 */
@Service
public class BizDrugIncompatibilityStandardServiceImpl implements IBizDrugIncompatibilityStandardService
{
    private static final String KB_CATEGORY_DRUG_INCOMPATIBILITY = "药物禁配标准";

    @Autowired
    private BizDrugIncompatibilityStandardMapper bizDrugIncompatibilityStandardMapper;

    @Autowired
    private BizDrugIncompatibilityCompanionMapper bizDrugIncompatibilityCompanionMapper;

    @Autowired
    private KnowledgeBaseClient knowledgeBaseClient;

    @Autowired
    private KbApiProperties kbApiProperties;

    @Autowired
    private DrugIncompatibilityStandardKbMarkdown drugIncompatibilityKbMarkdown;

    @Autowired
    private KbMarkdownGenerator kbMarkdownGenerator;

    @Override
    public BizDrugIncompatibilityStandard selectBizDrugIncompatibilityStandardById(Long id)
    {
        BizDrugIncompatibilityStandard row = bizDrugIncompatibilityStandardMapper.selectBizDrugIncompatibilityStandardById(id);
        if (row != null)
        {
            row.setCompanions(bizDrugIncompatibilityCompanionMapper.selectBizDrugIncompatibilityCompanionListByStandardId(id));
        }
        return row;
    }

    @Override
    public List<BizDrugIncompatibilityStandard> selectBizDrugIncompatibilityStandardList(BizDrugIncompatibilityStandard query)
    {
        return bizDrugIncompatibilityStandardMapper.selectBizDrugIncompatibilityStandardList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertBizDrugIncompatibilityStandard(BizDrugIncompatibilityStandard row)
    {
        prepareAndValidate(row);
        row.setKbSyncStatus(0);
        row.setKbDocId(null);
        int n = bizDrugIncompatibilityStandardMapper.insertBizDrugIncompatibilityStandard(row);
        if (n > 0 && row.getId() != null)
        {
            insertCompanions(row.getId(), row.getCompanions());
        }
        return n;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateBizDrugIncompatibilityStandard(BizDrugIncompatibilityStandard row)
    {
        if (row.getId() == null)
        {
            throw new ServiceException("主键不能为空");
        }
        prepareAndValidate(row);
        BizDrugIncompatibilityStandard db = requireRow(row.getId());
        if (!DrugIncompatibilityStandardRules.canEdit(db.getKbSyncStatus()))
        {
            throw new ServiceException("仅「未同步」状态允许编辑");
        }
        row.setKbSyncStatus(db.getKbSyncStatus());
        row.setKbDocId(db.getKbDocId());
        int n = bizDrugIncompatibilityStandardMapper.updateBizDrugIncompatibilityStandard(row);
        if (n > 0)
        {
            bizDrugIncompatibilityCompanionMapper.deleteBizDrugIncompatibilityCompanionByStandardId(row.getId());
            insertCompanions(row.getId(), row.getCompanions());
        }
        return n;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteBizDrugIncompatibilityStandardByIds(Long[] ids)
    {
        if (ids == null || ids.length == 0)
        {
            return 0;
        }
        List<Long> cleaned = new ArrayList<>();
        for (Long id : ids)
        {
            if (id != null)
            {
                cleaned.add(id);
            }
        }
        if (cleaned.isEmpty())
        {
            return 0;
        }
        for (Long id : cleaned)
        {
            BizDrugIncompatibilityStandard row = bizDrugIncompatibilityStandardMapper.selectBizDrugIncompatibilityStandardById(id);
            if (row == null)
            {
                continue;
            }
            if (!DrugIncompatibilityStandardRules.canDelete(row.getKbSyncStatus()))
            {
                throw new ServiceException("已同步的数据不可删除，请先移出知识库");
            }
        }
        return bizDrugIncompatibilityStandardMapper.deleteBizDrugIncompatibilityStandardByIds(cleaned.toArray(new Long[0]));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int syncKb(Long id)
    {
        BizDrugIncompatibilityStandard row = requireRow(id);
        if (!DrugIncompatibilityStandardRules.canSyncKb(row.getKbSyncStatus()))
        {
            throw new ServiceException("仅「未同步」可操作同步知识库");
        }
        Path mdFile = drugIncompatibilityKbMarkdown.generateForSync(row);
        try
        {
            String fileId = knowledgeBaseClient.uploadFile(
                    mdFile.toFile(),
                    mdFile.getFileName().toString(),
                    kbApiProperties.getDefaultKnowledgeBase(),
                    KB_CATEGORY_DRUG_INCOMPATIBILITY);
            row.setKbSyncStatus(1);
            row.setKbDocId(fileId);
            return bizDrugIncompatibilityStandardMapper.updateBizDrugIncompatibilityStandard(row);
        }
        finally
        {
            kbMarkdownGenerator.deleteQuietly(mdFile);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeKb(Long id)
    {
        BizDrugIncompatibilityStandard row = requireRow(id);
        if (!DrugIncompatibilityStandardRules.canRemoveKb(row.getKbSyncStatus()))
        {
            throw new ServiceException("仅「已同步」可移出知识库");
        }
        String docId = row.getKbDocId();
        if (StringUtils.isNotEmpty(docId) && !docId.startsWith("LOCAL-"))
        {
            knowledgeBaseClient.deleteFile(docId);
        }
        row.setKbSyncStatus(0);
        row.setKbDocId(null);
        return bizDrugIncompatibilityStandardMapper.updateBizDrugIncompatibilityStandard(row);
    }

    private void prepareAndValidate(BizDrugIncompatibilityStandard row)
    {
        DrugIncompatibilityStandardValidation.trimFieldsForSave(row);
        DrugIncompatibilityStandardValidation.validateMainDrugName(row.getMainDrugName());
        DrugIncompatibilityStandardValidation.validateCompatResult(row.getCompatResult());
        DrugIncompatibilityStandardValidation.validateCompanions(row);
    }

    private void insertCompanions(Long standardId, List<BizDrugIncompatibilityCompanion> companions)
    {
        if (companions == null)
        {
            return;
        }
        for (int i = 0; i < companions.size(); i++)
        {
            BizDrugIncompatibilityCompanion c = companions.get(i);
            if (c == null)
            {
                continue;
            }
            c.setStandardId(standardId);
            c.setSortOrder(i);
            bizDrugIncompatibilityCompanionMapper.insertBizDrugIncompatibilityCompanion(c);
        }
    }

    private BizDrugIncompatibilityStandard requireRow(Long id)
    {
        BizDrugIncompatibilityStandard row = bizDrugIncompatibilityStandardMapper.selectBizDrugIncompatibilityStandardById(id);
        if (row == null)
        {
            throw new ServiceException("记录不存在");
        }
        return row;
    }
}
