package com.crm.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.manager.dao.mapper.UserResignMapper;
import com.crm.manager.dao.repository.*;
import com.crm.manager.dto.export.UserResignSearchListExportDto;
import com.crm.manager.property.GooleUserAdminApiProperty;
import com.crm.manager.service.SysConfigService;
import com.crm.manager.service.UserResignService;
import com.crm.rely.backend.core.constant.*;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.user.info.UserResignSearchListDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.entity.user.info.UserResignAddEntity;
import com.crm.rely.backend.core.entity.user.info.UserResignSearchEntity;
import com.crm.rely.backend.core.entity.user.info.UserResignUpdateEntity;
import com.crm.rely.backend.core.pojo.table.*;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.GoogleAdminAPIHttp;
import com.google.common.base.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class UserResignServiceImpl implements UserResignService {

    @Autowired
    private UserResignRepository userResignRepository;
    @Autowired
    private UserResignMapper userResignMapper;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private SalesLeaderExtraRepository salesLeaderExtraRepository;
    @Autowired
    private CustomInfoRepository customInfoRepository;
    @Autowired
    private CustomLoginRepository customLoginRepository;
    @Autowired
    private RedisService redisService;
    @Autowired
    private Environment environment;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(UserResignAddEntity entity) throws Exception {
        UserResignTable resignTable = userResignRepository.getFirstByUserId(entity.getUserId());
        if (resignTable != null) {
            throw ServiceException.exception("user is resigned");
        }

        UserResignTable table = new UserResignTable();
        BeanUtils.copyProperties(entity, table);
        table.setResignStatus(1);
        userResignRepository.save(table);

        UserInfoTable user = userInfoRepository.getFirstById(table.getUserId());
        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.USER_RESIGN_EMAIL);
        if (sysConfigTable == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        this.sendUseResignApplyEmail(sysConfigTable, user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(UserResignUpdateEntity entity) throws Exception {
        UserResignTable resignTable = userResignRepository.getFirstByUserId(entity.getUserId());
        if (resignTable != null && resignTable.getId() != entity.getId()) {
            throw ServiceException.exception("user is resigned");
        }

        UserResignTable table = userResignRepository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        BeanUtils.copyProperties(entity, table);
        userResignRepository.save(table);
    }

    @Override
    public UserResignSearchListDto searchSingle(SingleLongEntity entity) throws ServiceException {
        UserResignTable table = userResignRepository.getFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        UserResignSearchListDto userResignSearchListDto = this.transformSearchListDto(table);
        return userResignSearchListDto;
    }


    @Override
    public ResultWithPagerDto<UserResignSearchListDto> searchPageList(UserResignSearchEntity entity) throws ServiceException {
        Integer count = userResignMapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<UserResignTable> userResignTables = userResignMapper.pageList(entity);

        if (userResignTables == null || userResignTables.size() <= 0) {

            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        List<UserResignSearchListDto> userResignSearchListDtos = new ArrayList<>(userResignTables.size());

        for (UserResignTable userResignTable : userResignTables) {
            UserResignSearchListDto userResignSearchListDto = this.transformSearchListDto(userResignTable);
            userResignSearchListDtos.add(userResignSearchListDto);
        }

        return ResultWithPagerDto.success(pageDto, userResignSearchListDtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveManage(UserResignUpdateEntity entity, HttpServletRequest httpServletRequest) throws Exception {
        if (null == entity.getResignStatus() || null == entity.getId()) {
            throw ServiceException.exception("parameter_error");
        }
        if (2 == entity.getResignStatus() && null == entity.getPid()) {
            throw ServiceException.exception("上级不能为空");
        }

        UserResignTable table = userResignRepository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (2 == table.getResignStatus() || 3 == table.getResignStatus()) {
            throw ServiceException.exception("离职信息已核验");
        }
        table.setResignStatus(entity.getResignStatus());
        table.setPid(entity.getPid());
        userResignRepository.save(table);

        if (2 == table.getResignStatus()) {
            UserInfoTable user = userInfoRepository.findFirstById(table.getUserId());
            user.setPid(entity.getPid());
            user.setValid(0);
            user.setResignDate(new Date());
            userInfoRepository.save(user);

            UserInfoTable pUser = userInfoRepository.getFirstById(table.getPid());

            SalesLeaderExtraTable extraTable = new SalesLeaderExtraTable();
            extraTable.setLeaderSalesNo(pUser.getIbNo());
            extraTable.setSalesNo(user.getIbNo());
            extraTable.setType(2);
            extraTable.setSalesDate(new Date());
            salesLeaderExtraRepository.save(extraTable);

            CustomInfoTable customInfo = customInfoRepository.findFirstByEmail(user.getEmail());
            if (customInfo != null) {
                customInfo.setValid(Constants.MANAGER_PENDING_STATUS);
                customInfoRepository.save(customInfo);

                List<CustomLoginTable> loginList = customLoginRepository.findByCustomId(customInfo.getId());
                if (loginList != null) {

                    for (CustomLoginTable customLoginTable : loginList) {
                        customLoginTable.setValid(Constants.MANAGER_PENDING_STATUS);
                        customLoginTable.setLoginStatus(Constants.MANAGER_PENDING_STATUS);
                    }
                    customLoginRepository.save(loginList);
                }
            }


            for (int i = 0; i < environment.getActiveProfiles().length; i++) {
                if (environment.getActiveProfiles()[i].equals("prod")) {
                    SysConfigTable gogleConfigTable =
                            sysConfigService.getByCode(ConfigConstants.GOOGLE_USER_ADMIN_API_PROPERTY);
                    if (gogleConfigTable == null) {
                        throw ServiceException.exception(Constants.SYSTEM_ERROR);
                    }

                    GooleUserAdminApiProperty property = JSON.parseObject(gogleConfigTable.getValue(),
                            GooleUserAdminApiProperty.class);
                    String accessToken = GoogleAdminAPIHttp.getAccessToken(property.getAdminEmail(),
                            property.getClientEmail(), property.getPrivateKey());

                    Integer resposeCode = GoogleAdminAPIHttp.deleteUser(accessToken, user.getEmail());
//                  if (204 != resposeCode) {
//                      throw ServiceException.exception("delete GoogleEmail is error");
//                  }
                    break;
                }
            }


            SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.USER_RESIGN_EMAIL);
            if (sysConfigTable == null) {
                throw ServiceException.exception(Constants.SYSTEM_ERROR);
            }
            this.sendUseResignVerifyEmail(sysConfigTable, user);

            if (customInfo != null) {
                String webToken =
                        redisService.getObject(PrefixEnum.PREFIX_CUSTOM.getCode() + customInfo.getId() + Constants.LOGIN_LINK + SourceEnum.WEB.getCode());
                if (!Strings.isNullOrEmpty(webToken)) {
                    redisService.remove(webToken);
                }
                String iosToken =
                        redisService.getObject(PrefixEnum.PREFIX_CUSTOM.getCode() + customInfo.getId() + Constants.LOGIN_LINK + SourceEnum.PHONE_IOS.getCode());
                if (!Strings.isNullOrEmpty(iosToken)) {
                    redisService.remove(iosToken);
                }
                String androidToken =
                        redisService.getObject(PrefixEnum.PREFIX_CUSTOM.getCode() + customInfo.getId() + Constants.LOGIN_LINK + SourceEnum.PHONE_ANDROID.getCode());
                if (!Strings.isNullOrEmpty(androidToken)) {
                    redisService.remove(androidToken);
                }
                String adminToken =
                        redisService.getObject(PrefixEnum.PREFIX_CUSTOM.getCode() + customInfo.getId() + Constants.LOGIN_LINK + SourceEnum.WEB_ADMIN.getCode());
                if (!Strings.isNullOrEmpty(adminToken)) {
                    redisService.remove(adminToken);
                }
            }

        }
    }

    @Override
    public List<UserResignSearchListExportDto> searchPageExport(UserResignSearchEntity entity) {
        entity.setPage(null);
        List<UserResignTable> userResignTables = userResignMapper.pageList(entity);

        List<UserResignSearchListExportDto> dtos = new ArrayList<>(userResignTables.size());
        for (UserResignTable userResignTable : userResignTables) {
            UserResignSearchListExportDto dto = new UserResignSearchListExportDto();
            BeanUtils.copyProperties(userResignTable, dto);
            dto.setResignDate(DateUtil.formatDate(userResignTable.getModifyTime()));
            if(1 == userResignTable.getResignStatus()){
                dto.setResignStatus("待审核");
            }else if(2 == userResignTable.getResignStatus()){
                dto.setResignStatus("已通过");
            }else if(3 == userResignTable.getResignStatus()){
                dto.setResignStatus("核验失败");
            }
            dtos.add(dto);
        }
        return dtos;
    }

    private void sendUseResignApplyEmail(SysConfigTable sysConfigTable, UserInfoTable table) throws ServiceException {
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(7);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.EMAIL, table.getEmail());
        map.put(MapConstants.NAME, table.getName());
        map.put(MapConstants.V_SALARY_PLATFORM_V, "BANK_ACCOUNT".equals(table.getSalaryPlatform()) ? "银行账户" :
                table.getSalaryPlatform());
        map.put(MapConstants.V_SALARY_LOGIN_V, String.valueOf(table.getSalaryLogin()));
        map.put(MapConstants.V_IB_NO_V, table.getIbNo());
        map.put(MapConstants.V_ENTRY_DATE_V, null == table.getEntryDate() ? "" :
                DateUtil.formatDate(table.getEntryDate()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG USER RESIGN APPLY");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.USER_RESIGN_APPLY);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.USER_RESIGN_APPLY);
        sysEmailSendEntity.setUsers(sysConfigTable.getValue());

        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendUseResignVerifyEmail(SysConfigTable sysConfigTable, UserInfoTable table) throws ServiceException {
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(7);

        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.EMAIL, table.getEmail());
        map.put(MapConstants.NAME, table.getName());
        map.put(MapConstants.V_SALARY_PLATFORM_V, "BANK_ACCOUNT".equals(table.getSalaryPlatform()) ? "银行账户" :
                table.getSalaryPlatform());
        map.put(MapConstants.V_SALARY_LOGIN_V, String.valueOf(table.getSalaryLogin()));
        map.put(MapConstants.V_IB_NO_V, table.getIbNo());
        map.put(MapConstants.V_ENTRY_DATE_V, null == table.getEntryDate() ? "" :
                DateUtil.formatDate(table.getEntryDate()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG USER RESIGN");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.USER_RESIGN_SUCCESS);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(SystemEmailCodeConstants.USER_RESIGN_SUCCESS);
        sysEmailSendEntity.setUsers(sysConfigTable.getValue());

        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private UserResignSearchListDto transformSearchListDto(UserResignTable userResignTable) {
        UserResignSearchListDto userResignSearchListDto = new UserResignSearchListDto();
        BeanUtils.copyProperties(userResignTable, userResignSearchListDto);
        userResignSearchListDto.setResignDate(DateUtil.formatDate(userResignTable.getModifyTime()));
        return userResignSearchListDto;
    }

}
