package cn.com.countrygarden.bi.main.service.resident.impl;

import cn.com.countrygarden.bi.main.dao.resident.ContractHistoryMapper;
import cn.com.countrygarden.bi.main.dao.resident.ResidentContractMapper;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbHsprCommunityMapper;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.resident.*;
import cn.com.countrygarden.bi.main.model.twerp.ErpCommunity;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.resident.ResidentContractService;
import cn.com.countrygarden.bi.main.service.resident.ResidentPaymentService;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbSysUserService;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageRowBounds;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Condition;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Created by chenweijiang on 2017/11/13.
 */
@Service
@Transactional(readOnly = true)
public class ResidentContractServiceImpl implements ResidentContractService {

    @Autowired
    private ResidentContractMapper mapper;

    @Autowired
    private TbHsprCommunityMapper tbHsprCommunityMapper;

    @Autowired
    private ContractHistoryMapper historyMapper;

    @Autowired
    private ResidentPaymentService paymentService;

    @Autowired
    private TbSysUserService tbSysUserService;

    @Override
    public PageData listContract(String userCode, ResidentContract query, int page, int size) {
        HashMap<String, Object> paramters = new HashMap<String, Object>();
        if (!StringUtils.isEmpty(query.getCommId())) {
            paramters.put("commId", query.getCommId());
        }
        if (!StringUtils.isEmpty(query.getOrganId())) {
            paramters.put("organId", query.getOrganId());
        }
        if (query.getStartDate() != null) {
            paramters.put("startTime", query.getStartDate());
        }
        if (query.getEndDate() != null) {
            paramters.put("endTime", query.getEndDate());
        }
        if (!StringUtils.isEmpty(query.getContractCode())) {
            paramters.put("contractCode", query.getContractCode());
        }
        if (!StringUtils.isEmpty(query.getStatus())) {
            paramters.put("contractStatus", query.getStatus());
        }

        if (StringUtils.isEmpty(query.getCommId())) {
            List<ErpCommunity> organBase = tbHsprCommunityMapper.findOrganBaseByUserCode(userCode, query.getOrganId());
            List<ErpCommunity> commBase = tbHsprCommunityMapper.findCommBaseByUserCode(userCode, query.getOrganId());

            List<String> organCodes = new ArrayList<String>();
            List<String> commIds = new ArrayList<String>();
            for (ErpCommunity community : organBase) {
                organCodes.add(community.getOrganCode());
            }
            for (ErpCommunity community : commBase) {
                commIds.add(community.getCommId());
            }
            if (organCodes.size() > 0) {
                paramters.put("organCodes", organCodes);
            }
            if (commIds.size() > 0) {
                paramters.put("commIds", commIds);
            }
            if (organCodes.size() == 0 && commIds.size() == 0) {
                List<ResidentContract> emptyList = new ArrayList<ResidentContract>();
                PageRowBounds pageRowBounds = new PageRowBounds(page, size);
                pageRowBounds.setTotal(0l);
                PageData pageData = new PageData(emptyList, pageRowBounds);
                return pageData;
            }
        }
        PageRowBounds pageRowBounds = new PageRowBounds(page, size);
        List<ResidentContract> contracts = mapper.findBy(paramters, pageRowBounds);
        for (ResidentContract contract : contracts) {
            String statusName = ContractConstant.ContractStatus.nameMap.get(contract.getStatus());
            contract.setStatus(statusName);

            String createBy = contract.getCreatedBy();
            String updateBy = contract.getModifiedBy();
            try {
                TbSysUser createUser = tbSysUserService.findByUserCode(createBy);
                contract.setCreatedBy(createUser.getUserName());

                TbSysUser upateUser = tbSysUserService.findByUserCode(updateBy);
                contract.setModifiedBy(upateUser.getUserName());
            } catch (Exception e) {

            }

            ResidentPaymentAggregate aggregate = paymentService.aggregate(contract.getId());
            if (aggregate != null) {
                contract.setPayments(aggregate.getPayments());
                contract.setPaidPayments(aggregate.getPaidPayments());
            }
        }
        PageData result = new PageData(contracts, pageRowBounds);
        return result;
    }

    @Transactional(readOnly = false)
    public void createContract(ResidentContract contract, String userCode) {
        ResidentContract query = new ResidentContract();
        query.setContractCode(contract.getContractCode());
        List<ResidentContract> duplicateList = mapper.select(query);
        if (duplicateList.size() > 0) {
            throw new ServiceException(String.format("合同编号'%s'重复,请重新编写合同编号", contract.getContractCode()));
        }
        if (StringUtils.isEmpty(contract.getFloatAmount())) {
            contract.setFloatAmount(ContractConstant.EMPTY_FLOAT_AMOUNT);
        }
        contract.setStatus(ContractConstant.ContractStatus.NORMAL);
        contract.setGmtCreate(new Date());
        contract.setGmtModified(new Date());
        contract.setCreatedBy(userCode);
        contract.setModifiedBy(userCode);
        int id = mapper.insert(contract);

        String json = JSON.toJSONString(contract);
        ContractHistory history = new ContractHistory();
        history.setContent(json);
        history.setContractId(id);
        history.setCreatedBy(userCode);
        history.setGmtCreate(new Date());
        historyMapper.insert(history);
        paymentService.createPaymentBatch(contract);
    }

    @Transactional(readOnly = false)
    public void updateContract(ResidentContract contract, String userCode) {
        Condition condition = new Condition(ResidentContract.class);
        condition.createCriteria().andEqualTo("contractCode", contract.getContractCode())
                .andNotEqualTo("id", contract.getId());
        List<ResidentContract> duplicateList = mapper.selectByCondition(condition);
        if (duplicateList.size() > 0) {
            throw new ServiceException(String.format("合同编号'%s'重复,请重新编写合同编号", contract.getContractCode()));
        }

        int payments = paymentService.findPaidPayment(contract.getId());
        if (payments > 0) {
            throw new ServiceException("协议已收费不能进行修改，请作废重新建立");
        }
        if (StringUtils.isEmpty(contract.getFloatAmount())) {
            contract.setFloatAmount(ContractConstant.EMPTY_FLOAT_AMOUNT);
        }
        ResidentContract entity = mapper.selectByPrimaryKey(contract.getId());
        contract.setGmtCreate(entity.getGmtCreate());
        contract.setCreatedBy(entity.getCreatedBy());
        contract.setStatus(ContractConstant.ContractStatus.NORMAL);
        contract.setGmtModified(new Date());
        contract.setModifiedBy(userCode);

        Condition updateCondiction = new Condition(ResidentContract.class);
        updateCondiction.createCriteria().andEqualTo("id", entity.getId())
                .andEqualTo("gmtModified", entity.getGmtModified());
        int updateNumber = mapper.updateByCondition(contract, updateCondiction);
        if (updateNumber == 0) {
            throw new ServiceException("更新失败请更新再试");
        }

        String json = JSON.toJSONString(contract);
        ContractHistory history = new ContractHistory();
        history.setContent(json);
        history.setContractId(contract.getId());
        history.setCreatedBy(userCode);
        history.setGmtCreate(new Date());
        historyMapper.insert(history);
        paymentService.reCreatePayment(contract);
    }

    @Override
    @Transactional(readOnly = false)
    public void expired(Integer contractId, String userCode) {
        Condition condition = new Condition(ResidentContract.class);

        ResidentContract contract = mapper.selectByPrimaryKey(contractId);
        condition.createCriteria().andEqualTo("id", contractId)
                .andEqualTo("gmtModified", contract.getGmtModified());
        contract.setStatus(ContractConstant.ContractStatus.EXPIRED);
        contract.setModifiedBy(userCode);
        contract.setGmtModified(new Date());
        int count = mapper.updateByCondition(contract, condition);
        if (count == 0) {
            throw new ServiceException("更新失败请更试");
        }
        String json = JSON.toJSONString(contract);
        ContractHistory history = new ContractHistory();
        history.setContent(json);
        history.setContractId(contract.getId());
        history.setCreatedBy(userCode);
        history.setGmtCreate(new Date());
        historyMapper.insert(history);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateStatus(Integer contractId, String userCode, String status) {
        if (!ContractConstant.ContractStatus.nameMap.containsKey(status)) {
            throw new ServiceException("未知的状态");
        }

        Condition condition = new Condition(ResidentContract.class);

        ResidentContract contract = mapper.selectByPrimaryKey(contractId);
        if (contract == null) {
            throw new ServiceException("未知的协议");
        }

        if (status.equals(contract.getStatus())) {
            return;
        }

        condition.createCriteria().andEqualTo("id", contractId);
        contract.setStatus(status);
        contract.setModifiedBy(userCode);
        contract.setGmtModified(new Date());
        int count = mapper.updateByCondition(contract, condition);
        if (count == 0) {
            throw new ServiceException("更新失败请更试");
        }
        String json = JSON.toJSONString(contract);
        ContractHistory history = new ContractHistory();
        history.setContent(json);
        history.setContractId(contract.getId());
        history.setCreatedBy(userCode);
        history.setGmtCreate(new Date());
        historyMapper.insert(history);
    }

    @Override
    @Transactional(readOnly = false)
    public List<ResidentContractParty> exportPartyB() {
        return mapper.exportPartyB();
    }
}
