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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
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.industrypolicy.support.PastureRules;
import com.ruoyi.web.modules.industryservice.domain.BizPasture;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenFarmDto;
import com.ruoyi.web.modules.industryservice.mapper.BizPastureMapper;
import com.ruoyi.web.modules.industryservice.support.PastureSyncRules;

/**
 * 单条养殖场同步事务服务。
 * <p>
 * 将 {@link OpenFarmDto} 映射为 {@link BizPasture} 并按 {@code external_id} upsert；
 * 每条记录独立事务（REQUIRES_NEW），避免批量同步中单条失败拖垮整批。
 * </p>
 */
@Service
public class PastureSyncTxService
{
    private static final SimpleDateFormat THIRD_PARTY_TIME = createThirdPartyTimeFormat();

    @Autowired
    private BizPastureMapper bizPastureMapper;

    /**
     * 持久化一条第三方养殖场记录。
     *
     * @param dto      OpenFarmVo 单条数据
     * @param syncTime 本次同步批次时间，写入 last_sync_time
     * @return true=新增，false=更新
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public boolean persistFarm(OpenFarmDto dto, Date syncTime)
    {
        if (dto == null || dto.getId() == null)
        {
            throw new ServiceException(PastureSyncRules.MSG_EXTERNAL_ID_REQUIRED);
        }
        if (StringUtils.isEmpty(dto.getFarmName()))
        {
            throw new ServiceException(PastureSyncRules.MSG_FARM_NAME_REQUIRED);
        }
        BizPasture row = new BizPasture();
        row.setExternalId(dto.getId());
        row.setPastureName(dto.getFarmName().trim());
        row.setFarmType(StringUtils.trim(dto.getFarmType()));
        row.setIntroduction(StringUtils.trim(dto.getIntroduction()));
        row.setLatitude(dto.getLatitude());
        row.setLongitude(dto.getLongitude());
        row.setDetailAddress(StringUtils.trim(dto.getAddress()));
        row.setPersonInCharge(StringUtils.trim(dto.getPerson()));
        row.setContactPhone(StringUtils.trim(dto.getContactPhone()));
        row.setCounty(StringUtils.trim(dto.getCounty()));
        row.setTown(StringUtils.trim(dto.getTown()));
        row.setFloorArea(StringUtils.trim(dto.getFloorArea()));
        row.setScaleBreeding(StringUtils.trim(dto.getScaleBreeding()));
        row.setBreedSpecies(StringUtils.trim(dto.getBreedSpecies()));
        row.setRemark(StringUtils.trim(dto.getRemarks()));
        row.setDataSource(PastureSyncRules.DATA_SOURCE_THIRD_PARTY);
        row.setLastSyncTime(syncTime);
        row.setDelFlag(PastureRules.DEL_FLAG_NORMAL);
        row.setUpdateBy("sync");

        BizPasture existing = bizPastureMapper.selectBizPastureByExternalId(dto.getId());
        Date now = syncTime != null ? syncTime : new Date();
        if (existing == null)
        {
            row.setCreateBy("sync");
            row.setCreateTime(parseThirdPartyTime(dto.getCreateTime(), now));
            bizPastureMapper.insertBizPasture(row);
            return true;
        }
        row.setId(existing.getId());
        row.setCreateTime(existing.getCreateTime());
        row.setUpdateTime(now);
        bizPastureMapper.updateBizPastureFromSync(row);
        return false;
    }

    private static Date parseThirdPartyTime(String value, Date fallback)
    {
        if (StringUtils.isEmpty(value))
        {
            return fallback;
        }
        try
        {
            synchronized (THIRD_PARTY_TIME)
            {
                return THIRD_PARTY_TIME.parse(value.trim());
            }
        }
        catch (ParseException e)
        {
            return fallback;
        }
    }

    private static SimpleDateFormat createThirdPartyTimeFormat()
    {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        df.setLenient(false);
        return df;
    }
}
