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

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.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.trading.domain.BizSupplier;
import com.ruoyi.web.modules.trading.mapper.BizSupplierMapper;
import com.ruoyi.web.modules.trading.service.IBizSupplierService;
import com.ruoyi.web.modules.trading.support.SupplierCodeGenerator;
import com.ruoyi.web.modules.trading.support.SupplierReferenceChecker;
import com.ruoyi.web.modules.trading.support.SupplierRules;
import com.ruoyi.web.modules.trading.support.SupplierValidation;
import com.ruoyi.web.modules.trading.support.TradePartnerAccountAssigner;
import com.ruoyi.web.modules.trading.support.TradePartnerAccountRules;
import com.ruoyi.web.modules.trading.support.SupplierVehiclePlatesHelper;

/**
 * 供应商管理服务实现。
 */
@Service
public class BizSupplierServiceImpl implements IBizSupplierService
{
    @Autowired
    private BizSupplierMapper bizSupplierMapper;

    @Autowired
    private SupplierCodeGenerator supplierCodeGenerator;

    @Autowired
    private SupplierReferenceChecker referenceChecker;

    @Autowired
    private TradePartnerAccountAssigner accountAssigner;

    @Override
    public BizSupplier selectBizSupplierById(Long id)
    {
        BizSupplier row = bizSupplierMapper.selectBizSupplierById(id);
        enrichRow(row);
        return row;
    }

    @Override
    public List<BizSupplier> selectBizSupplierList(BizSupplier query)
    {
        List<BizSupplier> list = bizSupplierMapper.selectBizSupplierList(query);
        if (list != null)
        {
            for (BizSupplier row : list)
            {
                enrichRow(row);
            }
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertBizSupplier(BizSupplier row)
    {
        row.setSupplierCode(null);
        SupplierValidation.validateRowForSave(row);
        assertSupplierNameUnique(row.getSupplierName(), null);
        assertIdentityNoUnique(row.getIdentityNo(), null);
        row.setSupplierCode(supplierCodeGenerator.allocateNextCode());
        row.setDelFlag(SupplierRules.DEL_FLAG_NORMAL);
        row.setAccountAssigned(TradePartnerAccountRules.ACCOUNT_ASSIGNED_NO);
        row.setSysUserId(null);
        row.setAssignedLoginName(null);
        return bizSupplierMapper.insertBizSupplier(row);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateBizSupplier(BizSupplier row)
    {
        if (row.getId() == null)
        {
            throw new ServiceException("主键不能为空");
        }
        BizSupplier db = requireActiveRow(row.getId());
        if (StringUtils.isNotEmpty(row.getSupplierCode())
                && !row.getSupplierCode().equals(db.getSupplierCode()))
        {
            throw new ServiceException("供应商编号不可修改");
        }
        row.setSupplierCode(db.getSupplierCode());
        SupplierValidation.validateRowForSave(row);
        assertSupplierNameUnique(row.getSupplierName(), row.getId());
        assertIdentityNoUnique(row.getIdentityNo(), row.getId());
        row.setDelFlag(SupplierRules.DEL_FLAG_NORMAL);
        row.setAccountAssigned(db.getAccountAssigned());
        row.setSysUserId(db.getSysUserId());
        row.setAssignedLoginName(db.getAssignedLoginName());
        return bizSupplierMapper.updateBizSupplier(row);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteBizSupplierByIds(Long[] ids, String updateBy)
    {
        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)
        {
            BizSupplier row = bizSupplierMapper.selectBizSupplierByIdAny(id);
            if (row == null || SupplierRules.DEL_FLAG_DELETED.equals(row.getDelFlag()))
            {
                continue;
            }
            if (referenceChecker.hasUnsettledSettlement(id))
            {
                throw new ServiceException(SupplierRules.MSG_DELETE_UNSETTLED_SETTLEMENT);
            }
            accountAssigner.deleteLinkedAccount(row.getAccountAssigned(), row.getSysUserId());
        }
        return bizSupplierMapper.logicDeleteBizSupplierByIds(cleaned.toArray(new Long[0]), updateBy);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int assignAccount(Long id, String operator)
    {
        BizSupplier row = requireActiveRow(id);
        SupplierValidation.validateForAssignAccount(row);
        SysUser user = accountAssigner.createAccount(
                row.getSupplierName(), row.getContactPhone(), row.getId(),
                TradePartnerAccountRules.ROLE_KEY_SUPPLIER, operator);
        row.setAccountAssigned(TradePartnerAccountRules.ACCOUNT_ASSIGNED_YES);
        row.setSysUserId(user.getUserId());
        row.setAssignedLoginName(user.getUserName());
        row.setUpdateBy(operator);
        return bizSupplierMapper.updateBizSupplier(row);
    }

    private void assertSupplierNameUnique(String supplierName, Long excludeId)
    {
        if (bizSupplierMapper.countBizSupplierByNameExcludeId(supplierName, excludeId) > 0)
        {
            throw new ServiceException("供应商名称已存在");
        }
    }

    private void assertIdentityNoUnique(String identityNo, Long excludeId)
    {
        if (bizSupplierMapper.countBizSupplierByIdentityNoExcludeId(identityNo, excludeId) > 0)
        {
            throw new ServiceException("该身份识别号已登记");
        }
    }

    private BizSupplier requireActiveRow(Long id)
    {
        BizSupplier row = bizSupplierMapper.selectBizSupplierById(id);
        if (row == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        return row;
    }

    private static void enrichRow(BizSupplier row)
    {
        if (row == null)
        {
            return;
        }
        row.setVehiclePlates(SupplierVehiclePlatesHelper.fromJson(row.getVehiclePlatesJson()));
        row.setSupplierTypeName(SupplierRules.supplierTypeName(row.getSupplierType()));
        row.setFeeMethodName(SupplierRules.feeMethodName(row.getFeeMethod()));
    }
}
