package com.reyun.saas.mob.user.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.reyun.saas.common.constants.RoleEnumType;
import com.reyun.saas.common.core.AbstractService;
import com.reyun.saas.common.framework.component.AwsS3Component;
import com.reyun.saas.common.model.Constant;
import com.reyun.saas.common.model.NoSqlTableName;
import com.reyun.saas.common.restResult.PageParam;
import com.reyun.saas.common.restResult.RestResult;
import com.reyun.saas.common.restResult.ResultCode;
import com.reyun.saas.common.restResult.ResultGenerator;
import com.reyun.saas.mob.async.AsyncTask;
import com.reyun.saas.mob.user.dao.*;
import com.reyun.saas.mob.user.domain.*;
import com.reyun.saas.mob.user.service.AppService;
import com.reyun.saas.mob.user.service.AuthService;
import com.reyun.saas.mob.user.service.NoSqlService;
import com.reyun.saas.mob.util.RoleUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.CRC32;

/**
 * @desc
 * @date
 */
@Slf4j
@Service
@Transactional
public class AppServiceImpl  extends AbstractService<App> implements AppService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private AppMapper appMapper;
    @Autowired
    private AsyncTask asyncTask;
    @Autowired
    private AwsS3Component awsS3Component;

    @Resource
    private ChannelMapper channelMapper;

    @Autowired
    private AuthService authService;

    @Resource
    private UserCoreConfigMapper userCoreConfigMapper;

    @Resource
    private PackageLevelMapper packageLevelMapper;

    @Resource
    private NoSqlService noSqlService;

    @Override
    public RestResult create(App app, Long loginUserId) {
        if(!Constant.OS.contains(app.getOs())){
            return ResultGenerator.genFailResult("系统不存在");
        }

        User user = userMapper.selectByPrimaryKey(loginUserId);
        //校验用户是否可以创建app
        if (!RoleUtil.isSuperUserOrManager(user)) {
            //当前角色不是主账号也不是管理员

            if(RoleEnumType.SUB_APP_MANAGER.getKey().equals(user.getRoleCategory())){
                //子应用管理员
                if(!user.getIsCreateApp()){
                    return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
                }
            }else{
                //其他角色
                return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
            }
        }

        Long rootParent = user.getRootParent()==0?user.getId():user.getRootParent();

        //校验app数量
        // 逻辑: 在user_core_config表中查询主用户的app数量上限 如果app数量为0 去packageLevel套餐表中查询zpp数量
        Example example = new Example(UserCoreConfig.class);
        example.and().andEqualTo("rootParent",rootParent);
        UserCoreConfig userCoreConfig = userCoreConfigMapper.selectOneByExample(example);
        Integer rootUserAppNum = 0;
        if(userCoreConfig.getAppNum().equals(0)){
            PackageLevel packageLevel = packageLevelMapper.selectByPrimaryKey(userCoreConfig.getPackageLevelId());
            rootUserAppNum = packageLevel.getAppNum();
        }else{
            rootUserAppNum = userCoreConfig.getAppNum();
        }
        Integer appCountByUser = authService.getRootUserAppNumByUser(user);
        if (!rootUserAppNum.equals(-1)) {//-1标识app数量无限制
            if (appCountByUser >= rootUserAppNum){
                return ResultGenerator.genResult(ResultCode.APP_NUM_REACH_MAX);
            }
        }

        Example appExample = new Example(App.class);
        appExample.and().andEqualTo("rootParent",rootParent).andEqualTo("os",app.getOs()).andEqualTo("bid", app.getBid()).andEqualTo("delFlag", false);
        PageHelper.startPage(0, 1);
        App bidCheck = appMapper.selectOneByExample(appExample);
        if(bidCheck!=null){
            return ResultGenerator.genFailResult("Bundle Id重复");
        }
        app.setRootParent(rootParent);
        app.setDelFlag(false);
        app.setDisableFlag(false);
        app.setCreateTime(new Date());
        app.setCreateUser(user.getId());
        app.setCreateEmail(user.getUsername());
        appMapper.insert(app);
        asyncTask.getAppIcon(app);
        CRC32 crc32 = new CRC32();
        crc32.update(app.getBid().getBytes());
        String appkey = rootParent+"D"+Long.toHexString(crc32.getValue())+"N"+app.getId()+"A"+Constant.OSMap.get(app.getOs());
        App app1 = new App();
        app1.setId(app.getId());
        app1.setAppkey(appkey);
        appMapper.updateByPrimaryKeySelective(app1);
        app.setAppkey(app1.getAppkey());

        //如果是子应用管理员创建的app 添加appAuth
        if(RoleEnumType.SUB_APP_MANAGER.getKey().equals(user.getRoleCategory())){
            authService.appendAuth(user,app);
        }

        //同步ddb  appkey——oid.os.bid 关系
        noSqlService.putAppInfo(app,user.getOid());

        return ResultGenerator.genSuccessResult(app);
    }

    @Override
    public RestResult list(PageParam pageParam, String query, String os, Long createUser, Long loginUserId) {

        User loginUser = userMapper.selectByPrimaryKey(loginUserId);

        Example example = new Example(App.class);
        Long rootId = RoleEnumType.SUPER_USER.getKey().equals(loginUser.getRoleCategory())?loginUser.getId():loginUser.getRootParent();
        example.and().andEqualTo("rootParent", rootId).andEqualTo("delFlag", false);

        //不是主账号 也不是管理员 根据权限查询对应的app
        if (!RoleUtil.isSuperUserOrManager(loginUser)) {
            List<AppAuth> appAuthByUser = authService.findAppAuthByUser(loginUser);
            if(!CollectionUtils.isEmpty(appAuthByUser)){
                //该用户拥有app权限
                List<Long> ids = appAuthByUser.stream().map(AppAuth::getAppId).collect(Collectors.toList());
                example.and().andIn("id",ids);
            }else{
                //该用户没有app权限
                return ResultGenerator.genSuccessResult();
            }
        }

        if (!StringUtils.isEmpty(query)) {
            example.and()
                    .andLike("appName", "%" + query + "%")
                    .orLike("appkey", "%" + query + "%");
        }
        if (!StringUtils.isEmpty(os)) {
            example.and().andEqualTo("os", os);
        }
        if (createUser != null) {
            example.and().andEqualTo("createUser", createUser);
        }

        PageHelper.startPage(pageParam.getPage(), pageParam.getSize(), pageParam.getOrderBy());

        List<App> apps = appMapper.selectByExample(example);
        for (App app : apps) {
            try {
                if (awsS3Component.doesObjectExist(app.getIconUrl())) {
                    URL url = awsS3Component.generatePresignedUrl(app.getIconUrl(), 30 * 60 * 1000);
                    app.setIconUrl(url.toString());
                }else{
                    app.setIconUrl(null);
                }
            } catch (Exception e) {
                app.setIconUrl(null);
                log.error("App图标获取凭证链接错误", e.getMessage());
            }
        }
        PageInfo<App> pageInfo = new PageInfo<>(apps);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public RestResult disable(Long appId, Boolean flag, Long loginUserId) {

        User user = userMapper.selectByPrimaryKey(loginUserId);

        //校验当前当前用户是否可以操作该App

        if (!authService.checkUserAppAuth(user, appId)) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        App app = new App();
        app.setId(appId);
        app.setDisableFlag(flag);
        app.setModifyTime(new Date());
        app.setModifyUser(loginUserId);
        appMapper.updateByPrimaryKeySelective(app);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public RestResult delete(Long appId, Long loginUserId) {

        User user = userMapper.selectByPrimaryKey(loginUserId);

        //校验当前当前用户是否可以操作该App
        if (!authService.checkUserAppAuth(user, appId)) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        App app = new App();
        app.setId(appId);
        app.setDelFlag(true);
        app.setModifyTime(new Date());
        app.setModifyUser(loginUserId);
        appMapper.updateByPrimaryKeySelective(app);

        //删除该app对应的渠道
        App app1 = appMapper.selectByPrimaryKey(appId);
        channelMapper.deleteChannel(app1.getAppkey(),loginUserId,new Date());

        //删除appAuth表中对应的权限
        authService.deleteAppAuth(appId);

        //同步删除ddb  appkey——oid.os.bid 关系
        noSqlService.deleteIetm(NoSqlTableName.YY_APP_INFO,"appkey",app1.getAppkey());

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public RestResult update(App inputApp, Long loginUserId) {
        User user = userMapper.selectByPrimaryKey(loginUserId);

        //校验当前当前用户是否可以操作该App
        if (!authService.checkUserAppAuth(user, inputApp.getId())) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        App app = new App();
        app.setId(inputApp.getId());
        app.setAppName(inputApp.getAppName());
        app.setModifyTime(new Date());
        app.setModifyUser(loginUserId);
        appMapper.updateByPrimaryKeySelective(app);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public List<Map<String, Object>> findAppsByUser(Long loginUserId, String os) {

        User loginUser = userMapper.selectByPrimaryKey(loginUserId);


        List<Map<String,Object>> appMap = new ArrayList<>();
        //todo app下拉列表权限，如果是主用户查所有的，管理员查自己和下属(另外加user字段)

        Long rootId = RoleEnumType.SUPER_USER.getKey().equals(loginUser.getRoleCategory())?loginUser.getId():loginUser.getRootParent();

        Example example = new Example(App.class);
        example.and().andEqualTo("rootParent",rootId).andEqualTo("delFlag",false).andEqualTo("disableFlag",false);

        //不是主账号 也不是管理员 根据权限查询对应的app
        if (!RoleUtil.isSuperUserOrManager(loginUser)) {
            List<AppAuth> appAuthByUser = authService.findAppAuthByUser(loginUser);

            if(!CollectionUtils.isEmpty(appAuthByUser)){
                List<Long> ids = appAuthByUser.stream().map(AppAuth::getAppId).collect(Collectors.toList());
                example.and().andIn("id",ids);
            }else{
                //用户没有app权限
                return new ArrayList<Map<String, Object>>();
            }
        }

        if(!StringUtils.isEmpty(os)){
            os = os.equals("1")?"iOS":"Android";
            example.and().andEqualTo("os",os);
        }
        List<App> apps = appMapper.selectByExample(example);
        for (App app : apps) {
            Map<String,Object> map = new HashMap<>();
            map.put("appkey",app.getAppkey());
            map.put("appName",app.getAppName());
            appMap.add(map);
        }

        return appMap;
    }

    @Override
    public List<Map<String, Object>> findAppsByCid(Long loginUserId, String cid, String os) {
        os=os.equals("1")?Constant.OS_IOS:Constant.OS_ANDROID;
        User loginUser = userMapper.selectByPrimaryKey(loginUserId);
        List<Map<String, Object>> apps = null;
        if(loginUser.getRoleCategory().equals(RoleEnumType.SUPER_USER.getKey())||loginUser.getRoleCategory().equals(RoleEnumType.MANAGER.getKey())){//主账号或管理员
             apps = appMapper.selectBySuperUser(loginUser.getRealRootParent(),cid,os);
        }else if(loginUser.getRoleCategory().equals(RoleEnumType.SUB_APP_MANAGER.getKey())){//子应用管理员
            List<AppAuth> appAuthByUser = authService.findAppAuthByUser(loginUser);
            StringBuilder stringBuilder = new StringBuilder();
            for (AppAuth appAuth : appAuthByUser) {
                stringBuilder.append(",").append(appAuth.getAppId());
            }
            if(org.springframework.util.StringUtils.isEmpty(stringBuilder.toString())){
                return apps;
            }
            String appIds = stringBuilder.toString().substring(1);
              apps = appMapper.findAppsBySubAppManager(appIds,cid,os);
        }else if(loginUser.getRoleCategory().equals(RoleEnumType.CUSTOM_AUTH.getKey())){//普通账号

        }

        return apps;
    }





}
