package com.yonge.cooleshow.biz.dal.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.yonge.toolset.mybatis.service.impl.BaseServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yonge.cooleshow.biz.dal.dao.ContractTemplateDao;
import com.yonge.cooleshow.biz.dal.dto.ContractTemplateDto;
import com.yonge.cooleshow.biz.dal.entity.ContractTemplate;
import com.yonge.cooleshow.biz.dal.service.ContractTemplateService;
import com.yonge.toolset.mybatis.dal.BaseDAO;
import com.yonge.cooleshow.common.exception.BizException;
import com.yonge.toolset.mybatis.page.PageInfo;
import com.yonge.toolset.mybatis.page.QueryInfo;
import com.yonge.toolset.utils.collection.MapUtil;

@Service
public class ContractTemplateServiceImpl extends BaseServiceImpl<Integer, ContractTemplate> implements ContractTemplateService {

	@Autowired
	private ContractTemplateDao contractTemplateDao;

	@Autowired
	private RedissonClient redissonClient;

	private final static String LOCK_NAME = "contract_template";

	@Override
	public BaseDAO<Integer, ContractTemplate> getDAO() {
		return contractTemplateDao;
	}

	@Override
	public PageInfo<ContractTemplateDto> queryPageList(QueryInfo queryInfo) {
		PageInfo<ContractTemplateDto> pageInfo = new PageInfo<ContractTemplateDto>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<String, Object>();
		MapUtil.populateMap(params, queryInfo);

		List<ContractTemplateDto> dataList = null;
		int count = this.findCount(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = contractTemplateDao.queryPageList(params);
		}
		if (count == 0) {
			dataList = new ArrayList<ContractTemplateDto>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	@Transactional
	public boolean enableContract(Integer id, Long userId) {
		ContractTemplate contractTemplate = contractTemplateDao.get(id);

		if (contractTemplate == null) {
			throw new BizException("未查询到协议模板");
		}

		if (contractTemplate.getStatus()) {
			return true;
		}

		RLock lock = redissonClient.getLock(LOCK_NAME);

		try {
			if (lock.tryLock(10, 10, TimeUnit.SECONDS)) {

				Integer maxVersion = contractTemplateDao.queryMaxVersion();
				int version = maxVersion == null ? 1 : maxVersion + 1;

				contractTemplate.setVersion(version);

				contractTemplateDao.disableContract(contractTemplate.getOwner(), contractTemplate.getType());

				Date date = new Date();

				contractTemplate.setStatus(true);
				contractTemplate.setUpdateTime(date);
				contractTemplate.setModifyBy(userId);

				contractTemplateDao.update(contractTemplate);

				return true;
			}
		} catch (InterruptedException e) {
			throw new BizException("锁获取失败:{}", e.getMessage());
		} finally {
			lock.unlock();
		}

		return false;
	}

	@Override
	public boolean updateContractVersion() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public ContractTemplate queryLatestContractTemplate(String owner, String type) {
		ContractTemplate ContractTemplate = contractTemplateDao.queryLatestContractTemplate(owner, type);

		return ContractTemplate;
	}

	@Override
	@Transactional
	public boolean createContractTemplate(ContractTemplate ContractTemplate) {

		RLock lock = redissonClient.getLock(LOCK_NAME);

		try {
			if (lock.tryLock(10, 10, TimeUnit.SECONDS)) {

				Integer maxVersion = contractTemplateDao.queryMaxVersion();
				int version = maxVersion == null ? 1 : maxVersion + 1;

				ContractTemplate.setVersion(version);
				Date date = new Date();
				ContractTemplate.setCreateTime(date);
				ContractTemplate.setUpdateTime(date);
				insert(ContractTemplate);

				return true;
			}
		} catch (InterruptedException e) {
			throw new BizException("锁获取失败:{}", e.getMessage());
		} finally {
			lock.unlock();
		}

		return false;
	}

	@Override
	@Transactional
	public boolean updateContractTempalte(ContractTemplate ContractTemplate) {

		RLock lock = redissonClient.getLock(LOCK_NAME);

		try {
			if (lock.tryLock(10, 10, TimeUnit.SECONDS)) {
				Integer maxVersion = contractTemplateDao.queryMaxVersion();
				int version = maxVersion == null ? 1 : maxVersion + 1;

				ContractTemplate.setVersion(version);
				Date date = new Date();
				ContractTemplate.setUpdateTime(date);

				update(ContractTemplate);
				return true;
			}
		} catch (InterruptedException e) {
			throw new BizException("锁获取失败:{}", e.getMessage());
		} finally {
			lock.unlock();
		}

		return false;
	}

}