package com.house365.ws.interfaces.rest;

import com.google.common.base.Strings;
import com.house365.beans.entity.BaseAttachment;
import com.house365.beans.entity.DepartmentEntity;
import com.house365.beans.entity.UserEntity;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.IllegalServiceParameterException;
import com.house365.rest.exception.ServiceRunException;
import com.house365.rest.parameter.House365RestObject;
import com.house365.rest.parameter.House365RestResponse;
import com.house365.ws.beans.request.UserListRequest;
import com.house365.ws.beans.response.DepartmentResponse;
import com.house365.ws.beans.response.UserListResponse;
import com.house365.ws.dao.mapper.UserMapper;
import com.house365.ws.interfaces.server.IDepartment;
import com.house365.ws.interfaces.server.IUser;
import com.house365.ws.service.interfaces.IAttachmentService;
import com.house365.ws.service.interfaces.ICustomerStatusLogService;
import com.house365.ws.service.interfaces.IUserService;
import com.house365.ws.system.ReturnAppResult;
import com.house365.ws.util.PathUtil;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("appHgsLogin")
public class AppHgsLoginImpl implements IAppHgsLogin {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppHgsLoginImpl.class);

    public static final String PREFIX = "HGS_";

    @Autowired
    private IUserService userService;

    @Autowired
    private IDepartment department;

    @Autowired
    private ICustomerStatusLogService customerStatusLogService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUser iuser;

    @Autowired
    private IAttachmentService attachmentService;
    @Autowired
    private UserMapper userMapper;

    @Override
    public Object rollback() {
        return null;
    }

    @Override
    public void commit() {

    }

    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        // 取得所需参数
        Map<String, Object> map = parameter.getArgs();
        House365RestResponse<UserEntity> response = new House365RestResponse<>();
        // 业务层统一处理
        try {
            House365RestObject<UserEntity> data = doBusiness(map);
            response.setData(data);
            response.setResult(ReturnAppResult.APP_SUCCESS.getResultCode());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            response.setResult(ReturnAppResult.APP_FAIL.getResultCode());
            response.setMsg((ReturnAppResult.APP_FAIL.getResultMessage() + ":" + e.getMessage()));
            return JSONObject.fromObject(response).toString();
        }
        String result = JSONObject.fromObject(response).toString();
        return result;
    }

    /**
     * 业务层统逻辑处理
     */
    private House365RestObject<UserEntity> doBusiness(Map<String, Object> map) throws Exception {
        // 返回Json对象
        House365RestObject<UserEntity> restObject = new House365RestObject<>();
        String loginName = getMapValueByKey("loginName", map, "");
        String loginPassword = getMapValueByKey("loginPassword", map, "");
        loginPassword = MD5(loginPassword);
        UserListRequest userListRequest = new UserListRequest();
        Map<String, Object> searchMap = new HashMap<>(10);
        searchMap.put("EQ_name", loginName);
        searchMap.put("EQ_password", loginPassword);
        userListRequest.setSearchParams(searchMap);
        UserListResponse userListResponse = iuser.getUserList(userListRequest);
        UserEntity accountEntity = null;
        if (userListResponse != null && !userListResponse.getObjectList().isEmpty()) {
            accountEntity = userListResponse.getObjectList().get(0);
            String phone = accountEntity.getMobile();
            final String cookieKey = PREFIX + "weChat:userInfo:isValid:" + phone;
            LOGGER.error("------------------app登陆key-------:" + cookieKey);
            if (!hasKey(cookieKey)) {
                redisTemplate.execute(new RedisCallback<Object>() {
                    @Override
                    public Object doInRedis(RedisConnection connection) throws DataAccessException {
                        LOGGER.error("====>>addRedis>>:======" + cookieKey + "===success");
                        byte[] serialKey = redisTemplate.getStringSerializer().serialize(cookieKey);
                        connection.del(serialKey);
                        connection.set(serialKey, redisTemplate.getStringSerializer().serialize("1"));
                        connection.expire(serialKey, 86400);
                        return null;
                    }
                });
            }
            //查询在线客服list
            Map<String, Object> queryMap = new HashMap<>(5);
            //测试临时新加部门，上线需要调整
            queryMap.put("deptUrlPath", "/1/2/69/70/567/568");
            queryMap.put("telephone", phone);
            List<UserEntity> userList = userMapper.queryByConditions(queryMap);
            if (CollectionUtils.isNotEmpty(userList)) {
                accountEntity.setIsOpen(1);
            } else {
                accountEntity.setIsOpen(0);
            }
            //带看次数
            int seeCount = customerStatusLogService.getSeeCount(accountEntity.getId());
            //初始带看次数
            int defaultVisit = accountEntity.getDefaultVisit();
            seeCount += defaultVisit;
            accountEntity.setSeeCount(seeCount);
            //城市
            DepartmentResponse departmentResponse = department.getDepartmentById(accountEntity.getDeptId());
            DepartmentEntity dept = departmentResponse.getEntity();
            Integer realDept = PathUtil.extractDept(dept.getUrlPath());
            if (!accountEntity.getDeptId().equals(realDept)) {
                dept = department.getDepartmentById(realDept).getEntity();
            }
            String cityId = dept.getCityID();
            DepartmentResponse departmentResponse2 = department.getDepartmentById(Integer.valueOf(cityId));
            String cityCode = departmentResponse2.getEntity().getDescripition();
            accountEntity.setCity(cityCode);
            UserEntity cityNameEntity = userService.getCityName(cityCode);
            if (cityNameEntity != null) {
                accountEntity.setCityName(cityNameEntity.getCityName());
            }

            //获取头像
            List<BaseAttachment> headImg = attachmentService.queryByResourceIdAndResouceType(String.valueOf(accountEntity.getId()), "hgs_user_headImg");
            if (headImg != null && headImg.size() != 0) {
                accountEntity.setHeadImgURL(headImg.get(0).getRemotePath());
            } else {
                accountEntity.setHeadImgURL("http://img33.house365.com/M00/1B/86/rBEBp1pu2JyAIp4jAAAGEjOUX2M365.jpg");
            }
            //全身像
            List<BaseAttachment> fullImg = attachmentService.queryByResourceIdAndResouceType(String.valueOf(accountEntity.getId()), "hgs_user_fullImg");
            if (fullImg != null && fullImg.size() != 0) {
                accountEntity.setFullImgURL(fullImg.get(0).getRemotePath());
            } else {
                accountEntity.setFullImgURL("http://img31.house365.com/M00/52/5E/rBEBYFpu2HGAb7o1AAAJ0juvDio725.jpg");
            }
        }

        restObject.setEntity(accountEntity);
        return restObject;
    }

    private boolean hasKey(final String key) {
        return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] serialKey = redisTemplate.getStringSerializer().serialize(key);
                return connection.exists(serialKey);
            }
        });
    }

    private static String MD5(String s) {
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取map中的值
     *
     * @param key          key
     * @param map          map
     * @param defaultValue 默认值
     * @return value
     */
    private String getMapValueByKey(String key, Map<String, Object> map, String defaultValue) {
        String value = "";
        if (map.containsKey(key) && map.get(key) != null && !Strings.isNullOrEmpty(((String[]) map.get(key))[0])) {
            value = ((String[]) map.get(key))[0];
        }

        if (Strings.isNullOrEmpty(value)) {
            value = defaultValue;
        }
        return value;
    }

    /**
     * 业务层统校验自己所需参数是否存在
     * 所有参数都要存在
     *
     * @author hqc
     */
    protected void checkInterfaceParameter(Map<String, Object> map, String[] checkParams) throws IllegalServiceParameterException {
        // 方法所需参数
        for (String str : checkParams) {
            // 如果不存在跳出 同时抛出相应异常
            if (!map.containsKey(str)) {
                throw new IllegalServiceParameterException("业务入口参数异常：" + str + "参数为空!");
            }
        }
    }

    @Override
    public boolean isControlService() {
        return false;
    }

    @Override
    public boolean isLogService() {
        return false;
    }

    @Override
    public boolean isMonitorService() {
        return false;
    }


}
