package common.service.impl;

import common.model.Auth;
import common.model.Code;
import common.model.User;
import common.repository.AuthRepository;
import common.repository.CodeRepository;
import common.repository.UserRepository;
import common.service.UserService;
import dic.RoleEnum;
import dic.RoleTypeEnum;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import office.service.BussinussManService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tkio.service.SalesManService;
import userio.service.IOSalesManService;
import util.CharacterUtils;
import util.CipherUtil;
import util.MailUtils;
import util.ValidateUtil;

import java.util.*;

/**
 * Created by mxq on 2017/12/21.
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private AuthRepository authRepository;
    @Autowired
    private CodeRepository codeRepository;
    @Autowired
    BussinussManService bussinussManService;
    @Autowired
    private SalesManService salesManService;
    @Autowired
    private IOSalesManService ioSalesManService;

    @Override
    public Boolean validEmail(String email) {
        User user = userRepository.login(email);
        if(null == user){
            return true;
        }
        return false;
    }

    @Override
    public User create(User login, User resource) {

        if(!login.getRole().equals(RoleEnum.MANAGER.getKey())){//非管理员只能创建本部门普通账户
            resource.setRole(login.getRole());
            resource.setRoleType(RoleTypeEnum.COMMON.getKey());
        }
        resource.setPassword(CipherUtil.generatePassword(resource.getPassword()));
        resource.setCreateTime(new Date());
        resource.setCreateAccount(login.getId());
        resource.setStatus(true);
        User save = userRepository.save(resource);

        if(resource.getRole().equals(RoleEnum.SOUTH_BUSSINUSS.getKey())){
            bussinussManService.create(login.getEmail(), save.getEmail(), save.getName(),"华北");
            salesManService.create(login.getEmail(), save.getEmail(), save.getName());
            ioSalesManService.create(login.getEmail(), save.getEmail(), save.getName());
        } else if(resource.getRole().equals(RoleEnum.NORTH_BUSSINUSS.getKey())){
            bussinussManService.create(login.getEmail(), save.getEmail(), save.getName(),"华南");
            salesManService.create(login.getEmail(), save.getEmail(), save.getName());
            ioSalesManService.create(login.getEmail(), save.getEmail(), save.getName());
        }


        //auth
        Auth auth = new Auth();
        auth.setCreateTime(new Date());
        auth.setCreateAccount(login.getId());
        auth.setAuth(resource.getAuth());
        auth.setUser(save.getId());
        authRepository.save(auth);
        return save;
    }

    @Override
    public User update(User login, User resource) {
        User one = userRepository.findOne(resource.getId());
        if(!login.getRole().equals(RoleEnum.MANAGER.getKey())){//非管理员只能创建本部门普通账户
            resource.setRole(login.getRole());
            resource.setRoleType(RoleTypeEnum.COMMON.getKey());
        }
        resource.setCreateTime(one.getCreateTime());
        resource.setStatus(one.getStatus());
        resource.setDelFlag(one.getDelFlag());
        resource.setCreateAccount(one.getCreateAccount());
        resource.setPassword(one.getPassword());
        resource.setModifyTime(new Date());
        resource.setModifyAccount(login.getId());
        User save = userRepository.save(resource);

        //auth
        Auth auth = authRepository.findByUser(one.getId());
        auth.setModifyTime(new Date());
        auth.setModifyAccount(login.getId());
        auth.setAuth(resource.getAuth());
        auth.setUser(save.getId());
        Auth authSave = authRepository.save(auth);

        if(null != save.getRoleType() && save.getRoleType().equals(RoleTypeEnum.COMMON.getKey())){
            JSONArray rootArr = JSONArray.fromObject(authSave.getAuth());
            List<String> authList = new ArrayList<>();
            if(ValidateUtil.isValid(rootArr)){
                for (int i = 0; i < rootArr.size(); i++) {
                    JSONObject obj = rootArr.getJSONObject(i);
                    authList.add(obj.getString("id"));
                }
            }
            List<User> userList = findSonsAlive(save.getId());
            if(ValidateUtil.isValid(userList)){
                List<Long> ids = new ArrayList<>();
                for(User u : userList){
                    ids.add(u.getId());
                }
                List<Auth> list = authRepository.findAllByUsers(ids);
                if(ValidateUtil.isValid(list)){
                    List<Auth> authListSave = new ArrayList<>();
                    for(Auth a : list){
                        String authStr = a.getAuth();
                        JSONArray arrSave = new JSONArray();
                        JSONArray arr = JSONArray.fromObject(authStr);
                        if(ValidateUtil.isValid(arr)){
                            for (int i = 0; i < arr.size(); i++) {
                                JSONObject obj = arr.getJSONObject(i);
                                if(authList.contains(obj.getString("id"))){
                                    arrSave.add(obj);
                                }
                            }
                        }
                       a.setAuth(arrSave.toString());
                        authListSave.add(a);
                    }
                    authRepository.save(authSave);
                }
            }
        }
        return save;
    }

    @Override
    public List<User> find(User login) {
        List<Auth> authList = authRepository.findAll();
        Map<Long, String> map = new HashMap<>();
        if(ValidateUtil.isValid(authList)){
            for(Auth a : authList){
                map.put(a.getUser(), a.getAuth());
            }
        }
        List<User> userList = new ArrayList<>();
        List<User> result = new ArrayList<>();
        if(login.getRole().equals(RoleEnum.MANAGER.getKey())) {
            userList = userRepository.findList();
        } else if(RoleTypeEnum.MANAGER.getKey().equals(login.getRoleType())){
            userList = userRepository.findOneDepartment(login.getRole());
        }else{
            userList = findSonsAlive(login.getId());
        }
        if(ValidateUtil.isValid(userList)){
            for(User u : userList){
                if(map.containsKey(u.getId())){
                    u.setAuth(map.get(u.getId()));
                }
                result.add(u);
            }
        }
        return result;
    }

    @Override
    public User delete(User login, Long id) {
        User one = userRepository.findOne(id);
        one.setModifyTime(new Date());
        one.setModifyAccount(login.getId());
        one.setDelFlag(true);
        return userRepository.save(one);
    }

    @Override
    public User enable(User login, Long id) {
        User one = userRepository.findOne(id);
        one.setModifyTime(new Date());
        one.setModifyAccount(login.getId());
        one.setStatus(true);
        return userRepository.save(one);
    }

    @Override
    public User forbiden(User login, Long id) {
        User one = userRepository.findOne(id);
        one.setModifyTime(new Date());
        one.setModifyAccount(login.getId());
        one.setStatus(false);
        return userRepository.save(one);
    }

    @Override
    public User updateName(User login, String name) {
        User one = userRepository.findOne(login.getId());
        one.setName(name);
        one.setModifyTime(new Date());
        one.setModifyAccount(login.getId());
        return userRepository.save(one);
    }

    @Override
    public User updatePwd(User login, String pwd) {
        User one = userRepository.findOne(login.getId());
        one.setPassword(CipherUtil.generatePassword(pwd));
        one.setModifyTime(new Date());
        one.setModifyAccount(login.getId());
        return userRepository.save(one);
    }

    @Override
    public User updatePwd(String email, String pwd) {
        User user = userRepository.login(email);
        user.setPassword(CipherUtil.generatePassword(pwd));
        user.setModifyTime(new Date());
        user.setModifyAccount(user.getId());
        return userRepository.save(user);
    }

    @Override
    public Boolean sendCode(String email) {
        User user = userRepository.login(email);
        if(null == user){
            return false;
        }
        String code = CharacterUtils.getRandomString(4);
        List<String> list = new ArrayList<>();
        list.add(email);
        try {
            MailUtils.sendSimpleEmail("验证码", code,list);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        Code c = new Code();
        c.setCreateTime(new Date());
        c.setCode(code);
        c.setEmail(email);
        codeRepository.save(c);
        return true;
    }

    @Override
    public Boolean validCode(String email, String code, String pwd) {
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.add(Calendar.MINUTE, -5);// 5分钟之前的时间
        Date beforeD = beforeTime.getTime();

        Code valid = codeRepository.findValid(email, beforeD);
        if(null != valid){
            boolean b = valid.getCode().equals(code);
            if(b){
                updatePwd(email, pwd);
                return true;
            }
            return false;
        }
        return false;
    }

    @Override
    public List<User> findbyRole(Long role) {
        List<Auth> authList = authRepository.findAll();
        Map<Long, String> map = new HashMap<>();
        if(ValidateUtil.isValid(authList)){
            for(Auth a : authList){
                map.put(a.getUser(), a.getAuth());
            }
        }

        List<User> result = new ArrayList<>();
        List<User> userList = userRepository.findAllByRole(role);
        if(ValidateUtil.isValid(userList)){
            for(User u : userList){
                if(map.containsKey(u.getId())){
                    u.setAuth(map.get(u.getId()));
                }
                result.add(u);
            }
        }
        return result;
    }

    @Override
    public List<User> findSonsAlive(Long user) {
        List<User> result = new ArrayList<>();
        User one = userRepository.findOne(user);
        if(one.getRole().equals(RoleEnum.MANAGER.getKey())){
            List<User> list = userRepository.findList();
            if(ValidateUtil.isValid(list)){
                result.addAll(list);
            }
        } else if(one.getRoleType().equals(RoleTypeEnum.MANAGER.getKey())){
            List<User> list = userRepository.findAllByRole(one.getRole());
            if(ValidateUtil.isValid(list)){
                result.addAll(list);
            }
        } else{
            List<User> list = userRepository.findAllByParent(user);
            while(ValidateUtil.isValid(list)){
                result.addAll(list);
                List<Long> ids = new ArrayList<>();
                for(User u : list){
                    ids.add(u.getId());
                }
                list = userRepository.findAllByParents(ids);
            }
        }
        return result;
    }

    @Override
    public List<User> findAllSons(Long user) {
        List<User> result = new ArrayList<>();
        User one = userRepository.findOne(user);
        if(one.getRole().equals(RoleEnum.MANAGER.getKey())){
            List<User> list = userRepository.findAll();
            if(ValidateUtil.isValid(list)){
                result.addAll(list);
            }
        } else if(one.getRoleType().equals(RoleTypeEnum.MANAGER.getKey())){
            List<User> list = userRepository.findAllUserByRole(one.getRole());
            if(ValidateUtil.isValid(list)){
                result.addAll(list);
            }
        } else{
            List<User> list = userRepository.findByParent(user);
            while(ValidateUtil.isValid(list)){
                result.addAll(list);
                List<Long> ids = new ArrayList<>();
                for(User u : list){
                    ids.add(u.getId());
                }
                list = userRepository.findByParents(ids);
            }
        }
        return result;
    }


}
