package track.service.impl;

import common.model.*;
import common.repository.*;
import dic.RoleEnum;
import dic.RoleTypeEnum;
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 track.model.Account;
import track.model.App;
import track.repository.TrackAccountRepository;
import track.repository.TrackAppRepository;
import track.repository.TrackCampaignRepository;
import track.repository.TrackChannelRepository;
import track.service.TrackAccountService;
import util.Constant;
import util.DateUtil;
import util.HttpClientUtil;
import util.ValidateUtil;

import java.math.BigInteger;
import java.util.*;

/**
 * Created by mxq on 2017/12/27.
 */
@Service
public class TrackAccountServiceImpl implements TrackAccountService{

    @Autowired
    TrackAccount4WebRepository trackAccount4WebRepository;
    @Autowired
    TrackAccountRepository accountRepository;
    @Autowired
    BackVisitRepository backVisitRepository;
    @Autowired
    PaymentRepository paymentRepository;
    @Autowired
    ReminderRepository reminderRepository;
    @Autowired
    TrackCampaignRepository campaignRepository;
    @Autowired
    TrackChannelRepository channelRepository;
    @Autowired
    TrackAppRepository appRepository;

    @Autowired
    UserRepository userRepository;

    @Override
    public List<TrackAccount4Web> findAll(User user) {
        List<TrackAccount4Web> result = new ArrayList<>();
        List<TrackAccount4Web> account4WebList = null;
        if(user.getRole().equals(RoleEnum.MANAGER.getKey())){
            account4WebList = trackAccount4WebRepository.findAll();
        }
        List<Reminder> reminderList = reminderRepository.findAllDistinct("track");
        Map<Long, Boolean> reMap = new HashMap<>();
        if(ValidateUtil.isValid(reminderList)){
            for(Reminder re : reminderList){
                reMap.put(re.getAccountId(), re.getRemindStatus());
            }
        }
        if(ValidateUtil.isValid(account4WebList)){
            Map<String, Integer> backTimeMap = getBackTime();
            Map<String, Long> payMap = getPayment();
            for(TrackAccount4Web aw : account4WebList){
                if(backTimeMap.containsKey(aw.getEmail())){
                    aw.setBackTime(backTimeMap.get(aw.getEmail()));
                } else{
                    aw.setBackTime(0);
                }
                if(payMap.containsKey(aw.getEmail())){
                    aw.setMoney(payMap.get(aw.getEmail()));
                } else{
                    aw.setMoney(0L);
                }
                if(reMap.containsKey(aw.getAccountId())){
                    aw.setRemStatus(reMap.get(aw.getAccountId()));
                } else{
                    aw.setRemStatus(true);
                }
                result.add(aw);
            }
        }
        return result;
    }

    @Override
    public Reminder forbiden(User user, Reminder resource) {
        resource.setUser(user.getId());
        resource.setModifyTime(new Date());
        resource.setPlatform("track");
        resource.setRemindStatus(false);
        resource.setDs(DateUtil.getBeforeDays(0));
        return reminderRepository.save(resource);
    }

    @Override
    public Reminder enable(User user, Reminder resource) {
        resource.setUser(user.getId());
        resource.setModifyTime(new Date());
        resource.setPlatform("track");
        resource.setRemindStatus(true);
        resource.setDs(DateUtil.getBeforeDays(0));
        return reminderRepository.save(resource);
    }

    @Override
    public Payment pay(User user, Payment resource) {
        resource.setUser(user.getId());
        resource.setPayDate(new Date());
        resource.setPlatform("track");
        resource.setDs(DateUtil.getBeforeDays(0));
        return paymentRepository.save(resource);
    }

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

    @Override
    public Map<String, Integer> findFunTimes(Long account, String startDate, String endDate) {
        Map<String, Integer> result = new HashMap<>();
        List<Account> accountList = accountRepository.findByParent(account);
        List<Long> idList = new ArrayList<>();
        idList.add(account);
        for(Account ac : accountList){
            idList.add(ac.getId());
        }

        List<App> appList = appRepository.findByAccount(idList);
        List<Long> appidList = new ArrayList<>();
        if(ValidateUtil.isValid(appList)){
            for(App app : appList){
                appidList.add(app.getId());
            }
        }

        BigInteger numAccount = accountRepository.countByRootParent(account, startDate, endDate);
        BigInteger numApp = appRepository.countByAccount(idList, startDate, endDate);
        BigInteger numCampaign = campaignRepository.countByAccount(idList, startDate, endDate);
        BigInteger numChannel = channelRepository.countByAccount(idList, startDate, endDate);

        result.put("numAccount", numAccount.intValue());
        result.put("numApp", numApp.intValue());
        result.put("numCampaign", numCampaign.intValue());
        result.put("numChannel", numChannel.intValue());
        result.put("event_sum", null);
        result.put("click_sum", null);
        return result;
    }


    @Override
    public List<Reminder> findRed(Long account, String startDate, String endDate) {
        List<Reminder> 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<Reminder> list = reminderRepository.findAll(account, startDate, endDate, "track");
        if (ValidateUtil.isValid(list)) {
            for(Reminder re : list){
                re.setUserName(userMap.get(re.getUser()));
                result.add(re);
            }
        }
        return result;
    }

    @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, "track");
        if (ValidateUtil.isValid(list)) {
            for(BackVisit re : list){
                re.setUserName(userMap.get(re.getUser()));
                result.add(re);
            }
        }
        return result;
    }

    @Override
    public List<Payment> findPay(Long account, String startDate, String endDate) {
        List<Payment> 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<Payment> list = paymentRepository.findAll(account, startDate, endDate, "track");
        if (ValidateUtil.isValid(list)) {
            for(Payment re : list){
                re.setUserName(userMap.get(re.getUser()));
                result.add(re);
            }
        }
        return result;
    }


    public Map<String, Integer> getBackTime(){
        Map<String, Integer> map = new HashMap<>();
        List<BackVisit> all = backVisitRepository.findAllByPlatform("track");
        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, Long> getPayment(){
        Map<String, Long> map = new HashMap<>();
        List<Payment> all = paymentRepository.findAllByPlatform("track");
        if (ValidateUtil.isValid(all)){
            for(Payment pa : all){
                if(map.containsKey(pa.getEmail())){
                    map.put(pa.getEmail(), map.get(pa.getEmail()) + pa.getMoney());
                } else{
                    map.put(pa.getEmail(), pa.getMoney());
                }
            }
        }
        return map;
    }
}
