package com.ruoyi.web.modules.trading.support;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.trading.domain.BizIsolationPatrol;
import com.ruoyi.web.modules.trading.domain.BizIsolationPen;
import com.ruoyi.web.modules.trading.mapper.BizIsolationPatrolMapper;
import com.ruoyi.web.modules.trading.mapper.BizIsolationPenMapper;

/**
 * 隔离巡查登记校验（P1～P3、在栏圈位/耳标）。
 */
@Component
public class PatrolValidation
{
    @Autowired
    private BizIsolationPatrolMapper bizIsolationPatrolMapper;

    @Autowired
    private BizIsolationPenMapper bizIsolationPenMapper;

    public void validateListQuery(BizIsolationPatrol query)
    {
        if (query == null)
        {
            return;
        }
        EntryIsolationValidation.validateDateRange(query.getPatrolDateStart(), query.getPatrolDateEnd());
    }

    public void prepareAndValidateForSave(BizIsolationPatrol row)
    {
        if (row == null)
        {
            throw new ServiceException("巡查数据不能为空");
        }
        trimFields(row);
        if (row.getPatrolTime() == null)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PATROL_TIME_REQUIRED);
        }
        if (row.getPatrolTime().after(new Date()))
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PATROL_TIME_FUTURE);
        }
        if (row.getPenId() == null)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PEN_REQUIRED);
        }
        if (!isPenInStock(row.getPenId()))
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PEN_NOT_IN_STOCK);
        }
        BizIsolationPen pen = bizIsolationPenMapper.selectBizIsolationPenById(row.getPenId());
        if (pen == null)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PEN_NOT_IN_STOCK);
        }
        row.setPenCode(pen.getPenCode());
        validateSickDeadQty(row.getSickDeadQty());
        validateDesc(row.getContentDesc(), IsolationPatrolRules.MSG_CONTENT_REQUIRED);
        validateDesc(row.getHandleDesc(), IsolationPatrolRules.MSG_HANDLE_REQUIRED);
        validatePhoto(row.getPhotoPath());
        List<String> tags = resolveEarTagsForSave(row);
        validateConsistency(row.getSickDeadQty(), tags);
        assertTagsInPen(row.getPenId(), tags);
        if (row.getSickDeadQty() == 0)
        {
            row.setEarTags(null);
            row.setEarTagList(null);
        }
        else
        {
            row.setEarTagList(tags);
            row.setEarTags(EarTagCodec.encode(tags));
        }
        if (StringUtils.isNotEmpty(row.getRemark()) && row.getRemark().length() > IsolationPatrolRules.MAX_REMARK_LEN)
        {
            throw new ServiceException("备注长度不能超过500个字符");
        }
    }

    public boolean isPenInStock(Long penId)
    {
        if (penId == null)
        {
            return false;
        }
        return bizIsolationPatrolMapper.countPenInStock(penId) > 0;
    }

    public List<String> listInStockEarTags(Long penId)
    {
        if (penId == null || !isPenInStock(penId))
        {
            return new ArrayList<>();
        }
        List<String> rows = bizIsolationPatrolMapper.selectAllocEarTagRowsForPen(penId);
        Set<String> merged = new LinkedHashSet<>();
        if (rows != null)
        {
            for (String raw : rows)
            {
                merged.addAll(EarTagCodec.parse(raw));
            }
        }
        return new ArrayList<>(merged);
    }

    public static void validateConsistency(int sickDeadQty, List<String> earTagList)
    {
        int size = earTagList == null ? 0 : earTagList.size();
        if (sickDeadQty == 0)
        {
            if (size > 0)
            {
                throw new ServiceException(IsolationPatrolRules.MSG_QTY_TAG_MISMATCH);
            }
            return;
        }
        if (size == 0)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_EAR_TAG_REQUIRED);
        }
        if (size != sickDeadQty)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_QTY_TAG_MISMATCH);
        }
    }

    private List<String> resolveEarTagsForSave(BizIsolationPatrol row)
    {
        int qty = row.getSickDeadQty() == null ? 0 : row.getSickDeadQty();
        if (qty == 0)
        {
            return new ArrayList<>();
        }
        return EarTagCodec.resolveMainTags(row.getEarTags(), row.getEarTagList());
    }

    private void assertTagsInPen(Long penId, List<String> tags)
    {
        if (tags == null || tags.isEmpty())
        {
            return;
        }
        List<String> inStock = listInStockEarTags(penId);
        Set<String> allowed = new LinkedHashSet<>(inStock);
        for (String tag : tags)
        {
            if (!allowed.contains(tag))
            {
                throw new ServiceException(IsolationPatrolRules.MSG_EAR_TAG_NOT_IN_PEN.replace("{0}", tag));
            }
        }
    }

    private static void validateSickDeadQty(Integer qty)
    {
        if (qty == null || qty < IsolationPatrolRules.MIN_SICK_DEAD_QTY)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_SICK_QTY_INVALID);
        }
    }

    private static void validateDesc(String text, String emptyMsg)
    {
        if (StringUtils.isEmpty(text) || text.trim().isEmpty())
        {
            throw new ServiceException(emptyMsg);
        }
        if (text.length() > IsolationPatrolRules.MAX_DESC_LEN)
        {
            throw new ServiceException(IsolationPatrolRules.MSG_DESC_TOO_LONG);
        }
    }

    private static void validatePhoto(String photoPath)
    {
        if (StringUtils.isEmpty(photoPath))
        {
            return;
        }
        if (!IsolationPatrolRules.isPhotoExtensionAllowed(photoPath))
        {
            throw new ServiceException(IsolationPatrolRules.MSG_PHOTO_EXT);
        }
    }

    private static void trimFields(BizIsolationPatrol row)
    {
        if (row.getContentDesc() != null)
        {
            row.setContentDesc(row.getContentDesc().trim());
        }
        if (row.getHandleDesc() != null)
        {
            row.setHandleDesc(row.getHandleDesc().trim());
        }
        if (row.getPenCode() != null)
        {
            row.setPenCode(row.getPenCode().trim());
        }
        if (row.getRemark() != null)
        {
            row.setRemark(row.getRemark().trim());
        }
        if (StringUtils.isEmpty(row.getPhotoUrl()))
        {
            row.setPhotoUrl(null);
        }
        if (StringUtils.isEmpty(row.getPhotoPath()))
        {
            row.setPhotoPath(null);
        }
    }
}
