package com.ruoyi.web.modules.video.service;

import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.domain.BizPasture;
import com.ruoyi.web.modules.industryservice.mapper.BizPastureMapper;
import com.ruoyi.web.modules.video.domain.BizLivestockMonitor;
import com.ruoyi.web.modules.video.domain.dto.OpenCameraDto;
import com.ruoyi.web.modules.video.mapper.BizLivestockMonitorMapper;
import com.ruoyi.web.modules.video.support.LivestockMonitorRules;
import com.ruoyi.web.modules.video.support.LivestockMonitorSyncRules;

/**
 * 单条监控点位同步事务服务。
 * <p>
 * 开放接口 → 本地字段映射：
 * <ul>
 *   <li>{@code cameraId} → {@code monitor_id}</li>
 *   <li>{@code deviceName} → {@code monitor_name}（空则「监控+id」，超长截断至 10 字）</li>
 *   <li>{@code farmName} → 按名称查 {@code biz_pasture}，匹配则 {@code owner_type=1}、{@code owner_id}、{@code owner_name}</li>
 *   <li>{@code enclosureName} → {@code enclosure_name}</li>
 *   <li>{@code videoSource} → {@code video_source}（小写校验 wvp/ys7/url）</li>
 * </ul>
 * 更新时保留本地 {@code install_location}；主体信息随第三方 {@code farmName} 重新解析。
 * 每条记录 {@code REQUIRES_NEW} 独立事务，单条失败不影响其它行。
 * </p>
 */
@Service
public class LivestockMonitorSyncTxService
{
    @Autowired
    private BizLivestockMonitorMapper bizLivestockMonitorMapper;

    @Autowired
    private BizPastureMapper bizPastureMapper;

    /**
     * 持久化一条第三方监控记录。
     *
     * @param dto      开放接口单条摄像头数据
     * @param syncTime 本次同步批次时间
     * @param operator 当前操作人（写入 create_by / update_by）
     * @return true=新增，false=更新
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public boolean persistCamera(OpenCameraDto dto, Date syncTime, String operator)
    {
        String syncBy = StringUtils.isNotEmpty(operator) ? operator.trim() : "";
        if (dto == null || dto.getCameraId() == null)
        {
            throw new ServiceException(LivestockMonitorSyncRules.MSG_CAMERA_ID_REQUIRED);
        }
        String monitorId = String.valueOf(dto.getCameraId());
        if (monitorId.length() > 32)
        {
            throw new ServiceException("摄像头ID不能超过32个字符");
        }
        String videoSource = normalizeVideoSource(dto.getVideoSource());
        BizLivestockMonitor row = new BizLivestockMonitor();
        row.setMonitorId(monitorId);
        row.setMonitorName(resolveMonitorName(dto.getDeviceName(), monitorId));
        row.setEnclosureName(trimToNull(dto.getEnclosureName(), 64));
        row.setVideoSource(videoSource);
        applyOwnerFromFarmName(row, dto.getFarmName());
        row.setDelFlag(LivestockMonitorRules.DEL_FLAG_NORMAL);
        row.setUpdateBy(syncBy);

        BizLivestockMonitor existing = bizLivestockMonitorMapper.selectBizLivestockMonitorByMonitorId(monitorId);
        Date now = syncTime != null ? syncTime : new Date();
        if (existing == null)
        {
            row.setCreateBy(syncBy);
            row.setCreateTime(now);
            bizLivestockMonitorMapper.insertBizLivestockMonitor(row);
            return true;
        }
        row.setId(existing.getId());
        // 更新时保留安装位置；主体随 farmName 重新匹配牧场
        row.setInstallLocation(existing.getInstallLocation());
        row.setCreateTime(existing.getCreateTime());
        row.setCreateBy(existing.getCreateBy());
        row.setUpdateTime(now);
        bizLivestockMonitorMapper.updateBizLivestockMonitorFromSync(row);
        return false;
    }

    /** 第三方 videoSource 转小写并校验 wvp/ys7/url */
    private static String normalizeVideoSource(String videoSource)
    {
        String source = StringUtils.trim(videoSource);
        if (StringUtils.isEmpty(source))
        {
            throw new ServiceException(LivestockMonitorSyncRules.MSG_VIDEO_SOURCE_REQUIRED);
        }
        source = source.toLowerCase();
        if (!LivestockMonitorRules.isVideoSourceValid(source))
        {
            throw new ServiceException(LivestockMonitorSyncRules.MSG_VIDEO_SOURCE_INVALID);
        }
        return source;
    }

    /** 监控名称须 1～10 字；第三方 deviceName 超长时截断 */
    private static String resolveMonitorName(String deviceName, String monitorId)
    {
        String name = StringUtils.trim(deviceName);
        if (StringUtils.isEmpty(name))
        {
            name = "监控" + monitorId;
        }
        if (name.length() > 10)
        {
            return name.substring(0, 10);
        }
        return name;
    }

    /**
     * 按第三方 farmName 精确匹配 {@code biz_pasture.pasture_name}，命中则绑定养殖主体。
     */
    private void applyOwnerFromFarmName(BizLivestockMonitor row, String farmName)
    {
        String name = StringUtils.trim(farmName);
        if (StringUtils.isEmpty(name))
        {
            row.setOwnerType(null);
            row.setOwnerId(null);
            row.setOwnerName(null);
            return;
        }
        if (name.length() > 64)
        {
            name = name.substring(0, 64);
        }
        BizPasture pasture = bizPastureMapper.selectBizPastureByExactName(name);
        if (pasture != null)
        {
            row.setOwnerType(LivestockMonitorRules.OWNER_TYPE_PASTURE);
            row.setOwnerId(pasture.getId());
            row.setOwnerName(pasture.getPastureName());
            return;
        }
        row.setOwnerType(null);
        row.setOwnerId(null);
        row.setOwnerName(name);
    }

    private static String trimToNull(String value, int maxLen)
    {
        String text = StringUtils.trim(value);
        if (StringUtils.isEmpty(text))
        {
            return null;
        }
        if (text.length() > maxLen)
        {
            return text.substring(0, maxLen);
        }
        return text;
    }
}
