package adi.service.impl;

import adi.model.ADIUser;
import adi.service.ADIAccountService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import common.model.*;
import common.repository.*;
import common.service.UserService;
import dic.ContractTypeEnum;
import dic.RoleEnum;
import dic.RoleTypeEnum;
import office.model.ADISaleMap;
import office.model.BussinessMan;
import office.repository.ADISaleMapRepository;
import office.repository.BussinessManRepository;
import org.apache.commons.collections4.list.TreeList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tkio.model.PackageType;
import userio.repository.IOPackageTypeRepository;
import userio.repository.IOSalesManLeaderRepository;
import util.DateUtil;
import util.HttpClientUtil;
import util.ValidateUtil;

import javax.annotation.Nullable;
import java.io.IOException;
import java.util.*;

/**
 * Created by mxq on 2017/12/26.
 */
@Service
public class ADIAccountServiceImpl implements ADIAccountService {

    //查询URI
    private final static String URI_REPORT_BY_SQL = "/api/trackingio/bysql";

    @Autowired
    IOAccount4WebRepository account4WebRepository;
    @Autowired
    IOSalesManLeaderRepository salesManLeaderRepository;
    @Autowired
    BackVisitRepository backVisitRepository;
    @Autowired
    PaymentRepository paymentRepository;
    @Autowired
    BussinessManRepository bussinessManRepository;
    @Autowired
    ADISaleMapRepository adiSaleMapRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    ContractMoneyRepository contractMoneyRepository;
    @Autowired
    ContractRepository contractRepository;
    @Autowired
    ContractChangeRepository contractChangeRepository;
    @Autowired
    IOPackageTypeRepository packageTypeRepository;
    @Autowired
    UserService userService;
    @Autowired
    ReminderLevelRepository reminderLevelRepository;
    @Autowired
    PressMoneyRepository pressMoneyRepository;
    private static String u = "http://10.3.20.51:80/";
    @Override
    public Map<String, Object> findSale(User user, Long sale) {
        Map<String, Object> map = new HashMap();
        String email = null;
        if(null != sale){
            User user1 = userRepository.findOne(sale);
            if (null != user1)
                map.put("old", user1.getName());
        }
        List<User> list = new ArrayList<>();
        if(user.getRole().equals(RoleEnum.NORTH_BUSSINUSS.getKey()) || user.getRole().equals(RoleEnum.SOUTH_BUSSINUSS.getKey())){
            list = userService.findbyRole(user.getRole());
        }else {
            list = userRepository.findSales();
        }
        map.put("new", list);
        return map;
    }

    @Override
    public Map<String, String> findSale(String email) {
        Map<String, String> map = new HashMap<>();
        System.out.println(email);
        ADISaleMap adiSaleMap = adiSaleMapRepository.findByAccountEmail(email);
        System.out.println(adiSaleMap);
        if(null != adiSaleMap && null != adiSaleMap.getSaleEmail()){
            User user = userRepository.findByEmail(adiSaleMap.getSaleEmail());
            System.out.println(user);
            map.put("name",user.getName());
            map.put("phone","");
        }
        System.out.println(map);
        return map;
    }

    @Override
    public IOAccount4Web updateSale(String email, String account) {
        BussinessMan bussinessMan = bussinessManRepository.findByEmail(email);
        ADISaleMap adiSaleMap = adiSaleMapRepository.findByAccountEmail(account);
        System.out.println(account + "==" + (null == adiSaleMap));
        if(null == adiSaleMap){
            adiSaleMap = new ADISaleMap();
            adiSaleMap.setAccountEmail(account);
            adiSaleMap.setSaleEmail(email);
            adiSaleMap.setSale(bussinessMan.getId());
            adiSaleMap.setModifeTime(new Date());
        }else {
            adiSaleMap.setSaleEmail(email);
            adiSaleMap.setSale(bussinessMan.getId());
        }
        adiSaleMapRepository.save(adiSaleMap);
        return null;
    }

    @Override
    public void updateAccount(Contract contract) {
        ADIUser adiUser = findOne(contract.getEmail());
        if(null != adiUser){
            String url = u + "adi/api/user/web/update";
            Map<String,String> conditions = new HashMap<>();
            conditions.put("expriedTime", contract.getEndDate() + " 00:00:00");
            conditions.put("constractStartTime",contract.getStartDate() + " 00:00:00");
            conditions.put("id", adiUser.getId().toString());
            String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");

            if(!contract.getSale().equals(adiUser.getBussinessMan())){
                User user = userRepository.findOne(contract.getSale());
                updateSale(user.getEmail(), adiUser.getEmail());
            }
        }
    }



    private  List<ADIUser> getAllAccount() throws JSONException {
        List<ADIUser> list = new ArrayList<>();
        String url = u + "adi/api/user/web/list";
        Map<String,String> conditions = new HashMap<>();
        conditions.put("type","");
        conditions.put("status","");
        // conditions.put("keyw","");
        String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");
        JSONObject rs = new JSONObject(request);
        List<Contract> contractList = contractRepository.findByPlatform("adi");
        Map<String, Contract> dicContract = new HashMap<>();
        if(ValidateUtil.isValid(contractList)){
            for(Contract co : contractList){
                dicContract.put(co.getEmail(), co);
            }
        }

        List<ADISaleMap> saleMaps = adiSaleMapRepository.findAll();
        final Map<String, ADISaleMap> dicSale = Maps.uniqueIndex(saleMaps, new Function<ADISaleMap, String>() {
            @Override
            public String apply(@Nullable ADISaleMap adiSaleMap)
            {
                return adiSaleMap.getAccountEmail();
            }
        });
        JSONArray rsJSONArray = rs.getJSONArray("content");
        if(rsJSONArray.length() > 0 && !rsJSONArray.isNull(0)){
            for(int i = 0; i < rsJSONArray.length(); i++){
                String object = rsJSONArray.get(i).toString();
                ADIUser val = null;
                try {
                    System.out.println(object);
                    val = new ObjectMapper().readValue(object, ADIUser.class);
                    System.out.println(val);
                    if(dicContract.containsKey(val.getEmail())){
                        Contract contract = dicContract.get(val.getEmail());
                        String date = DateUtil.format(val.getExpriedTime(), "yyyy-MM-dd");
                        if(null != date && contract.getPayMoney() > 0 && contract.getEndDate().compareTo(date) >= 0){
                            val.setPackageType("正式套餐");
                        }else{
                            val.setPackageType("试用套餐");
                        }
                    }

                    if(null != dicSale.get(val.getEmail().toString())){
                        ADISaleMap saleMap = dicSale.get(val.getEmail());
                        val.setBussinessMan(saleMap.getSale());
                        val.setBussinessManEmail(saleMap.getSaleName());
                    }else{
                        val.setBussinessMan(null);
                    }
                    list.add(val);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        return list;
    }

    private List<ADIUser> transAccount(List<ADIUser> list, List<String> emailList){
        List<ADIUser> result = new ArrayList<>();
        if(ValidateUtil.isValid(list)){
            for(ADIUser aw : list){
                if(null != emailList && !emailList.contains(aw.getBussinessManEmail())){
                    continue;
                }

                Map<String, String> statusMap = ImmutableMap.of("0", "未激活",
                        "1", "已开通",
                        "2", "已过期",
                        "3","已停用");
                List<ADISaleMap> saleMapList = adiSaleMapRepository.findAll();
                Map<String, String> busAccMap = new HashMap<>();
                for(ADISaleMap u : saleMapList){
                    busAccMap.put(u.getAccountEmail(),u.getSaleEmail());
                }

                List<PressMoney> allPress = pressMoneyRepository.findAllPress("adi");
                Map<Long, Boolean> pressMap = new HashMap<>();
                if(ValidateUtil.isValid(allPress)){
                    for(PressMoney re : allPress){
                        pressMap.put(re.getAccountId(), re.getPressStatus());
                    }
                }
                List<BussinessMan> roles = bussinessManRepository.findAll();
                Map<String, String> busMap = new HashMap<>();
                for(BussinessMan u : roles){
                    busMap.put(u.getEmail(),u.getName());
                }
                List<User> users = userRepository.findAll();
                Map<String, Long> saleMap = new HashMap<>();
                for(User u : users){
                    saleMap.put(u.getEmail(),u.getId());
                }
                Map<String, Integer> backTimeMap = getBackTime();
                Map<String, List<Contract>> payMap = getPay();

                if (backTimeMap.containsKey(aw.getEmail())) {
                    aw.setBackTime(backTimeMap.get(aw.getEmail()));
                } else {
                    aw.setBackTime(0);
                }

                if (busAccMap.containsKey(aw.getEmail())) {
                    aw.setSaleName(busMap.get(busAccMap.get(aw.getEmail())));
                    aw.setSaleEamil(busAccMap.get(aw.getEmail()));
                } else {
                    aw.setSaleName("");
                }
                if (pressMap.containsKey(aw.getId())) {
                    aw.setPressStatus(true);
                    aw.setContractStatus("stop");
                } else {
                    aw.setPressStatus(false);
                }
                if (payMap.containsKey(aw.getEmail())) {
                    List<Contract> contractList = payMap.get(aw.getEmail());
                    aw.setMoney(contractList.get(contractList.size() - 1).getPayMoney());
                    aw.setContractStatus(contractRepository.findByPlatformAndEmailLimit1("adi", aw.getEmail(), ContractTypeEnum.MAIN.getKey()).getStatus());
                    aw.setContractTime(contractList.size());
                } else {
                    aw.setContractTime(0);
                    aw.setContractStatus("empty");
                    aw.setMoney(0L);
                }
                if (saleMap.containsKey(aw.getSaleEamil())) {
                    aw.setSale(saleMap.get(aw.getSaleEamil()));
                }
                aw.setStatus(statusMap.get(aw.getStatus()));
                aw.setPastDate(null == aw.getExpriedTime() ? "" :DateUtil.getFormatDate(aw.getExpriedTime()));
                aw.setAccountId(aw.getId());
                result.add(aw);
            }
        }
        return result;
    }
    @Override
    public List<ADIUser> findAll(User user) {
        List<ADIUser> result = new ArrayList<>();
        List<ADIUser> account4WebList = null;
        List<String> emialList = null;
        try {
            account4WebList = getAllAccount();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(user.getRole().equals(RoleEnum.MANAGER.getKey())){

        } else{
            if(user.getRoleType().equals(RoleTypeEnum.MANAGER.getKey())){
                List<User> userList = userRepository.findAllUserByRole(user.getRole());
                emialList = new ArrayList<>();
                for(User u : userList){
                    emialList.add(u.getEmail());
                }
            }else{
                List<String> emailList = new ArrayList<>();
                emailList.add(user.getEmail());
                List<User> userList = userService.findAllSons(user.getId());
                if(ValidateUtil.isValid(userList)){
                    for(User u : userList){
                        emailList.add(u.getEmail());
                    }
                }
            }
        }

        result = transAccount(account4WebList, emialList);
        return result;
    }
    @Override
    public ADIUser findOne(String email) {
        String url = u + "adi/api/user/web/one";
        Map<String,String> conditions = new HashMap<>();
        conditions.put("field", "email");
        conditions.put("value",email);
        String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");
        ADIUser adiUser =null;
        try {
            JSONObject rs = new JSONObject(request);
            String content = rs.get("content").toString();
            if(!"null".equals(content)){
                try {
                    adiUser = new ObjectMapper().readValue(content, ADIUser.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(null != adiUser){
            List<ADIUser> list = new ArrayList<>();
            list.add(adiUser);
            List<ADIUser> adiUsers = transAccount(list, null);
            adiUser = adiUsers.get(0);
        }
        return adiUser;
    }

    @Override
    public List<ReminderLevel> findReminderlevel() {
        return reminderLevelRepository.findAll();
    }




    @Override
    public PressMoney forbidenPress(User user, PressMoney resource) {
        PressMoney pressMoney = pressMoneyRepository.findOne("adi", resource.getAccountId());
        pressMoney.setUser(user.getId());
        pressMoney.setModifyTime(new Date());
        pressMoney.setPressStatus(false);
        pressMoney.setDs(DateUtil.getBeforeDays(0));

        Contract contract = contractRepository.findByPlatformAndEmailLimit1("adi", resource.getEmail(), ContractTypeEnum.MAIN.getKey());
        if(null != contract){
            contract.setStatus("executing");
            contractRepository.save(contract);
        }
        String url = u + "adi/api/user/web/update";
        Map<String,String> conditions = new HashMap<>();
        conditions.put("expriedTime", null);
        conditions.put("constractStartTime",null);
        conditions.put("useStatus","0");
        conditions.put("id", resource.getAccountId().toString());
        // conditions.put("keyw","");
        String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");

        pressMoneyRepository.save(pressMoney);
        return null;
    }

    @Override
    public PressMoney enablePress(User user, PressMoney resource) {
        PressMoney pressMoney = pressMoneyRepository.findOne("adi", resource.getAccountId());
        if(null == pressMoney){
            resource.setUser(user.getId());
            resource.setModifyTime(new Date());
            resource.setPlatform("adi");
            resource.setPressStatus(true);
            resource.setDs(DateUtil.getBeforeDays(0));
            pressMoneyRepository.save(resource);
        }else{
            pressMoney.setUser(user.getId());
            pressMoney.setModifyTime(new Date());
            pressMoney.setPressStatus(true);
            pressMoney.setDs(DateUtil.getBeforeDays(0));
            pressMoneyRepository.save(pressMoney);
        }


        Contract contract = contractRepository.findByPlatformAndEmailLimit1("adi", resource.getEmail(), ContractTypeEnum.MAIN.getKey());
        if(null != contract){
            contract.setStatus("stop");
            contractRepository.save(contract);
        }

        String url = u + "adi/api/user/web/update";
        Map<String,String> conditions = new HashMap<>();
        conditions.put("expriedTime", null);
        conditions.put("constractStartTime",null);
        conditions.put("useStatus","1");
        conditions.put("id", resource.getAccountId().toString());
        // conditions.put("keyw","");
        String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");

        return null;
    }



    @Override
    public BackVisit visit(User user, BackVisit resource) {
        resource.setUser(user.getId());
        resource.setVisitDate(new Date());
        resource.setPlatform("adi");
        resource.setDs(DateUtil.getBeforeDays(0));
        return backVisitRepository.save(resource);
    }


    @Override
    public List<BackVisit> findVisit(Long account, String startDate, String endDate) {
        List<BackVisit> result = new ArrayList<>();
        List<User> userList = userRepository.findAll();
        Map<Long, String> userMap = new HashMap<>();
        for(User u : userList){
            userMap.put(u.getId(), u.getName());
        }
        List<BackVisit> list = backVisitRepository.findAll(account, startDate, endDate, "adi");
        if (ValidateUtil.isValid(list)) {
            for(BackVisit re : list){
                re.setUserName(userMap.get(re.getUser()));
                result.add(re);
            }
        }
        return result;
    }

    @Override
    public List<ContractMoney> findPay(String email, String startDate, String endDate) {
        List<ContractMoney> result = new ArrayList<>();
        List<User> userList = userRepository.findAll();
        Map<Long, String> userMap = new HashMap<>();
        for(User u : userList){
            userMap.put(u.getId(), u.getName());
        }
        List<ContractMoney> list = contractMoneyRepository.findByDs(startDate, endDate, email,"adi");
        if(ValidateUtil.isValid(list)){
            for(ContractMoney cm : list){
                Long user = null == cm.getModifyAccount() ? cm.getUser() : cm.getModifyAccount();
                cm.setCreateName(userMap.containsKey(user) ? userMap.get(user) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public List<Contract> findContract(String email) {
        List<Contract> result = new ArrayList<>();
        List<User> userList = userRepository.findAll();
        Map<Long, String> userMap = new HashMap<>();
        for(User u : userList){
            userMap.put(u.getId(), u.getName());
        }

        List<Contract> contractList = contractRepository.findByPlatformAndEmail("adi", email,ContractTypeEnum.MAIN.getKey());
        if(ValidateUtil.isValid(contractList)){
            for(Contract cm : contractList){
                cm.setSaleName(userMap.containsKey(cm.getSale()) ? userMap.get(cm.getSale()) : "");
               // cm.setPriceLevelName(typeMap.containsKey(cm.getPriceLevel()) ? typeMap.get(cm.getPriceLevel()) : "");
                result.add(cm);
            }
        }
        return result;
    }

    @Override
    public List<Contract> findContractChange(String email, String startDate, String endDate) {
        List<Contract> result = new ArrayList<>();
        List<User> userList = userRepository.findAll();
        Map<Long, String> userMap = new HashMap<>();
        for(User u : userList){
            userMap.put(u.getId(), u.getName());
        }

        List<Contract> contractList = contractRepository.findByPlatformAndEmail("adi", email,ContractTypeEnum.MAIN.getKey());
        if(ValidateUtil.isValid(contractList)){
            for(Contract cm : contractList){
                cm.setSaleName(userMap.containsKey(cm.getSale()) ? userMap.get(cm.getSale()) : "");
                //cm.setPriceLevelName(typeMap.containsKey(cm.getPriceLevel()) ? typeMap.get(cm.getPriceLevel()) : "");
                result.add(cm);
            }
        }
        return result;
    }


    public Map<String, Integer> getBackTime(){
        Map<String, Integer> map = new HashMap<>();
        List<BackVisit> all = backVisitRepository.findAllByPlatform("adi");
        if (ValidateUtil.isValid(all)){
            for(BackVisit bv : all){
                if(map.containsKey(bv.getEmail())){
                    map.put(bv.getEmail(), map.get(bv.getEmail()) + 1);
                } else{
                    map.put(bv.getEmail(), 1);
                }
            }
        }
        return map;
    }



    public Map<String, List<Contract>> getPay(){
        Map<String, List<Contract>> map = new HashMap<>();
        List<Contract> contractList = contractRepository.findByPlatform("adi");
        if (ValidateUtil.isValid(contractList)){
            for(Contract pa : contractList){
                if(map.containsKey(pa.getEmail())){
                    List<Contract> list = map.get(pa.getEmail());
                    list.add(pa);
                    map.put(pa.getEmail(), list);
                } else{
                    List<Contract> list = new TreeList<>();
                    list.add(pa);
                    map.put(pa.getEmail(), list);
                }
            }
        }
        return map;
    }

    public static void main(String[] args) {
        String url = u + "adi/api/user/web/one";
        Map<String,String> conditions = new HashMap<>();
        conditions.put("field", "email");
        conditions.put("value","zhangshaoyou@reyun.com");
        String request = HttpClientUtil.doHttpPostRequest(url, "",conditions,"utf-8");
        System.out.println(request);
        ADIUser adiUser =null;
        try {
            JSONObject rs = new JSONObject(request);
            String content = rs.get("content").toString();
            if(!"null".equals(content)){
                try {
                    adiUser = new ObjectMapper().readValue(content, ADIUser.class);
                    System.out.println(adiUser);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

//        String url2 = "http://localhost:8081/adi/api/user/web/update";
//        Map<String,String> conditions2 = new HashMap<>();
//        conditions2.put("expriedTime", null);
//        conditions2.put("constractStartTime",null);
//        conditions2.put("status","3");
//        conditions2.put("id", "2");
//        // conditions.put("keyw","");
//        String request2 = HttpClientUtil.doHttpPostRequest(url2, "",conditions2,"utf-8");
    }
}
