package com.house365.ws.interfaces.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.house365.beans.entity.CmDictionaryEntity;
import com.house365.beans.entity.CmUserEntity;
import com.house365.beans.entity.ExportLogEntity;
import com.house365.beans.system.Page;
import com.house365.beans.system.QueryParams;
import com.house365.commons.system.HttpClientUtil;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.ServiceRunException;
import com.house365.web.util.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.beans.request.CmUserListRequest;
import com.house365.ws.beans.request.CmUserRequest;
import com.house365.ws.beans.response.CmUserListResponse;
import com.house365.ws.beans.response.CmUserResponse;
import com.house365.ws.dao.mapper.CmUserMapper;
import com.house365.ws.dao.mapper.ExportLogMapper;
import com.house365.ws.interfaces.server.ICmUser;
import com.house365.ws.service.interfaces.ICmDictionaryService;
import com.house365.ws.service.interfaces.ICmUserService;
import com.house365.ws.system.ReturnResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * CmUserWS接口<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2015-08-10
 * @see
 * @since 1.0
 */
@Service("cmUser")
public class CmUserImpl implements ICmUser {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(CmUserImpl.class);

    /**
     * CmUser服务对象
     */
    @Autowired
    private ICmUserService<CmUserEntity> cmUserService;

    @Autowired
    private ICmDictionaryService cmDictionary;

    @Autowired
    private CmUserMapper cmUserMapper;

    @Autowired
    private ExportLogMapper logMapper;

    /**
     * CmUser列表查询
     *
     * @param request CmUser列表查询请求
     * @return CmUser列表查询响应
     */
    @Override
    public CmUserListResponse getCmUserList(CmUserListRequest request) {
        CmUserListResponse response = new CmUserListResponse();
        try {
            QueryParams<CmUserEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            List<CmUserEntity> cmUsers = cmUserService.queryByPage(queryParams);
            response.setPaging(queryParams.getPaging());
            response.setObjectList(cmUsers);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 保存CmUser
     *
     * @param request CmUser请求
     * @return 保存CmUser响应
     */
    @Override
    public CmUserResponse addCmUser(CmUserRequest request) {
        CmUserResponse response = new CmUserResponse();
        try {
            CmUserEntity entity = request.getEntity();
            cmUserService.save(entity);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 删除CmUser通过唯一标识
     *
     * @param id 唯一标识
     * @return 删除CmUser响应
     */
    @Override
    public CmUserResponse deleteCmUserById(Integer id) {
        CmUserResponse response = new CmUserResponse();
        try {
            cmUserService.delete(id);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 修改CmUser
     *
     * @param request 修改CmUser请求
     * @return 修改CmUser响应
     */
    @Override
    public CmUserResponse updateCmUser(CmUserRequest request) {
        CmUserResponse response = new CmUserResponse();
        try {
            cmUserService.update(request.getEntity());
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 通过ID获取CmUser
     *
     * @param id 唯一标识
     * @return 通过ID获取CmUser响应
     */
    @Override
    public CmUserResponse getCmUserById(Integer id) {
        CmUserResponse response = new CmUserResponse();
        try {
            CmUserEntity entity = cmUserService.getById(id);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }


    @Override
    public Integer countAllCreditsNotNull() {
        return cmUserService.countAllCreditsNotNull();
    }

    @Override
    public Integer countAllRemainingCredits() {
        return cmUserService.countAllRemainingCredits();
    }

    @Override
    public void signRemind() {
        logger.info("run task [signRemind]");
        int size = 950;
        String env = MemoryPropertyPlaceholderConfigurer.getContextProperty("system.env");
        String url = MemoryPropertyPlaceholderConfigurer.getContextProperty("singremind.url." + env);
        Calendar yesterday = Calendar.getInstance();
        yesterday.set(Calendar.HOUR_OF_DAY, 23);
        yesterday.set(Calendar.MINUTE, 59);
        yesterday.set(Calendar.SECOND, 59);
        yesterday.set(Calendar.MILLISECOND, 0);
        yesterday.add(Calendar.DAY_OF_MONTH, -1);

        Calendar threeDaysAgo = Calendar.getInstance();
        threeDaysAgo.set(Calendar.HOUR_OF_DAY, 0);
        threeDaysAgo.set(Calendar.MINUTE, 0);
        threeDaysAgo.set(Calendar.SECOND, 0);
        threeDaysAgo.set(Calendar.MILLISECOND, 0);
        threeDaysAgo.add(Calendar.DAY_OF_MONTH, -5);

        QueryParams queryParams = new QueryParams();
        Map<String, Object> queryMap = new HashMap<>(5);
        queryMap.put("LTE_lastSignTimeEnd", yesterday.getTime());
        queryMap.put("GTE_lastSignTimeBegin", threeDaysAgo.getTime());
        queryParams.setSearchParams(queryMap);

        String alert = "";
        CmDictionaryEntity dictionaryEntity = (CmDictionaryEntity) cmDictionary.getById(1);
        if (dictionaryEntity != null && !Strings.isNullOrEmpty(dictionaryEntity.getDicValue())) {
            alert = dictionaryEntity.getDicValue();
            alert = alert.replaceAll(" ", "");
            if (Strings.isNullOrEmpty(alert)) {
                logger.warn("push content is empty !!!");
                return;
            }
        } else {
            logger.warn("No push content defined !!!");
        }

        int count = cmUserService.getTotalCount(queryParams);
        logger.info("signRemind total user is :{}", count);
        if (count > size) {
            int times = count / size;
            int left = count % size;

            if (left > 0) {
                times += 1;
            }

            for (int i = 0; i < times; i++) {
                Page page = new Page(size);
                page.setCurrentPage(i + 1);
                queryParams.setPaging(page);
                callURL(url, queryParams, alert);
            }

        } else {
            if (count > 0) {
                Page page = new Page(count);
                page.setCurrentPage(0);
                queryParams.setPaging(page);
                callURL(url, queryParams, alert);
            }
        }

        HttpClientUtil.get(
                "http://jfsc.house365.com/house365-cm-web/rest/interface/?serviceCode=Cm&serviceName=GetSignedCredits&cityKey=1&userId=1827137&userCityKey=nj&useridType=1",
                null);
    }

    /**
     * 通过手机号获取CmUser
     *
     * @param phone 用户手机号
     * @return 通过手机号获取CmUser响应
     */
    @Override
    public CmUserResponse getUserByPhone(String phone) {
        CmUserResponse response = new CmUserResponse();
        try {
            CmUserEntity entity = cmUserService.getUserEntity(phone);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 查询事业部榜单
     *
     * @param request
     * @return
     */
    @Override
    public CmUserListResponse selectRanksByDivision(CmUserListRequest request) {
        CmUserListResponse response = new CmUserListResponse();
        try {
            String type = request.getSearchParams().get("type").toString();
            if (StringUtils.isBlank(type)) {
                return response;
            }
            String startTime = null;
            String endTime = null;
            CmDictionaryEntity dictionaryEntity = (CmDictionaryEntity) cmDictionary.getById(3);
            if (type.equals("1")) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(DateTimeUtils.getDateByString(DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd 23:59:59")));
                //当天0点
                endTime = DateTimeUtils.parseDate(calendar.getTime(), "yyyy-MM-dd 00:00:00");
                //季度开始时间
                if (DateTimeUtils.parseDate(dictionaryEntity.getDicValue(), "yyyy-MM-dd HH:mm:ss").after(DateTimeUtils.getCurrentQuarterStartTime())) {
                    //项目开始时间
                    startTime = dictionaryEntity.getDicValue();
                } else {
                    startTime = DateTimeUtils.parseDate(DateTimeUtils.getCurrentQuarterStartTime(), "yyyy-MM-dd 00:00:00");
                }
            } else if (type.equals("2")) {
                //当天0点
                endTime = DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd 00:00:00");
                //项目开始时间
                startTime = dictionaryEntity.getDicValue();
            }

            List<CmUserEntity> cmUsers = cmUserService.selectRanksByDivision(startTime, endTime);
            response.setObjectList(cmUsers);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 查询个人榜单
     *
     * @param request
     * @return
     */
    @Override
    public CmUserListResponse selectRanksByInvite(CmUserListRequest request) {
        CmUserListResponse response = new CmUserListResponse();
        try {
            String type = request.getSearchParams().get("type").toString();
            if (StringUtils.isBlank(type)) {
                return response;
            }
            String startTime = null;
            String endTime = null;
            CmDictionaryEntity dictionaryEntity = (CmDictionaryEntity) cmDictionary.getById(3);
            if (type.equals("3")) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(DateTimeUtils.getDateByString(DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd 23:59:59")));
                //当前时间
                endTime = DateTimeUtils.parseDate(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                //季度开始时间
                if (DateTimeUtils.parseDate(dictionaryEntity.getDicValue(), "yyyy-MM-dd HH:mm:ss").after(DateTimeUtils.getCurrentQuarterStartTime())) {
                    //项目开始时间
                    startTime = dictionaryEntity.getDicValue();
                } else {
                    startTime = DateTimeUtils.parseDate(DateTimeUtils.getCurrentQuarterStartTime(), "yyyy-MM-dd 00:00:00");
                }
            } else if (type.equals("4")) {
                //当前时间
                endTime = DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd HH:mm:ss");
                //项目开始时间
                startTime = dictionaryEntity.getDicValue();
            }
            List<CmUserEntity> cmUsers = cmUserService.selectRanksByInvite(startTime, endTime);
            response.setObjectList(cmUsers);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    /**
     * 查询个人榜单
     *
     * @param request
     * @return
     */
    @Override
    public CmUserResponse getRankByInvite(CmUserListRequest request) {
        CmUserResponse response = new CmUserResponse();
        try {
            Map<String, Object> paramMap = request.getSearchParams();
            String type = paramMap.get("type").toString();
            Integer userId = Integer.valueOf(paramMap.get("userId").toString());
            if (StringUtils.isBlank(type)) {
                return response;
            }
            String startTime = null;
            String endTime = null;
            CmDictionaryEntity dictionaryEntity = (CmDictionaryEntity) cmDictionary.getById(3);
            if (type.equals("5")) {
                //当前时间
                endTime = DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd HH:mm:ss");
                //季度开始时间
                if (DateTimeUtils.parseDate(dictionaryEntity.getDicValue(), "yyyy-MM-dd HH:mm:ss").after(DateTimeUtils.getCurrentQuarterStartTime())) {
                    //项目开始时间
                    startTime = dictionaryEntity.getDicValue();
                } else {
                    startTime = DateTimeUtils.parseDate(DateTimeUtils.getCurrentQuarterStartTime(), "yyyy-MM-dd 00:00:00");
                }
            } else if (type.equals("6")) {
                //当前时间
                endTime = DateTimeUtils.parseDate(new Date(), "yyyy-MM-dd HH:mm:ss");
                //项目开始时间
                startTime = dictionaryEntity.getDicValue();
            }
            CmUserEntity cmUser = cmUserService.getRankByInvite(userId, startTime, endTime);
            response.setEntity(cmUser);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    private void callURL(String url, QueryParams queryParams, String alert) {
        List<CmUserEntity> userList = cmUserService.queryByPage(queryParams);
        List<String> phoneList = new ArrayList<>();
        if (userList != null && !userList.isEmpty()) {
            try {
                url += ("&extra=" + URLEncoder.encode("{\"TFRouteType\":\"1008\",\"TFRouteParm\":\"\"}", "utf-8"));
            } catch (UnsupportedEncodingException e) {
                logger.error(e.getMessage(), e);
            }
            for (CmUserEntity user : userList) {
                if (!Strings.isNullOrEmpty(user.getPhoneNumber())) {
                    phoneList.add(user.getPhoneNumber());
                }
            }
            String sendUrl = "";
            String result = "";
            //split phone by size ,can't big then 1000
            if (!phoneList.isEmpty()) {
                try {
                    sendUrl = url + "&alert=" + URLEncoder.encode(alert, "utf-8");
                    List<NameValuePair> params = new ArrayList<>();
                    params.add(new BasicNameValuePair("phone", Joiner.on(",").join(phoneList)));
                    result = HttpClientUtil.doPost(sendUrl, params);
                } catch (Exception e) {
                    logger.error("sendUrl is :{}, phones:{}, result:{}", sendUrl, Joiner.on(",").join(phoneList),
                            result);
                    logger.error(e.getMessage(), e);
                }
            } else {
                logger.warn("No user to push !!!");
            }

        } else {
            logger.warn("No user to push !!!");
        }
    }

    @Override
    public CmUserListResponse list(CmUserListRequest request, String startTime, String endTime, String phone) {
        CmUserListResponse response = new CmUserListResponse();
        try {
            Map<String, Object> map = new HashMap<>(10);
            Map<String, Object> searchParams = request.getSearchParams();
            int start = 20 * (request.getPaging().getCurrentPage() - 1);
            String city = searchParams.get("EQ_cityKey").toString();
            map.put("city", city);
            map.put("start", start);
            map.put("limit", 20);
            map.put("order", 1);
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            List<Integer> idList = new ArrayList<>();
            putMap(phone, map, idList);
            int count = 0;
            List<CmUserEntity> list = new ArrayList<>();
            if(map.containsKey("noInviter") && "1".equals(map.get("noInviter").toString())){
                logger.info("该手机号查不到人员" + phone);
            }else {
                list = cmUserMapper.queryReport(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (CmUserEntity entity : list) {
                        int inviteCode = entity.getInviteCode();
                        int id = (inviteCode + 6) / 8;
                        Map<String, Object> searchMap = new HashMap<>(5);
                        searchMap.put("id", id);
                        List<CmUserEntity> userList = cmUserMapper.queryByConditions(searchMap);
                        if (CollectionUtils.isNotEmpty(userList)) {
                            entity.setCity(userList.get(0).getPhoneNumber());
                        }
                        Map<String, Object> queryMap = new HashMap<>(10);
                        queryMap.put("city", city);
                        queryMap.put("inviteCode", inviteCode);
                        queryMap.put("startTime", startTime);
                        queryMap.put("endTime", endTime);
                        List<CmUserEntity> queryList = cmUserMapper.queryReport(queryMap);
                        entity.setInviteCount(queryList.size());
                    }
                }
                map.put("start", -1);
                List<CmUserEntity> countList = cmUserMapper.queryReport(map);
                count = countList.size();
            }
            request.getPaging().setRecords(count);
            response.setPaging(request.getPaging());
            response.setObjectList(list);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception e) {
            logger.error("查询邀请记录一级菜单列表失败", e);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(e.getMessage());
        }
        return response;
    }

    @Override
    public List<Map<String, Object>> queryList(Map<String, Object> map) {
        try {
            String phone = map.get("phone").toString();
            if (StringUtils.isNotBlank(phone)) {
                if (phone.contains(",")) {
                    String[] phones = phone.split(",");
                    List<String> phoneList = Arrays.asList(phones);
                    map.put("phoneList", phoneList);
                } else {
                    map.put("phoneNumber", phone);
                }
            }
            List<Map<String, Object>> list = cmUserMapper.exportList(map);
            if (CollectionUtils.isNotEmpty(list)) {
                for (Map<String, Object> m : list) {
                    Map<String, Object> queryMap = new HashMap<>(10);
                    queryMap.put("city", map.get("city").toString());
                    queryMap.put("inviteCode", m.get("inviteCode").toString());
                    queryMap.put("startTime", map.get("startTime").toString());
                    queryMap.put("endTime", map.get("endTime").toString());
                    int count = cmUserMapper.queryCount(queryMap);
                    m.put("inviteCount", count);
                }
                return list;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("查询导出一级菜单失败", e);
        }
        return Collections.emptyList();
    }

    private void putMap(String phone, Map<String, Object> map, List<Integer> idList) {
        if (StringUtils.isNotBlank(phone)) {
            if (phone.contains(",")) {
                String[] phones = phone.split(",");
                for (String s : phones) {
                    Map<String, Object> queryMap = new HashMap<>(5);
                    queryMap.put("phoneNumber", s);
                    List<CmUserEntity> userList = cmUserMapper.queryByConditions(queryMap);
                    if (CollectionUtils.isNotEmpty(userList)) {
                        idList.add(userList.get(0).getId());
                    }
                }
                if(CollectionUtils.isNotEmpty(idList)){
                    map.put("inviterList", idList);
                }else{
                    map.put("noInviter", 1);
                }
            } else {
                Map<String, Object> queryMap = new HashMap<>(5);
                queryMap.put("phoneNumber", phone);
                List<CmUserEntity> userList = cmUserMapper.queryByConditions(queryMap);
                if (CollectionUtils.isNotEmpty(userList)) {
                    map.put("inviter", userList.get(0).getId());
                }else {
                    map.put("noInviter", 1);
                }
            }
        }
    }

    @Override
    public CmUserListResponse stepList(CmUserListRequest request, int inviteCode, String startTime, String endTime) {
        CmUserListResponse response = new CmUserListResponse();
        try {
            Map<String, Object> map = new HashMap<>(10);
            Map<String, Object> searchParams = request.getSearchParams();
            int start = 20 * (request.getPaging().getCurrentPage() - 1);
            String city = searchParams.get("EQ_cityKey").toString();
            map.put("city", city);
            map.put("start", start);
            map.put("limit", 20);
            map.put("inviteCode", inviteCode);
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            List<CmUserEntity> list = cmUserMapper.queryReport(map);
            response.setPaging(request.getPaging());
            response.setObjectList(list);
            map.put("start", -1);
            List<CmUserEntity> countList = cmUserMapper.queryReport(map);
            int count = countList.size();
            request.getPaging().setRecords(count);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
        } catch (Exception e) {
            logger.error("查询邀请记录二级菜单列表失败", e);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(e.getMessage());
        }
        return response;
    }

    @Override
    public List<CmUserEntity> exportStepList(Map<String, Object> map) {
        List<CmUserEntity> list = cmUserMapper.queryReport(map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public void save(ExportLogEntity logEntity) {
        logMapper.save(logEntity);
    }

    /**
     * 以下均为自动生成
     */

    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        // TODO Auto-generated method stub
        return null;
    }

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

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

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

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

    @Override
    public void commit() {
    }

}
