package com.mvc.service.dic;

import com.mvc.dao.DicDbUnitMapper;
import com.mvc.dao.DicSequenceStationMapper;
import com.mvc.entity.DicDbUnit;
import com.mvc.entity.DicSequenceStation;
import com.mvc.entity.DicSequenceStationExample;
import com.mvc.model.StationAccModel;
import com.mvc.service.taizhang.StationAccService;
import com.mvc.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class DicSequenceStationService {
    @Resource
    private DicSequenceStationMapper dicSequenceStationMapper;

    @Resource
    private StationAccService stationAccService;

    @Resource
    private DicDbUnitMapper dicDbUnitMapper;//地标单位字典当前只在此使用,暂未创建Service

    private static List<DicDbUnit> dicDbUnits;

    private static final Integer LEN_STATION_CODE = 10;

    //private static final AtomicLong currentSequence = new AtomicLong(0);

    public List<DicSequenceStation> findAllDicSequenceStation() {
        List<DicSequenceStation> resList = findDicSequenceStationsByParentId(0);
        return resList;
    }

    /**
     * 根据parentId查询下属列表
     *
     * @param parentId
     * @return
     */
    public List<DicSequenceStation> findDicSequenceStationsByParentId(int parentId) {
        DicSequenceStationExample example = new DicSequenceStationExample();
        DicSequenceStationExample.Criteria criteria = example.createCriteria();
        return selectByExample(example);
    }

    private List<DicSequenceStation> selectByExample(DicSequenceStationExample example) {
        List<DicSequenceStation> dicSequenceStations = dicSequenceStationMapper.selectByExample(example);
        return dicSequenceStations;
    }

    public DicSequenceStation saveDicSequenceStation(DicSequenceStation model) {
        model.setUpdateTime(new Date());
        dicSequenceStationMapper.insert(model);
        return model;
    }

    public DicSequenceStation updateDicSequenceStation(DicSequenceStation model) {
        model.setUpdateTime(new Date());
        dicSequenceStationMapper.updateByPrimaryKey(model);
        return model;
    }

    public int deleteDicSequenceStation(Date serialDate) {
        int i = dicSequenceStationMapper.deleteByPrimaryKey(serialDate);
        return i;
    }

    /**
     * 获取最新一条记录
     *
     * @return
     */
    private DicSequenceStation getLatestSequenceStation(Date date) {
        DicSequenceStationExample example = new DicSequenceStationExample();
        DicSequenceStationExample.Criteria criteria = example.createCriteria();
        if (date != null) {
            criteria.andSerialDateEqualTo(date);
        } else {
            criteria.andSerialDateEqualTo(new Date());
        }

        example.setOrderByClause("SERIAL_DATE DESC");
        List<DicSequenceStation> list = selectByExample(example);

        return list.size() > 0 ? list.get(0) : null;
    }

    /**
     * 生成下一个遥测站编码
     * @return
     */
    public synchronized String generatorNextCode() {
        //下面的代码,即使站点台账没有保存,也会占用一个站码
        boolean isAvailable = false;
        if (dicDbUnits == null) {
            dicDbUnits = dicDbUnitMapper.selectByExample(null);
        }

        Date serialDate = new Date();
        String dateStr = DateUtil.formateDate(serialDate, "yyMMdd");

        //从数据库中取值
        DicSequenceStation curSequenceStation = getLatestSequenceStation(serialDate);
        long serialNumber = curSequenceStation == null ? (Long.valueOf(dateStr) * 10000 + 1) : curSequenceStation.getSerialNumber() + 1;
        long dbTemp = 100000;//当前4位与地标重叠时使用(使年份yy首位减1)

        while (!isAvailable) {
            String strValue = StringUtils.leftPad(String.valueOf(serialNumber),LEN_STATION_CODE,'0');

            //判断前4位是否与北京地标规定的单位代码重叠
            boolean hasMatch = dicDbUnits.stream().anyMatch(s -> strValue.startsWith(s.getUnitCode()));
            if (hasMatch) {
                long temp = Long.valueOf(dateStr) - dbTemp;//240425->140425;(年份首位变历史年份)
                serialDate = DateUtil.parseTimeStr(StringUtils.leftPad(String.valueOf(temp),6,'0'),"yyMMdd");
                //将序列从当前日期切换为140425
                curSequenceStation = getLatestSequenceStation(serialDate);
                dateStr = DateUtil.formateDate(serialDate, "yyMMdd");
                serialNumber = curSequenceStation == null ? (Long.valueOf(dateStr) * 10000 + 1) : curSequenceStation.getSerialNumber() + 1;
                continue;
                //有极端情况未处理,当230425时,中减过2次变公030425后,如果0304仍冲突,会有问题(地标的代码有限,产生概率较低)
            }

            //避开当前站点台账
            StationAccModel accModel = stationAccService.findStationAccByStationCode(strValue);
            if (accModel != null) {
                serialNumber++;
                continue;
            }

            isAvailable = true;
        }

        if (curSequenceStation == null) {//今日还未生成过
            curSequenceStation = new DicSequenceStation();
            curSequenceStation.setSerialDate(serialDate);
            curSequenceStation.setSerialNumber(serialNumber);
            saveDicSequenceStation(curSequenceStation);
        } else {
            curSequenceStation.setSerialNumber(serialNumber);
            updateDicSequenceStation(curSequenceStation);
        }

        return StringUtils.leftPad(String.valueOf(serialNumber),LEN_STATION_CODE,'0');
    }

    /*public synchronized String generatorNextCode() {
        boolean isAvailable = false;
        if (dicDbUnits == null) {
            dicDbUnits = dicDbUnitMapper.selectByExample(null);
        }

        //从数据库中取值
        DicSequenceStation curSequenceStation = getLatestSequenceStation();
        if (curSequenceStation != null) {
            currentSequence.set(curSequenceStation.getSerialNumber());
        } else {
            currentSequence.set(1000);//库中没有时,默认从1000开始排列
        }

        while (!isAvailable) {
            long value = currentSequence.incrementAndGet();
            String strValue = StringUtils.leftPad(String.valueOf(value), 10, '0');

            //避开北京地标规定的单位代码
            boolean hasMatch = dicDbUnits.stream().anyMatch(s -> strValue.startsWith(s.getUnitCode()));
            if (hasMatch) {
                //与地标站码重叠,加999999(循环内第一行+1,因此处+999999,不然为会0位)
                long temp = value / 1000000 * 1000000 + 1000000;//保留4位有效值 xxxx000000(为了防止库中开始就与地标冲突,且后6位不是0000001)
                currentSequence.set(temp);
                continue;
            }

            //避开当前站点台账
            StationAccModel accModel = stationAccService.findStationAccByStationCode(strValue);
            if (accModel != null) {
                continue;
            }

            isAvailable = true;
        }

        updateLastRecord(curSequenceStation, currentSequence.get());
        String resValue = String.valueOf(currentSequence.get());

        return StringUtils.leftPad(resValue, 10, '0');
    }*/
}
