package io.renren.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.renren.common.advert.AdvertPlatformAuthStatusEnum;
import io.renren.common.advert.AdvertPlatformOauthContext;
import io.renren.common.advert.AdvertService;
import io.renren.common.exception.RenException;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.modules.demo.service.RemoteAdvertPort;
import io.renren.modules.demo.service.SaveOrUpdateAdvertAccount;
import io.renren.modules.sys.dao.AdvertOauthDao;
import io.renren.modules.sys.dto.AdvertOauthDTO;
import io.renren.modules.sys.entity.AdvertOauthEntity;
import io.renren.modules.sys.service.AdvertOauthService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * 广告平台授权
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2022-05-30
 */
@Service
public class AdvertOauthServiceImpl extends CrudServiceImpl<AdvertOauthDao, AdvertOauthEntity, AdvertOauthDTO> implements AdvertOauthService {

    @Autowired
    private AdvertPlatformOauthContext advertPlatformOauthContext;
    @Autowired
    private SaveOrUpdateAdvertAccount saveOrUpdateAdvertAccount;
    @Override
    public QueryWrapper<AdvertOauthEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");
        String advertPlatformAccountId = (String)params.get("advertPlatformAccountId");
        String accountName = (String)params.get("accountName");
        String startDate = (String)params.get("startDate");
        String endDate = (String)params.get("endDate");
        String status = (String)params.get("status");

        QueryWrapper<AdvertOauthEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id).isNull("delete_time")
                .eq(StringUtils.isNotBlank(advertPlatformAccountId), "advert_platform_account_id", advertPlatformAccountId)
                .eq(StringUtils.isNotBlank(status), "status", status)
                .like(StringUtils.isNotBlank(accountName), "account_name", "%"+accountName+"%")
                .ge(StringUtils.isNotBlank(startDate), "create_time", startDate)
                .le(StringUtils.isNotBlank(endDate), "create_time", endDate)
                .orderByDesc("id");

        return wrapper;
    }

    @Override
    public String saveOauth(AdvertOauthDTO advertOauth) {
        AdvertOauthEntity advertOauthEntity = new AdvertOauthEntity();
        BeanUtils.copyProperties(advertOauth,advertOauthEntity);

        List<AdvertOauthEntity> advertOauthEntityList = baseDao.selectList(new QueryWrapper<AdvertOauthEntity>().isNull("delete_time").eq("account_name",advertOauth.getAccountName()));
        if(!CollectionUtils.isEmpty(advertOauthEntityList)){
            throw new RenException("账号名称重复");
        }
        List<AdvertOauthEntity> advertPlatformAccountIdList = baseDao.selectList(new QueryWrapper<AdvertOauthEntity>().isNull("delete_time").eq("advert_platform_account_id",advertOauth.getAdvertPlatformAccountId()));
        if(!CollectionUtils.isEmpty(advertPlatformAccountIdList)){
            throw new RenException("广告平台账号id重复");
        }
        advertOauthEntity.setStatus(AdvertPlatformAuthStatusEnum.INIT.name());
        baseDao.insert(advertOauthEntity);
        RemoteAdvertPort remoteAdvertPort = advertPlatformOauthContext.getAdvertOauthPortByAnnotation(AdvertService.SERVICE_OAUTH+advertOauthEntity.getAdvertPlatform());
        String url = remoteAdvertPort.grantOauth(advertOauthEntity.getId());
        return url;
    }

    @Override
    public String updateOauth(AdvertOauthDTO advertOauth) {
        AdvertOauthEntity advertOauthEntity = baseDao.selectById(advertOauth.getId());
        if(advertOauthEntity!=null){

            List<AdvertOauthEntity> advertOauthEntityList = baseDao.selectList(new QueryWrapper<AdvertOauthEntity>().isNull("delete_time").eq("account_name",advertOauth.getAccountName())
                .ne("id",advertOauth.getId()));
            if(!CollectionUtils.isEmpty(advertOauthEntityList)){
                throw new RenException("账号名称重复");
            }
            List<AdvertOauthEntity> advertPlatformAccountIdList = baseDao.selectList(new QueryWrapper<AdvertOauthEntity>().isNull("delete_time").eq("advert_platform_account_id",advertOauth.getAdvertPlatformAccountId())
                    .ne("id",advertOauth.getId()));
            if(!CollectionUtils.isEmpty(advertPlatformAccountIdList)){
                throw new RenException("广告平台账号id重复");
            }
            advertOauthEntity.setAdvertPlatformAccountId(advertOauth.getAdvertPlatformAccountId());
            advertOauthEntity.setAdvertPlatform(advertOauth.getAdvertPlatform());
            advertOauthEntity.setAccountName(advertOauth.getAccountName());
            baseDao.updateById(advertOauthEntity);
            RemoteAdvertPort remoteAdvertPort = advertPlatformOauthContext.getAdvertOauthPortByAnnotation(AdvertService.SERVICE_OAUTH+advertOauthEntity.getAdvertPlatform());
            String url = remoteAdvertPort.grantOauth(advertOauthEntity.getId());
            return url;
        }
        return null;
    }

    public void getToken(Map<String,Object> paramMap) {
        if(paramMap==null || paramMap.get("state")==null){
            throw new RenException("缺少必要参数");
        }
        Long state = Long.parseLong(paramMap.get("state").toString());
        AdvertOauthEntity advertOauthEntity = baseDao.selectById(state);
        RemoteAdvertPort remoteAdvertPort = advertPlatformOauthContext.getAdvertOauthPortByAnnotation(AdvertService.SERVICE_OAUTH+advertOauthEntity.getAdvertPlatform());
        remoteAdvertPort.getToken(paramMap);
    }

    @Override
    public void cancelOauth(AdvertOauthDTO advertOauth) {
        AdvertOauthEntity advertOauthEntity = baseDao.selectById(advertOauth.getId());
        if(advertOauthEntity!=null){
            advertOauthEntity.setAccessToken(null);
            advertOauthEntity.setAccessTokenExpiresIn(null);
            advertOauthEntity.setAccessTokenExpireTime(null);
            advertOauthEntity.setRefreshToken(null);
            advertOauthEntity.setRefreshTokenExpiresIn(null);
            advertOauthEntity.setRefreshTokenExpireTime(null);
            advertOauthEntity.setAuthorizerInfo(null);
            advertOauthEntity.setStatus(AdvertPlatformAuthStatusEnum.INIT.name());
            baseDao.updateById(advertOauthEntity);
            RemoteAdvertPort remoteAdvertPort = advertPlatformOauthContext.getAdvertOauthPortByAnnotation(AdvertService.SERVICE_OAUTH+advertOauthEntity.getAdvertPlatform());
            //获取账户和类型
            Map<String,String> accountTypeMap = remoteAdvertPort.getAccountType(advertOauthEntity.getAccessToken(), advertOauthEntity.getAuthorizerInfo());
            //维护授权账号（取消授权操作）
            saveOrUpdateAdvertAccount.saveAdvertAccountByCancelOath(advertOauthEntity,accountTypeMap);
        }
    }

    /**
     *
     * @param advertOauth
     * @return  返回前端授权访问url地址
     */
    @Override
    public String grantOauth(AdvertOauthDTO advertOauth) {
        AdvertOauthEntity advertOauthEntity = baseDao.selectById(advertOauth.getId());
        RemoteAdvertPort remoteAdvertPort = advertPlatformOauthContext.getAdvertOauthPortByAnnotation(AdvertService.SERVICE_OAUTH+advertOauthEntity.getAdvertPlatform());
        String url = remoteAdvertPort.grantOauth(advertOauthEntity.getId());
        return url;
    }


}