package common.service.impl;

import adi.dic.PackageEnum;
import adi.model.ADIUser;
import adi.service.ADIAccountService;
import common.model.*;
import common.repository.*;
import common.service.ContractService;
import common.service.UserService;
import dic.ContractStatusEnum;
import dic.ContractTypeEnum;
import dic.RoleEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tkio.model.Account;
import tkio.model.IncrementFlow;
import tkio.model.PackageType;
import tkio.repository.AccountRepository;
import tkio.repository.IncrementFlowRepository;
import tkio.repository.PackageTypeRepository;
import tkio.service.AccountService;
import tkio.service.TkioAccountService;
import userio.service.AccountIOService;
import userio.service.IOAccountService;
import util.*;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * Created by mxq on 2018/1/16.
 */
@Service
public class ContractServiceImpl implements ContractService {


    private static final Map<String, String> CONTRACT_TYPE = new HashMap() {{
        put("0", "首次签约");
        put("1", "续约");
        put("2", "合同变更");

    }};

    @Autowired
    ContractRepository contractRepository;
    @Autowired
    ContractBodyRepository contractBodyRepository;
    @Autowired
    Account4WebRepository account4WebRepository;
    @Autowired
    PackageTypeRepository packageTypeRepository;
    @Autowired
    PriceLevelMoneyRepository priceLevelMoneyRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    ContractChangeRepository contractChangeRepository;
    @Autowired
    ContractMoneyRepository contractMoneyRepository;
    @Autowired
    AccountService accountService;
    @Autowired
    AccountIOService accountIOService;
    @Autowired
    IOAccount4WebRepository ioAccount4WebRepository;
    @Autowired
    ContractIncrementRepository contractIncrementRepository;
    @Autowired
    TkioAccountService tkioAccountService;
    @Autowired
    IOAccountService ioAccountService;
    @Autowired
    AccountRepository accountRepository;
    @Autowired
    UserService userService;
    @Autowired
    IncrementFlowRepository incrementFlowRepository;
    @Autowired
    BPUContractRepository bpuContractRepository;
    @Autowired
    ADIAccountService adiAccountService;

    @Autowired
    TradeTypeRepsitory tradeTypeRepsitory;

    @Autowired
    ContractRelationRepository contractRelationRepository;


    @Override
    public Map<String, Object> checkAccount(String email, String platfrom) {
        Map<String, Object> map = new HashMap<>();
        Account4Web account4Web = null;
        IOAccount4Web ioAccount4Web = null;
        ADIUser adiUser = null;
        platfrom = "tkio";

        if ("tkio".equals(platfrom)) {
            account4Web = account4WebRepository.findByEmail(email);
        } else if ("io".equals(platfrom)) {
            ioAccount4Web = ioAccount4WebRepository.findByEmail(email);
        } else if ("adi".equals(platfrom)) {
            adiUser = adiAccountService.findOne(email);
        }
        if (null == account4Web && null == ioAccount4Web && null == adiUser) {
            map.put("result", 0);
        } else {
            BigInteger integer = contractRepository.countNumByEmail(email, platfrom);
            map.put("result", 1);
            if (platfrom.equals("adi")) {
                map.put("company", adiUser.getCompany());
            } else {
                map.put("company", null == account4Web ? ioAccount4Web.getCompany() : account4Web.getCompany());
            }

            map.put("num", integer.intValue());
            Contract contract = contractRepository.findByPlatformAndEmailLimitVaild(platfrom, email);
            if (null == contract) {
                map.put("status", false);
            } else {
                map.put("status", true);
            }
        }

        return map;
    }

    @Override
    public Boolean checkTime(String email, String platfrom, String type, String product) {
        Boolean flag = false;
        if (ContractTypeEnum.MAIN.getKey().equals(type)) {
            Contract contract = contractRepository.findByPlatformAndEmailLimit1(platfrom, email, type);
            if (null == contract) {
                flag = true;
            } else {
                String beforeDay = DateUtil.getBeforeDays(180);
                if (beforeDay.compareTo(contract.getEndDate()) > 0) {
                    flag = true;
                }
            }
        } else {
            ContractIncrement increment = contractIncrementRepository.findByCode(product);
            Contract contract = contractRepository.findByPlatformAndEmailAndPricelevelLimit1(platfrom, email, type, increment.getId());
            if (null == contract) {
                flag = true;
            } else {
                String beforeDay = DateUtil.getBeforeDays(180);
                String endDate = contract.getEndDate() == null ? contract.getDs() : contract.getEndDate();
                if (beforeDay.compareTo(endDate) > 0) {
                    flag = true;
                }
            }
        }
        return flag;
    }

    @Override
    public List<ContractBody> findBody() {
        return contractBodyRepository.findAll();
    }

    @Override
    public String getContractCode(String code) {
        BigInteger integer = contractRepository.countNumByDs(DateUtil.getBeforeDays(0));
        String lastCode = "";
        if (integer.intValue() < 9) {
            lastCode = "0" + (integer.intValue() + 1);
        } else {
            lastCode = "" + (integer.intValue() + 1);
        }
        String re = code + "-" + DateUtil.getDays2(0) + lastCode;
        return re;
    }

    @Override
    public String getContractCode(String code, String platform, String company) {

        BigInteger countContract = contractRepository.findcountContract(code);

        String lastCode;

        if("fake".equals(platform)){
            platform = "FZBWS";
        }

        int codeInt = countContract.intValue();

        if (codeInt < 9) {
            lastCode = "0" + (codeInt + 1);
        } else {
            lastCode = "" + (codeInt + 1);
        }
        return  code + "-" + platform.toUpperCase() + "-" + DateUtil.getDays2(0) + "-" + lastCode;
    }

    @Override
    public List findSetmeal(String platform) {

        platform = "tkio";

        List list = new ArrayList();
        if ("adi".equals(platform)) {
            for (int i = 1; i < 3; i++) {
                Map<String, String> packageMap = new HashMap<>();
                packageMap.put("id", i + "");
                if (i == 1) {
                    packageMap.put("packageName", PackageEnum.PROBATION.getValue());
                } else {
                    packageMap.put("packageName", PackageEnum.FORMAL.getValue());
                }
                list.add(packageMap);
            }
        } else {
            if ("tkio".equals(platform) || "io".equals(platform)) {
//            List<PackageType> packageTypeList = packageTypeRepository.findAll();
                List<PackageType> packageTypeList = packageTypeRepository.findIsNewAll();
                for (PackageType p : packageTypeList) {
                    p.setType("main");
                    list.add(p);
                }
                // 增值套餐
//                List<ContractIncrement> increments = contractIncrementRepository.findAll();
//                list.addAll(increments);
            } else if ("userdesk".equals(platform) || "dmp".equals(platform) || "fake".equals(platform)) {
                list = bpuContractRepository.findByProduct(platform);
            }
        }

        return list;
    }

    @Override
    public List<ContractIncrement> findIncrement() {
        return null;
    }

    @Override
    public Double getRebat(String product, Integer level, Long money) {
        Double rebat = 1d;
        try {
            PriceLevelMoney levelMoney = priceLevelMoneyRepository.getOne(product, level);
            rebat = money * 1.0 / levelMoney.getMoney();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rebat;
    }

    @Override
    public List<User> getSales() {
        return userRepository.findSales();
    }

    @Override
    public Contract build(Contract contract) {
        User user = userRepository.findByEmail(contract.getSaleName());
        if (null != user) {
            contract.setSale(user.getId());
        }
        contract.setVirtual(true);
        Account account = accountRepository.findByEmail(contract.getEmail());
        contract.setCustomerBody(account.getCompany());
        contract.setType("increment");
        contract.setPlatform("tkio");
        contract.setStartDate(DateUtil.getBeforeDays(0));
        ContractIncrement contractIncrement = contractIncrementRepository.findByCode(contract.getPriceLevelName());
        contract.setPriceLevel(contractIncrement.getId());
        Contract contract1 = create(null, contract);
        return contract1;
    }

    @Override
    public Contract create(User loginUser, Contract resource) {

        if (resource == null) {
            return null;
        }

        Contract contractExist = contractRepository.findByCodePlatform(resource.getContractCode(), resource.getPlatform());

        if (contractExist != null) {
            // 合同编号已存在
            return null;
        }


        resource.setPayMoney(0L);
        resource.setInvoice(0L);
        Long extraFlow = resource.getExtraFlow();
        if(extraFlow==null){
            extraFlow = 0L;
        }

        resource.setDs(DateUtil.getBeforeDays(0));

//        if (resource.getType().equals("main")) {
//            if (resource.getPlatform().equals("tkio")) {
//                if (!(extraFlow.longValue() == 0)) {
//                    if (resource.getPlatform().equals("tkio")) {
//                        IncrementFlow flow = new IncrementFlow();
//                        Account account = accountRepository.findByEmail(resource.getEmail());
//                        flow.setAccount(account.getId());
//                        flow.setFlow(extraFlow);
//                        flow.setEndDate(resource.getEndDate());
//                        flow.setStartDate(resource.getStartDate());
//                        flow.setContractCode(resource.getContractCode());
//                        incrementFlowRepository.save(flow);
//                    }
//                }
//            }
//        }

        this.dealContractStatus(resource);

        if (resource.getRelationContract() == null) {
            resource.setRelationContract(-1L);
        }

        if (null != loginUser) {
            resource.setCreateAccount(loginUser.getId());
            resource.setCreateName(loginUser.getName());
        }




        resource.setCreateTime(new Date());

        //同步修改trackingio的数据
//        if (resource.getPlatform().equals("tkio") && resource.getType().equals("main")) {
//            accountService.update(resource);
//        }
//        if (resource.getPlatform().equals("io") && resource.getType().equals("main")) {
//            accountIOService.update(resource);
//        }
//        if (resource.getPlatform().equals("adi")) {
//            adiAccountService.updateAccount(resource);
//        }

        resource = contractRepository.save(resource);

        this.saveContractRelations(resource,resource.getId());

        return resource;
    }


    private void saveContractRelations(Contract resource,Long contractId){
        if (resource.getRelationContract() != null && resource.getRelationContract() > 0) {
            //保存关联合同信息
            ContractRelation relation = new ContractRelation();
            relation.setCreateTime(new Date());
            relation.setMainContract(contractId);
            relation.setRelationId(resource.getRelationContract());
            relation.setPlatform(resource.getPlatform());

            ContractRelation relationOrig =  contractRelationRepository.findByRelationData(relation.getMainContract(),relation.getRelationId(),resource.getPlatform());
            if(relationOrig==null){
                contractRelationRepository.save(relation);
            }

            //处理被关联 合同
            Contract contract = contractRepository.findOne(resource.getRelationContract());
            if (contract.getRelationContract() == null || contract.getRelationContract() == -1) {
                contract.setRelationContract(contractId);
                contractRepository.save(contract);
            }

//            ContractRelation relationOrigNext = contractRelationRepository.findByRelationData(relation.getRelationId(), relation.getMainContract(), resource.getPlatform());
//
//            if (relationOrigNext == null) {
//                // 主动关联
//                ContractRelation relation2 = new ContractRelation();
//                relation2.setCreateTime(new Date());
//                relation2.setMainContract(resource.getRelationContract());
//                relation2.setRelationId(contractId);
//                relation2.setPlatform(resource.getPlatform());
//                contractRelationRepository.save(relation2);
//            }

        }
    }


    public Contract create_bak(User loginUser, Contract resource) {

        if (resource == null) {
            return null;
        }

        Contract contractExist = contractRepository.findByCodePlatform(resource.getContractCode(), resource.getPlatform());

        if (contractExist != null) {
            // 合同编号已存在
            return null;
        }

        // 老的逻辑
        String contractCode = getContractCode(resource.getMyBodyCode());

        if (!contractCode.equals(resource.getContractCode())) {
            resource.setContractCode(contractCode);
        }

        resource.setPayMoney(0L);
        resource.setInvoice(0L);
        Long extraFlow = resource.getExtraFlow();
        resource.setDs(DateUtil.getBeforeDays(0));

        if (resource.getType().equals("main")) {
            if (resource.getPlatform().equals("tkio")) {
                if (!(extraFlow.longValue() == 0)) {
                    if (resource.getPlatform().equals("tkio")) {
                        IncrementFlow flow = new IncrementFlow();
                        Account account = accountRepository.findByEmail(resource.getEmail());
                        flow.setAccount(account.getId());
                        flow.setFlow(extraFlow);
                        flow.setEndDate(resource.getEndDate());
                        flow.setStartDate(resource.getStartDate());
                        flow.setContractCode(resource.getContractCode());
                        incrementFlowRepository.save(flow);
                    }
                }
            }
            if (DateUtil.getBeforeDays(0).compareTo(resource.getStartDate()) < 0) {
                resource.setDs(DateUtil.getBeforeDays(0));
                resource.setStatus("wait");
            } else {
                resource.setDs(DateUtil.getBeforeDays(0));
                resource.setStatus("executing");
            }
        } else {
//            resource.setDs(DateUtil.getBeforeDays(0));
//            resource.setStatus("wait");
        }

//        if (resource.getRebateMoney() != null) {
//            if (resource.getMoney() == null) {
//                resource.setMoney(0L);
//            }
//
//            if (resource.getRebateMoney().compareTo(BigDecimal.ZERO) < 0) {
//                //未回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
//
//            }else if(resource.getRebateMoney().compareTo(new BigDecimal(resource.getMoney()+""))< 0){
//                // 部分回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_PART.getKey());
//            }else{
//                // 已回款
//                resource.setStatus(ContractStatusEnum.MONEY_BACK_ALL.getKey());
//            }
//
//        } else {
//            //未回款
//            resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
//        }

        Double rebat = null;
        if (null != resource.getPriceLevel()) {
            rebat = getRebat(resource.getProduct(), resource.getPriceLevel().intValue(), resource.getMoney());
        } else {
            rebat = getRebat(resource.getProduct(), 0, resource.getMoney());
        }

        BigDecimal bg = new BigDecimal(rebat);
        double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        resource.setRebate(f1);

        if (null != loginUser) {
            resource.setCreateAccount(loginUser.getId());
            resource.setCreateName(loginUser.getName());
        }
        resource.setCreateTime(new Date());

        //同步修改trackingio的数据
        if (resource.getPlatform().equals("tkio") && resource.getType().equals("main")) {
            accountService.update(resource);
        }
        if (resource.getPlatform().equals("io") && resource.getType().equals("main")) {
            accountIOService.update(resource);
        }
        if (resource.getPlatform().equals("adi")) {
            adiAccountService.updateAccount(resource);
        }

        if (resource.getType().equals(ContractTypeEnum.MAIN.getKey())
                || (resource.getType().equals(ContractTypeEnum.INCREMENT.getKey()) && resource.getPriceLevel().equals(1L))) {
            List<Contract> contractList = contractRepository.findByPlatformAndEmail(resource.getPlatform(), resource.getEmail(), resource.getType());
            if (ValidateUtil.isValid(contractList)) {
                List<Contract> list = new ArrayList<>();
                for (Contract contract : contractList) {
                    if (contract.getType().equals(ContractTypeEnum.MAIN.getKey())
                            || (contract.getType().equals(ContractTypeEnum.INCREMENT.getKey()) && contract.getPriceLevel().equals(1L))) {

                        if (contract.getStatus().equals(ContractStatusEnum.EXECUTING.getKey())
                                || contract.getStatus().equals(ContractStatusEnum.WAIT.getKey())) {
                            contract.setStatus(ContractStatusEnum.CANCEL.getKey());
                        }
                        list.add(contract);
                    }

                }
                contractRepository.save(contractList);
            }
        }

        resource = contractRepository.save(resource);


        if (resource.getRelationContract() != null && resource.getRelationContract() > 0) {
            //保存关联合同信息
            ContractRelation relation = new ContractRelation();
            relation.setCreateTime(new Date());
            relation.setMainContract(resource.getId());
            relation.setRelationId(resource.getRelationContract());
            relation.setPlatform(resource.getPlatform());
            contractRelationRepository.save(relation);

        }

        return resource;
    }

    @Override
    public Contract update(User loginUser, Contract resource) {
        Map<Long, String> packageMap = getPackageMap();
        Map<Long, String> saleMap = getSaleMap();
        Contract contract = contractRepository.findOne(resource.getId());

        ContractChange cc = new ContractChange();
        cc.setType("update");
        cc.setUser(loginUser.getId());
        cc.setDs(DateUtil.getBeforeDays(0));
        cc.setContent("");
        cc.setEmail(contract.getEmail());
        cc.setCompany(contract.getCustomerBody());
        cc.setContractCode(contract.getContractCode());



        this.dealContractStatus(resource);


        if (!resource.getStartDate().equals(contract.getStartDate())) {
            cc.setContent(cc.getContent() + "开始时间变更 : " + contract.getStartDate() + "-->" + resource.getStartDate());
            contract.setStartDate(resource.getStartDate());
//            if(DateUtil.getBeforeDays(0).compareTo(resource.getStartDate()) < 0){
//                contract.setStatus("wait");
//            }else{
//                contract.setStatus("executing");
//            }
        }
        if (!resource.getEndDate().equals(contract.getEndDate())) {
            cc.setContent(cc.getContent() + "   结束时间变更 : " + contract.getEndDate() + "-->" + resource.getEndDate());
            contract.setEndDate(resource.getEndDate());
        }

        boolean newRebat = false;
        if (contract.getType().equals(ContractTypeEnum.MAIN.getKey()) && null != resource.getPriceLevel()) {
            if (!resource.getPriceLevel().equals(contract.getPriceLevel())) {
                cc.setContent(cc.getContent() + "  套餐变更:" + packageMap.get(contract.getPriceLevel()) + "-->" + packageMap.get(resource.getPriceLevel()));
                newRebat = true;
                contract.setPriceLevel(resource.getPriceLevel());
            }
        }

        if (!resource.getMoney().equals(contract.getMoney())) {
            cc.setContent(cc.getContent() + "   金额变更: " + contract.getMoney() + "-->" + resource.getMoney());
            newRebat = true;
            contract.setMoney(resource.getMoney());
        }

        if (!resource.getRebateMoney().equals(contract.getRebateMoney())) {
            cc.setContent(cc.getContent() + "  回款金额变更: " + contract.getMoney() + "-->" + resource.getMoney());
            newRebat = true;
            contract.setMoney(resource.getMoney());
        }

        if (!resource.getSale().equals(contract.getSale())) {
            cc.setContent(cc.getContent() + "销售变更:" + saleMap.get(contract.getSale()) + "-->" + saleMap.get(resource.getSale()));
            contract.setSale(resource.getSale());
        }

//        if (newRebat && !"adi".equals(contract.getPlatform())) {
//            Double rebat = getRebat(contract.getProduct(), contract.getPriceLevel().intValue(), contract.getMoney());
//            BigDecimal bg = new BigDecimal(rebat);
//            double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
////            contract.setRebate(f1);
//        }

        if (!resource.getSale().equals(contract.getSale())) {
            cc.setContent(cc.getContent() + "销售变更:" + saleMap.get(contract.getSale()) + "-->" + saleMap.get(resource.getSale()));
            contract.setSale(resource.getSale());
        }

        cc.setPlatform(contract.getPlatform());
        contractChangeRepository.save(cc);

        //同步修改trackingio的数据
//        if (contract.getPlatform().equals("tkio") && resource.getType().equals("main")) {
//            accountService.update(contract);
//        }
//        if (contract.getPlatform().equals("io") && resource.getType().equals("main")) {
//            accountIOService.update(contract);
//        }
//        if (contract.getPlatform().equals("adi")) {
//            adiAccountService.updateAccount(contract);
//        }

//        if (contract.getPlatform().equals("tkio")) {
//            if (contract.getType().equals("main")) {
//                IncrementFlow flow = incrementFlowRepository.findOne(resource.getContractCode());
//                if (null != flow) {
//                    flow.setEndDate(resource.getEndDate());
//                    flow.setStartDate(resource.getStartDate());
//                    if (contract.getExtraFlow() != resource.getExtraFlow()) {
//                        flow.setFlow(resource.getExtraFlow());
//                        incrementFlowRepository.save(flow);
//                    }
//                } else if (resource.getExtraFlow().longValue() > 0) {
//                    IncrementFlow flow1 = new IncrementFlow();
//                    Account account = accountRepository.findByEmail(contract.getEmail());
//                    flow1.setAccount(account.getId());
//                    flow1.setFlow(resource.getExtraFlow());
//                    flow1.setEndDate(resource.getEndDate());
//                    flow1.setStartDate(resource.getStartDate());
//                    flow1.setContractCode(resource.getContractCode());
//                    incrementFlowRepository.save(flow1);
//                }
//            }
//
//        }

        contract.setStatus(resource.getStatus());
        contract.setExtraFlow(resource.getExtraFlow());
        contract.setTradeType(resource.getTradeType());
        contract.setInvoiceMoney(resource.getInvoiceMoney());
        contract.setRelationContract(resource.getRelationContract());
        contract.setRebateMoney(resource.getRebateMoney());
        contract.setDiscountTimeLong(resource.getDiscountTimeLong());

        contract.setModifyTime(new Date());
        if (null != loginUser) {
            resource.setModifyAccount(loginUser.getId());
        }


        this.saveContractRelations(resource,contract.getId());

        return contractRepository.save(contract);
    }


    private void dealContractStatus(Contract resource){
        if (resource.getRebateMoney() != null) {
            if (resource.getMoney() == null) {
                resource.setMoney(0L);
            }

            if (resource.getRebateMoney().compareTo(BigDecimal.ZERO) <= 0) {
                //未回款
                resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());

            }else if(resource.getRebateMoney().compareTo(new BigDecimal(resource.getMoney()+""))< 0){
                // 部分回款
                resource.setStatus(ContractStatusEnum.MONEY_BACK_PART.getKey());
            }else{
                // 已回款
                resource.setStatus(ContractStatusEnum.MONEY_BACK_ALL.getKey());
            }

        } else {
            //未回款
            resource.setStatus(ContractStatusEnum.MONEY_BACK_NONE.getKey());
        }

        if (resource.getRebateMoney() == null) {
            resource.setRebateMoney(new BigDecimal(0));
        }

        if (resource.getInvoiceMoney() == null) {
            resource.setInvoiceMoney(new BigDecimal(0));
        }

        if (resource.getDiscountTimeLong() == null) {
            resource.setDiscountTimeLong(0L);
        }

        if (resource.getExtraFlow() == null) {
            resource.setExtraFlow(0L);
        }
    }


    /**
     *
     * @param loginAccount
     * @param startDate
     * @param endDate
     * @param platform
     * @param contractId 用于 获取关联合同列表
     * @return
     */
    @Override
    public List<Contract> findAll(User loginAccount, String startDate, String endDate, String platform, String contractId) {
        List<Contract> result = new ArrayList<>();
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }



        List<PackageType> typeList = packageTypeRepository.findAll();
        Map<Long, String> typeMap = new HashMap<>();
        if (ValidateUtil.isValid(typeList)) {
            for (PackageType s : typeList) {
                typeMap.put(s.getId(), s.getPackageName());
            }
        }
        List<ContractIncrement> incrementList = contractIncrementRepository.findAll();
        Map<Long, String> incremenMap = new HashMap<>();
        if (ValidateUtil.isValid(incrementList)) {
            for (ContractIncrement s : incrementList) {
                incremenMap.put(s.getId(), s.getPackageName());
            }
        }
        List<BPUContract> bpuContractList = bpuContractRepository.findAll();
        Map<Long, String> bpuMap = new HashMap<>();
        if (ValidateUtil.isValid(bpuContractList)) {
            for (BPUContract s : bpuContractList) {
                bpuMap.put(s.getId(), s.getPackageName());
            }
        }

        List<Long> contractIds = null;

        List<String> platforms = new ArrayList<>();
        platforms.add(platform);
        if (!StringUtils.isEmpty(contractId)) {
            //获取 关联合同列表
            contractIds = contractRelationRepository.findRelationIds(contractId);

            if("fake".equals(platform)){
                platforms.add("tkio");
            }
        }

        List<Contract> contractList = new ArrayList<>();



        if (loginAccount.getRole().equals(RoleEnum.SOUTH_BUSSINUSS.getKey()) || loginAccount.getRole().equals(RoleEnum.NORTH_BUSSINUSS.getKey())) {

            List<User> userList = userService.findAllSons(loginAccount.getId());
            List<Long> idList = new ArrayList<>();
            idList.add(loginAccount.getId());
            for (User u : userList) {
                idList.add(u.getId());
            }

//            contractList = contractRepository.findByDsAndRoile(startDate, endDate, platfrom, idList);


            if(!StringUtils.isEmpty(contractId)){
                //查看关联合同
                if (contractIds != null && contractIds.size() > 0) {
                    contractList = contractRepository.findByDsAndRoileRelation(startDate, endDate, platforms, idList, contractIds);
                }

            }else{
                contractList = contractRepository.findByDsAndRoile(startDate, endDate, platform, idList);
            }


        } else {
//            contractList = contractRepository.findByDs(startDate, endDate, platform);

            if(!StringUtils.isEmpty(contractId)){
                if (contractIds != null && contractIds.size() > 0) {
                    contractList = contractRepository.findByDsRelation(startDate, endDate, platforms, contractIds);
                }
            }else{
                contractList = contractRepository.findByDs(startDate, endDate, platform);
            }

        }

        if (ValidateUtil.isValid(contractList)) {
            for (Contract c : contractList) {

                if ((c.getExtraFlow() != null && c.getExtraFlow() > 0) ||
                        (c.getDiscountTimeLong() != null && c.getDiscountTimeLong() > 0)) {

                    c.setHasDiscount("有");

                } else {
                    c.setHasDiscount("无");
                }

                c.setSaleName(saleMap.containsKey(c.getSale()) ? saleMap.get(c.getSale()) : "");
                c.setPriceLevelName(typeMap.containsKey(c.getPriceLevel()) ? typeMap.get(c.getPriceLevel()) : "");
//                if (c.getType().equals(ContractTypeEnum.MAIN.getKey()) && platform.contains("io")) {
//
//                } else if (c.getType().equals(ContractTypeEnum.MAIN.getKey())) {
//                    c.setPriceLevelName(bpuMap.containsKey(c.getPriceLevel()) ? bpuMap.get(c.getPriceLevel()) : "");
//                } else {
//                    c.setPriceLevelName(incremenMap.containsKey(c.getPriceLevel()) ? incremenMap.get(c.getPriceLevel()) : "");
//                }

                c.setCreateName(saleMap.containsKey(c.getCreateAccount()) ? saleMap.get(c.getCreateAccount()) : "");
                result.add(c);
            }
        }
        return result;
    }

//    @Override
//    public List<Contract> findAllContract(User loginAccount, String startDate, String endDate, String platform, String contractId) {
//
//        List<Long> contractIds = null;
//
//        if (!StringUtils.isEmpty(contractId)) {
//            //获取 关联合同列表
//            contractIds = contractRelationRepository.findRelationIds(contractId);
//        }
//
//        List<Contract> contractList;
//        if (!loginAccount.getRole().equals(RoleEnum.MANAGER.getKey())) {
//            //非 管理员
//            List<User> userList = userService.findAllSons(loginAccount.getId());
//            List<Long> idList = new ArrayList<>();
//            idList.add(loginAccount.getId());
//            for (User u : userList) {
//                idList.add(u.getId());
//            }
//
//            if (contractIds != null && contractIds.size() > 0) {
//                contractList = contractRepository.findByDsAndRoileRelation(startDate, endDate, platform, idList, contractIds);
//            } else {
//                contractList = contractRepository.findByDsAndRoile(startDate, endDate, platform, idList);
//            }
//
//        } else {
//
//            if (contractIds != null && contractIds.size() > 0) {
//                contractList = contractRepository.findByDsRelation(startDate, endDate, platform, contractIds);
//            } else {
//                contractList = contractRepository.findByDs(startDate, endDate, platform);
//            }
//
//        }
//
//        return contractList;
//    }

    @Override
    public Contract contractStatusUpdate(String platform, String contractId, String status) {

        if (StringUtils.isEmpty(contractId)) {
            return null;
        }

        Contract contract = contractRepository.findOne(Long.parseLong(contractId));

        if (ContractStatusEnum.CANCEL.getKey().equals(status)) {
            contract.setStatus(status);
        } else {
            contract.setStatus(ContractStatusEnum.DELETE.getKey());
        }

        return contractRepository.save(contract);
    }

    @Override
    public Contract findOne(String code) {

        List<Contract> result = new ArrayList<>();
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }
        List<PackageType> typeList = packageTypeRepository.findAll();
        Map<Long, String> typeMap = new HashMap<>();
        if (ValidateUtil.isValid(typeList)) {
            for (PackageType s : typeList) {
                typeMap.put(s.getId(), s.getPackageName());
            }
        }
        List<ContractIncrement> incrementList = contractIncrementRepository.findAll();
        Map<Long, String> incremenMap = new HashMap<>();
        if (ValidateUtil.isValid(incrementList)) {
            for (ContractIncrement s : incrementList) {
                incremenMap.put(s.getId(), s.getPackageName());
            }
        }
        Contract contract = contractRepository.findByCode(code);
        contract.setSaleName(saleMap.containsKey(contract.getSale()) ? saleMap.get(contract.getSale()) : "");
        if (contract.getType().equals(ContractTypeEnum.MAIN.getKey())) {
            contract.setPriceLevelName(typeMap.containsKey(contract.getPriceLevel()) ? typeMap.get(contract.getPriceLevel()) : "");
        } else {
            contract.setPriceLevelName(incremenMap.containsKey(contract.getPriceLevel()) ? incremenMap.get(contract.getPriceLevel()) : "");
        }
        contract.setCreateName(saleMap.containsKey(contract.getCreateAccount()) ? saleMap.get(contract.getCreateAccount()) : "");

        Boolean flag = null;
        if (!contract.getType().equals(ContractTypeEnum.MAIN.getKey())) {
            //人群分析
            if (null == contract.getEndDate()) {
                flag = checkTime(contract.getEmail(), contract.getPlatform(), contract.getType(), "black");
            } else {
                flag = checkTime(contract.getEmail(), contract.getPlatform(), contract.getType(), "analysis");
            }

            if (flag) {
                contract.setContractType("0");
            } else {
                contract.setContractType("1");
            }
        }
        return contract;
    }

    @Override
    public ContractMoney pay(User loginUser, ContractMoney resource) {
        Contract contract = contractRepository.findByCode(resource.getContractCode());
        if (resource.getType().equals("pay")) {
            contract.setPayMoney(contract.getPayMoney() + resource.getMoney());
        } else {
            contract.setInvoice(contract.getInvoice() + resource.getMoney());
        }

        if (contract.getType().equals(ContractTypeEnum.INCREMENT.getKey())) {
            contract.setStatus("end");
        }
        contractRepository.save(contract);

        resource.setPlatform(contract.getPlatform());
        resource.setCreateAccount(loginUser.getId());
        resource.setCreateTime(new Date());
        resource.setUser(loginUser.getId());

        if (resource.getType().equals("pay") && contract.getPlatform().equals("tkio")) {
            tkioAccountService.contractPay(loginUser, resource);
        } else if (resource.getType().equals("pay") && contract.getPlatform().equals("io")) {
            ioAccountService.contractPay(loginUser, resource);
        }
        return contractMoneyRepository.save(resource);
    }

    @Override
    public Contract change(User loginUser, ContractChange resource) {
        Map<Long, String> packageMap = getPackageMap();
        Map<Long, String> saleMap = getSaleMap();
        Contract contract = contractRepository.findByCode(resource.getContractCode());
        if (resource.getType().equals("price")) {
            resource.setContent("套餐变更 :" + packageMap.get(contract.getPriceLevel()) + "-->" + packageMap.get(resource.getLevel())
                    + " 金额变更 :" + contract.getMoney() + "-->" + (resource.getMoney() + contract.getMoney()));

            contract.setMoney(resource.getMoney() + contract.getMoney());
            contract.setPriceLevel(resource.getLevel());
            Double rebat = getRebat(contract.getProduct(), contract.getPriceLevel().intValue(), contract.getMoney());
            BigDecimal bg = new BigDecimal(rebat);
            double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            contract.setRebate(f1);

            //同步修改trackingio的数据
            if (contract.getPlatform().equals("tkio")) {
                accountService.update(contract);
            } else if (contract.getPlatform().equals("io")) {
                accountIOService.update(contract);
            }
        } else {
            //同步修改trackingio的数据
            if (contract.getPlatform().equals("tkio") && contract.getType().equals("main")) {
                accountService.forbiden(contract);
            } else if (contract.getPlatform().equals("io") && contract.getType().equals("main")) {
                accountIOService.update(contract);
            }
            contract.setStatus("cancel");
        }
        resource.setPlatform(contract.getPlatform());
        resource.setCreateAccount(loginUser.getId());
        resource.setCreateTime(new Date());
        resource.setDs(DateUtil.getBeforeDays(0));
        resource.setUser(loginUser.getId());
        contractChangeRepository.save(resource);

        return contractRepository.save(contract);
    }

    @Override
    public List<ContractMoney> findPay(String startDate, String endDate, String code) {
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        List<ContractMoney> result = new ArrayList<>();
        List<ContractMoney> list = contractMoneyRepository.findByDs(startDate, endDate, code);
        if (ValidateUtil.isValid(list)) {
            for (ContractMoney cm : list) {
                cm.setCreateName(saleMap.containsKey(cm.getUser()) ? saleMap.get(cm.getUser()) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public List<ContractChange> findChange(String startDate, String endDate, String code) {

        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        List<ContractChange> result = new ArrayList<>();
        List<ContractChange> list = contractChangeRepository.findByDs(startDate, endDate, code);
        if (ValidateUtil.isValid(list)) {
            for (ContractChange cm : list) {
                cm.setCreateName(saleMap.containsKey(cm.getUser()) ? saleMap.get(cm.getUser()) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public Contract updatePay(User loginUser, ContractMoney resource) {
        ContractMoney contractMoney = contractMoneyRepository.findOne(resource.getId());
        Contract contract = contractRepository.findByCode(resource.getContractCode());
        if (contractMoney.getType().equals("pay")) {
            contract.setPayMoney(contract.getPayMoney() + resource.getMoney() - contractMoney.getMoney());
        } else {
            contract.setInvoice(contract.getInvoice() + resource.getMoney() - contractMoney.getMoney());
        }
        Contract save = contractRepository.save(contract);

        contractMoney.setModifyAccount(loginUser.getId());
        contractMoney.setModifyTime(new Date());
        contractMoney.setMoney(resource.getMoney());
        contractMoney.setDs(resource.getDs());
        contractMoneyRepository.save(contractMoney);

        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }
        List<PackageType> typeList = packageTypeRepository.findAll();
        Map<Long, String> typeMap = new HashMap<>();
        if (ValidateUtil.isValid(typeList)) {
            for (PackageType s : typeList) {
                typeMap.put(s.getId(), s.getPackageName());
            }
        }

        save.setSaleName(saleMap.containsKey(save.getSale()) ? saleMap.get(save.getSale()) : "");
        save.setPriceLevelName(typeMap.containsKey(save.getPriceLevel()) ? typeMap.get(save.getPriceLevel()) : "");
        save.setCreateName(saleMap.containsKey(save.getSale()) ? saleMap.get(save.getSale()) : "");
        return save;
    }

    @Override
    public List<ContractMoney> findPayAll(String startDate, String endDate, String platfrom) {
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }

        List<ContractMoney> result = new ArrayList<>();
        List<ContractMoney> list = contractMoneyRepository.findByDsAll(startDate, endDate, platfrom);
        if (ValidateUtil.isValid(list)) {
            for (ContractMoney cm : list) {
                cm.setCreateName(saleMap.containsKey(cm.getUser()) ? saleMap.get(cm.getUser()) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public List<TradeType> getTradeData(String platform) {
        return tradeTypeRepsitory.findAll();
    }

    @Override
    public List<Map> contractCodeAll(String platform, String contractId) {

        Map<String,String> data = new HashMap<>();
        data.put("id","-1");
        data.put("contractCode","无");

        List result = new ArrayList();
        result.add(data);

        List<String> plats = new ArrayList<>();

        plats.add(platform);

        if("fake".equals(platform)){
            plats.add("tkio");
        }

        List<ContractRelation> ids = null;

        if(!StringUtils.isEmpty(contractId)){
            ids =  contractRelationRepository.findRelationIdsMain(contractId);
        }

        if (ids != null) {

            Map<String,String> filterMap = new HashMap();
            for(ContractRelation relation : ids){
                filterMap.put(relation.getRelationId()+"_","");
            }

            List<Map> resultBefore = contractRepository.contractCodePlatform(plats);
            for (Map  m : resultBefore) {

                String m_id = m.get("id").toString() + "_";
                if (filterMap.get(m_id) == null && !m_id.equals(contractId+"_")) {
                    result.add(m);
                }
            }

        } else {
            result.addAll(contractRepository.contractCodePlatform(plats));
        }

        return result;
    }

    public Map<Long, String> getPackageMap() {
        List<PackageType> typeList = packageTypeRepository.findAll();
        Map<Long, String> typeMap = new HashMap<>();
        if (ValidateUtil.isValid(typeList)) {
            for (PackageType s : typeList) {
                typeMap.put(s.getId(), s.getPackageName());
            }
        }
        return typeMap;
    }

    public Map<Long, String> getSaleMap() {
        List<User> sales = userRepository.findAll();
        Map<Long, String> saleMap = new HashMap<>();
        if (ValidateUtil.isValid(sales)) {
            for (User s : sales) {
                saleMap.put(s.getId(), s.getName());
            }
        }
        return saleMap;
    }

    public static Map<String, String> convertBean(Object bean) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class type = bean.getClass();
        Map<String, String> returnMap = new HashMap<String, String>();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();

                Object invoke = readMethod.invoke(bean, new Object[0]);
                String result = (null == invoke ? null : invoke.toString());

                if (result != null) {
                    returnMap.put(propertyName, result);
                } else {
                    returnMap.put(propertyName, null);
                }


            }
        }
        return returnMap;
    }


//    public static void main(String[] args) {
//
//        ContractServiceImpl contractService = new ContractServiceImpl();
//        try {
//            Map data = contractService.dealContractChangeMap(new Contract(), new Contract());
//            System.out.println(data);
//
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//
//    }
}