package com.ytpm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ytpm.advertise.enums.AppCategoryEnum;
import com.ytpm.advertise.param.AddAppParam;
import com.ytpm.advertise.param.ComprehensiveReportParam;
import com.ytpm.advertise.param.RelativeChannelParam;
import com.ytpm.advertise.view.AddAppResponse;
import com.ytpm.advertise.view.ComprehensiveAppReport;
import com.ytpm.agent.model.YtApp;
import com.ytpm.agent.model.YtAppChannelRelative;
import com.ytpm.agent.model.YtPlatformUserApp;
import com.ytpm.agent.param.AppListParam;
import com.ytpm.agent.param.AppParam;
import com.ytpm.agent.view.AgentAppView;
import com.ytpm.agent.view.AgentEnableAppView;
import com.ytpm.app.model.YtAppDefaultConfig;
import com.ytpm.dao.AgentAppMapper;
import com.ytpm.dao.AppChannelRelativeMapper;
import com.ytpm.dao.AppMapper;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.ResultTable;
import com.ytpm.handle.CustomerException;
import com.ytpm.middle.view.AppListVO;
import com.ytpm.service.AgentAppService;
import com.ytpm.utils.FeignClientInvoker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;


@Service
@Slf4j
public class AgentAppServiceImpl implements AgentAppService {

    @Autowired
    private FeignClientInvoker feignInvoker;
    @Resource
    private AgentAppMapper agentAppMapper;
    @Resource
    private AppMapper appMapper;
    @Resource
    private AppChannelRelativeMapper appChannelRelativeMapper;

    /**
     * 查询渠道启用的应用列表
     */
    @Override
    public ResultTable<AgentEnableAppView> getEnabledList(String userId) {
        return ResultTable.resultTableOk(new PageInfo<>(agentAppMapper.getEnabledList(userId)));
    }


    /**
     * 查询应用列表
     */
    @Override
    public ResultTable<AgentAppView> searchAppList(AppListParam appListParam) {
        PageHelper.startPage(appListParam.getPage(), appListParam.getLimit());
        List<AgentAppView> views = agentAppMapper.searchAppList(appListParam);
        //设置报表数据
        if(CollUtil.isEmpty(views)){
            return ResultTable.resultTableOk(new PageInfo<>(new ArrayList<>()));
        }
        return ResultTable.resultTableOk(new PageInfo<>(views));
    }

    @Override
    public List<AgentAppView> searchAppIdList(AppListParam appListParam) {
        List<AgentAppView> agentAppViews = agentAppMapper.searchAppIdList(appListParam);
        return agentAppViews;
    }

    /**
     * 新增应用
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> saveApp(AppParam param, String userId) {
        //数据库操作，有appId为修改， 没有时为新增
        changeDataAction(param,userId);
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    private void saveDitch(YtApp app) {
        YtApp ytApp = appMapper.selectPrimary(app.getAppId());
        YtPlatformUserApp parent = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        feignInvoker.invoke(parent.getServiceName(), "addDitch",ytApp);
    }

    /**
     * 处理数据库数据变更操作
     */
    private void changeDataAction(AppParam param, String userId) {
        YtApp app = new YtApp();
        BeanUtil.copyProperties(param, app);
        if(CharSequenceUtil.isNotBlank(param.getAppId())){
            appMapper.updateOne(app);
        }else{
            //同一个应用同一个渠道只能出一个包
            YtApp exist = appMapper.getByDitchIdAndSuperiorId(param.getDitchId(),param.getSuperiorId());
            if(Objects.nonNull(exist)){
                throw new CustomerException("该渠道已存在："+exist.getAppName()+", 请选择其他渠道");
            }
            exist = appMapper.getByAppName(param.getAppName());
            if(Objects.nonNull(exist)){
                throw new CustomerException("已存同名应用名称："+exist.getAppName()+", 请重新填写");
            }
            app.setAppId(IdUtil.fastSimpleUUID());
            app.setUserId(userId);
            app.setEnabled(1);
            app.setCreateTime(new Date());
            appMapper.insertOne(app);
            //新增APP时要生成 app_default_config
            generateDefaultConfig(param,app);
            // ios应用同步生成渠道表
            if (param.getAppType() == 2){
                saveDitch(app);
            }
        }
    }

    /**
     * 新增APP时生成 应用的默认配置
     */
    private void generateDefaultConfig(AppParam param, YtApp app) {
        //查询所有app应用
        com.ytpm.middle.param.AppListParam appListParam = new com.ytpm.middle.param.AppListParam();
        appListParam.setPage(1);
        appListParam.setLimit(Integer.MAX_VALUE);
        List<AppListVO> appList = appMapper.getAppList(appListParam);
        //判断当前应用是否存在于列表，取出用来生成app默认配置
        List<AppListVO> vos = appList.stream().filter(s->s.getAppId().equals(param.getSuperiorId())).collect(Collectors.toList());
        if(CollUtil.isEmpty(vos)){
            throw new CustomerException("上架的APP应用包不存在！");
        }
        AppListVO vo = vos.get(0);
        if(CharSequenceUtil.isBlank(vo.getWxSecret())){
            throw new CustomerException("APP应用包未绑定微信开放平台应用，请与ADS管理员联系!");
        }
        //拿到下标值用来组合 appType
        int index = appList.indexOf(vo)+1;
        //判断当前应用的渠道 截取最后5位数
        String ditchId = param.getDitchId().toString();
        String substr = ditchId.substring(ditchId.length() - 5);
        int appType = Integer.parseInt(index + substr);
        //远程调用指定应用保存 应用的出包配置
        YtPlatformUserApp superior = agentAppMapper.selectByPrimaryKey(param.getSuperiorId());
        YtAppDefaultConfig config = new YtAppDefaultConfig(null, param.getAppName(), vo.getWxAppId(), vo.getWxSecret(), app.getAppId(), app.getAppId(), appType,ditchId);
        feignInvoker.invoke(superior.getServiceName(), "saveAppConfig",config);
    }

    /**
     * 删除应用
     */
    @Override
    public Result<?> delApp(String appId, String userId) {
        YtApp ytApp = appMapper.selectPrimary(appId);
        if(Objects.isNull(ytApp)|| !userId.equals(ytApp.getUserId())){
            Result.resultErr(RepMessage.NOT_PERMIT);
        }
        YtPlatformUserApp superior = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        appMapper.deleteApp(appId);
        feignInvoker.invoke(superior.getServiceName(), "delAppConfig",appId);
        return Result.resultOk(RepMessage.DELETE_SUCCESS);
    }

    /**
     * 应用关联广告平台 & 广告平台应用
     */
    @Override
    public Result<?> relativeChannel(RelativeChannelParam param) {
        //根据应用ID查询应用信息
        YtApp ytApp = appMapper.selectPrimary(param.getAppId());
        if(Objects.isNull(ytApp)){
            Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
        }
//        advertiseFeign.relativePlatform(param);
        YtAppChannelRelative ytAppChannelRelative = new YtAppChannelRelative();
        ytAppChannelRelative.setRelativeId(UUID.randomUUID().toString().replace("-",""));
        ytAppChannelRelative.setAppId(param.getAppId());
        ytAppChannelRelative.setChannelId(param.getChannelId());
        ytAppChannelRelative.setChannelName(param.getChannelName());
        ytAppChannelRelative.setNetworkAppId(param.getNetworkAppId());
        appChannelRelativeMapper.insert(ytAppChannelRelative);
        return Result.resultOk(RepMessage.RELATIVE_SUCCESS);
    }

    @Override
    public Result<?> getPrimaryCategories(String platform) {
        List<String> primaryCategories = AppCategoryEnum.getPrimaryCategories(platform);
        return Result.resultObjOk(primaryCategories);
    }

    @Override
    public Result<?> getSecondaryCategories(String platform, String primaryCategory) {
        List<String> secondaryCategories = AppCategoryEnum.getSecondaryCategories(platform, primaryCategory);
        return Result.resultObjOk(secondaryCategories);
    }

    /**
     * 查询加盟商上架应用列表
     */
    @Override
    public ResultTable<YtPlatformUserApp> getIssuedAppList(String userId) {
        return ResultTable.resultTableOk(new PageInfo<YtPlatformUserApp>(agentAppMapper.getIssuedAppList(userId)));
    }

    /**
     * 查询代理商子包ID
     */
    @Override
    public List<String> getApkIdList(String userId) {
        return agentAppMapper.getApkIdList(userId);
    }

    /**
     * 主键查询母包
     */
    @Override
    public YtPlatformUserApp selectByPrimaryKey(String appId) {
        return agentAppMapper.selectByPrimaryKey(appId);
    }

}
