package com.platform.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.dao.BrandDao;
import com.platform.entity.*;
import com.platform.service.BrandService;
import com.platform.service.custom.MySysUserBrandService;
import com.platform.service.custom.TmBrandTypeService;
import com.platform.utils.*;
import com.platform.vo.BrandBindUserVo;
import com.platform.vos.CurrentUserLoginVo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Service实现类
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @date 2017-08-19 17:59:15
 */
@Service("brandService")
public class BrandServiceImpl implements BrandService {
    private static Logger log = LoggerFactory.getLogger(BrandServiceImpl.class);

    @Autowired
    private BrandDao brandDao;

    @Autowired
    private ZhiHouseService zhiHouseService;

    @Autowired
    private ControllerUtils controllerUtils;

    @Autowired
    private OssCheckPointUploadUtil ossCheckPointUploadUtil;

    @Autowired
    private TmBrandTypeService tmBrandTypeService;

    @Autowired
    private MySysUserBrandService mySysUserBrandService;


    @Value("${api.host.url}")
    private String apiHostQueryUrl;
    @Value("${api.id}")
    private String appId;

    @Value("${api.secret}")
    private String appSecret;

    @Value("${scenePath}")
    private String scenePath;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public IPage<BrandEntity> queryBrandBindList(Long pageNum, Long pageSize,  String sceneName,String brandName,
                                                 List<Long> deptIdList , Integer type,Long userId,Integer livestreamStatus,String orderBy) {
        QueryWrapper<BrandEntity> queryWrapper = new QueryWrapper<>();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(sceneName)){
            queryWrapper.like("b.name" , sceneName);
        }
        //添加是否绑定的过滤条件
        if(!ObjectUtils.isEmpty(userId)){
            //捞取已经绑定的
            queryWrapper.and(query->query.eq("b.create_user_id",userId).or().eq("u.user_id",userId));
        }
        if(!CollectionUtils.isEmpty(deptIdList)){
            queryWrapper.in("b.create_user_dept_id" , deptIdList);
        }
        if(!ObjectUtils.isEmpty(type)){
            queryWrapper.eq("b.type",type);
        }
        if(!ObjectUtils.isEmpty(livestreamStatus)){
            queryWrapper.eq("b.livestream_status",livestreamStatus);
        }
        queryWrapper.groupBy("b.id");
        //这里投机取巧使用id来代替创建时间来做倒序，历史原因，原来的表没创建时间这个字段
        queryWrapper.orderByAsc("b.sort_order").orderByDesc("b.id");
        IPage<BrandEntity> page = new Page<>(pageNum , pageSize);
        IPage<BrandEntity> resultPage = new Page<>();
        resultPage = brandDao.getBrandBindListWithPage(page , queryWrapper);
        return resultPage;
    }

    @Override
    public BrandEntity queryObject(Integer id) {
        return brandDao.queryObject(id);
    }

    @Override
    public List<BrandEntity> queryList(Map<String, Object> map) {
        return brandDao.queryList(map);
    }


    @Override
    public IPage<BrandEntity> queryBrandList(Long pageNum, Long pageSize, String key) {
        QueryWrapper<BrandEntity> queryWrapper = new QueryWrapper<>();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(key)){
            queryWrapper.like("name" , key);
        }
        queryWrapper.isNotNull("scene_num");
        queryWrapper.orderByDesc("id");
        IPage<BrandEntity> page = new Page<>(pageNum , pageSize);
        IPage<BrandEntity> resultPage = new Page<>();
        resultPage = brandDao.getBrandListWithPage(page , queryWrapper);
        return resultPage;
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return brandDao.queryTotal(map);
    }

    @Override
    public int save(BrandEntity brand,Boolean checkName) {
        BrandEntity brandEntity = brandDao.findByName(brand.getName());
        if(!ObjectUtils.isEmpty(brandEntity)){
            if(ObjectUtils.isEmpty(checkName) || checkName){
                throw new RuntimeException("直播间生成失败，已经存在相同名称直播间");
            }
            brand.setName(brandEntity.getName().concat(DateUtils.format(new Date(),"MMddHHmmss")));
        }
        return brandDao.save(brand);
    }

    @Override
    public Result updateWithoutCheck(BrandEntity brand) {
        brandDao.update(brand);
        return Result.success();
    }

    @Override
    public Result update(BrandEntity brand) {
        BrandEntity brandEntity = brandDao.findByName(brand.getName());
        if(brandEntity != null && brandEntity.getId().intValue() != brand.getId().intValue()){
            return Result.failure("店铺名称重复");
        }
        int update = brandDao.update(brand);
        if(update != 1){
            return Result.failure("更新店铺失败");
        }
        return Result.success();
    }

    @Override
    public int delete(Integer id) {
        return brandDao.delete(id);
    }

    @Override
    public int deleteBatch(Integer[] ids) {
        return brandDao.deleteBatch(ids);
    }

    @Override
    public Integer queryIdByScene(String sceneNum) {
        return brandDao.queryIdByScene(sceneNum);
    }

    @Override
    public BrandEntity queryByScene(String sceneNum) {

        if(StringUtils.isBlank(sceneNum)){
            return null;
        }
        return brandDao.queryByScene(sceneNum);
    }

    @Override
    public List<String> queryAllLiveSceneNum() {
        return brandDao.queryAllLiveSceneNum();

    }

    public String generalWxShareQrCode(BrandEntity brand , boolean needUpdate){
        //生成二维码
        String sqCodePath = ResourceUtil.getConfigByName("h5.wx.mini.program.url.pre");
        String totalUrl = sqCodePath + brand.getId();
        log.info("生成二维码的参数为:{}" , totalUrl);
        String imageFilePath = ResourceUtil.getConfigByName("file-backup-path");
        String viewerWxAppId = ResourceUtil.getConfigByName("wx.appId");
        String viewerWxAppSecret = ResourceUtil.getConfigByName("wx.secret");
        String ossQueryUrl = ResourceUtil.getConfigByName("oss.query.url");
        String ossImagePath = ResourceUtil.getConfigByName("oss.image.file.path");
        //生成带看页面的二维码
        File imagePath = new File(imageFilePath);
        if(!imagePath.exists()){
            imagePath.mkdirs();
        }
        String imageLocalPath = imageFilePath + brand.getSceneNum() + System.currentTimeMillis() + "_QRCode.png";
        log.info("生成二维码的本地缓存路径:{}" , imageLocalPath);
        log.info("生成二维码的appId={},appSecret={}" , viewerWxAppId , viewerWxAppSecret);
        WxOpUtils.getWxQRCode(totalUrl, viewerWxAppId, viewerWxAppSecret, imageLocalPath);
        String ossPath = ossImagePath + brand.getSceneNum() + System.currentTimeMillis() + "_QRCode.png";
        log.info("生成的二维码上传oss的路径:{}" , ossPath);
        ossCheckPointUploadUtil.upload2(imageLocalPath, ossPath);
        String imageTotalOssUrl = ossQueryUrl + ossPath;
        if(needUpdate){
            brand.setShareWxQrCode(imageTotalOssUrl);
            updateWithoutCheck(brand);
        }
        File file = new File(imageLocalPath);
        if (file.exists()) {
            //删除本地缓存的二维码
            file.delete();
        }
        return imageTotalOssUrl;
    }

    public Result sendDataToApi(BrandEntity brandEntity){
        if(null == brandEntity){
            return Result.failure("商家信息为空，无法请求api平台");
        }
        Map<String, Object> reqData = new HashMap<>();
        reqData.put("brandId" , brandEntity.getId());
        reqData.put("brandName" , brandEntity.getName());
        reqData.put("simpleDesc" , brandEntity.getSimpleDesc());
        reqData.put("sortOrder" , brandEntity.getSortOrder());
        reqData.put("isShow" , brandEntity.getLivestreamStatus());
        reqData.put("type" , brandEntity.getType());
        if(null != brandEntity.getType()){
            TmBrandType tmBrandType = tmBrandTypeService.getByBrandType(brandEntity.getType());
            if(null != tmBrandType){
                reqData.put("typeName" , tmBrandType.getName());
            }
        }
        reqData.put("sceneNum" , brandEntity.getSceneNum());
        if(org.apache.commons.lang3.StringUtils.isNotBlank(brandEntity.getSceneNum())){
            String videoData =  getSceneVideoData(brandEntity.getSceneNum());
            log.info("指房宝返回的video data={}" , videoData);
            reqData.put("sceneVideoData" , videoData);
            JSONObject jsonObject = zhiHouseService.queryBySceneNum(brandEntity.getSceneNum(),brandEntity.getToken());
            if(!ObjectUtils.isEmpty(jsonObject)){
                reqData.put("scenenName" , jsonObject.getString("sceneName"));
            }
        }

        reqData.put("shareWxQrCode" , brandEntity.getShareWxQrCode());
        reqData.put("address" , brandEntity.getAddress());
        reqData.put("picList" , brandEntity.getPicList());
        reqData.put("longitude" , brandEntity.getLongitude());
        reqData.put("latitude" , brandEntity.getLatitude());
        reqData.put("introduceVideo" , brandEntity.getIntroduceVideo());
        reqData.put("introduceVideoCover" , brandEntity.getIntroduceVideoCover());
        reqData.put("imageCover" , brandEntity.getAppListPicUrl());
        reqData.put("appId" , appId);
        reqData.put("origin" , ResourceUtil.getConfigByName("origin"));
        log.info("获取到的api平台的app_id={}, app_secret={}" , appId , appSecret);

        Long timeStamp = System.currentTimeMillis();

        //token=app_id+app_secret+timestamp
        String token = SHAUtils.getSHA256(appId + appSecret + timeStamp.toString());

        Map<String , Object> sortMap = controllerUtils.sortMapByKey(reqData);
        String sortMapStr = JSONObject.toJSONString(sortMap);
        log.info("待加密的数据={}" ,sortMapStr + appSecret + timeStamp);
        String sign  = SHAUtils.getSHA256(sortMapStr + appSecret + timeStamp);

        String openApiurl = apiHostQueryUrl + "/api/shop/formatBrand?" + "appId=" + appId + "&sign=" + sign + "&token=" + token + "&timeStamp=" + timeStamp;
        log.info("请求openApi的url={}", openApiurl);
        String apiResultStr = HttpClientUtil.doPostJson(openApiurl , sortMapStr);
        log.info("api平台返回结果:{}" , apiResultStr);
        return Result.success(apiResultStr);

    }

    private String getSceneVideoData(String sceneNum){
        if(org.apache.commons.lang3.StringUtils.isBlank(sceneNum)){
            return null;
        }
        String url = scenePath + "api/scene/getInfo?num=" + sceneNum;
        log.info("请求的url为：{}" ,url);
        JSONObject resObj = null;
        try{
            ResponseEntity<String> resultString = restTemplate.getForEntity(url,String.class);
            log.info("指房宝返回场景详情:{}" , JSON.toJSONString(resultString.getBody()));
            resObj = JSON.parseObject(resultString.getBody() , JSONObject.class);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        if(ObjectUtils.isEmpty(resObj)){
            return "";
        }
        int code = resObj.getInteger("code");
        if(code != 0){
            log.error("调用指房宝失败");
            return "";
        }
        JSONObject data = resObj.getJSONObject("data");
        if(null == data){
            log.error("指房宝返回数据格式异常");
            return "";
        }
        JSONObject videos = data.getJSONObject("videos");
        if(null == videos){
            log.info("指房宝返回videos为空");
        }else{
            JSONArray dataArray = videos.getJSONArray("data");
            if(null != dataArray){
                return dataArray.toJSONString();
            }else{
                log.error("指房宝返回videos中的data数组为空");
            }
        }
        return "";
    }

    @Override
    public BrandEntity generateDefaultLiveRoom(SceneEntity sceneEntity) {
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setName(sceneEntity.getName());
        brandEntity.setSimpleDesc(sceneEntity.getName());
        brandEntity.setSceneNum(sceneEntity.getSceneNum());
        brandEntity.setType(0);
        brandEntity.setAppListPicUrl(sceneEntity.getAppListPicUrl());
        brandEntity.setLivestreamStatus(0);

        CurrentUserLoginVo userEntity = ShiroUtils.getUserEntity();
        brandEntity.setContractPhone(userEntity.getPhone());
        brandEntity.setPicList(sceneEntity.getAppListPicUrl());
        brandEntity.setCreateUserId(userEntity.getId());
        brandEntity.setSortOrder(100);
        if(StringUtils.isNotBlank(sceneEntity.getCompanyId())){
            brandEntity.setCreateUserDeptId(Long.valueOf(sceneEntity.getCompanyId()));
        }
        brandEntity.setAddress("浙江省,杭州市,萧山区 山阴路688号恒隆广场B座1217");
        brandEntity.setLongitude(new BigDecimal(120.262421));
        brandEntity.setLatitude(new BigDecimal(30.178317));
        String liveRoomUrl = sceneEntity.getSceneUrl().replaceAll("smobile.html", "shop.html");
        brandEntity.setLiveRoomUrl(liveRoomUrl);

        save(brandEntity,false);
        //生成微信分享二维码
        generalWxShareQrCode(brandEntity , true);
        brandEntity.setToken(sceneEntity.getToken());
        sendDataToApi(brandEntity);

        return brandEntity;
    }
//{brandId: 1, canShow: 0, type: -1, userId: "1"}
    public void bindUsers(Integer brandId,List<BrandBindUserVo> brandBindUserVoList) {
        List<Long> userIdList = new ArrayList<>();
        if(brandBindUserVoList !=null && brandBindUserVoList.size() >0){
            userIdList = brandBindUserVoList.stream().map(BrandBindUserVo::getUserId).collect(Collectors.toList());
        }

        mySysUserBrandService.unbindUserByBrandId(brandId,userIdList);

        if(brandBindUserVoList !=null && brandBindUserVoList.size() >0){
            for (BrandBindUserVo vo : brandBindUserVoList) {
                bindUser(vo.getUserId(), vo.getBrandId(), vo.getCanShow());
            }
        }

//        brandBindUserVoList.parallelStream().filter(vo -> !ObjectUtils.isEmpty(vo.getType())).forEach(vo -> {
//                    //绑定或者修改带看权限
//                    if (vo.getType().compareTo(1) == 0) {
//                        bindUser(vo.getUserId(), vo.getBrandId(), vo.getCanShow());
//                    } else {
//                        unbindUser(vo.getUserId(), vo.getBrandId());
//                    }
//                }
//        );
    }

    public void bindUser(Long userId,Integer brandId,Integer canShow) {
        SysUserBrand dbUserBrand  = mySysUserBrandService.getUserBrandById(userId,brandId);
        if(ObjectUtils.isEmpty(canShow) || (canShow.compareTo(1) != 0 && canShow.compareTo(0) != 0)){
            log.info("带看权限类型非法");
            return;
        }
        if(null != dbUserBrand){
            if(null != dbUserBrand.getCanShow() && dbUserBrand.getCanShow().compareTo(canShow) == 0){
                log.info("此用户权限已改过，无需重复修改");
                return;
            }
            dbUserBrand.setCanShow(canShow);
            mySysUserBrandService.updateSysUserBrand(dbUserBrand);
        }else{
            //新增绑定关系
            CurrentUserLoginVo userEntity = ShiroUtils.getUserEntity();
            if(null == userEntity){
                log.info("用户不存在");
                return;
            }
            BrandEntity brandEntity = queryObject(brandId);
            if(null == brandEntity){
                log.info("店铺不存在");
                return;
            }
            dbUserBrand = new SysUserBrand();
            dbUserBrand.setBrandId(brandId.longValue());
            dbUserBrand.setUserId(userId);
            dbUserBrand.setCanShow(canShow);
            dbUserBrand.setEnable(1);
            dbUserBrand.setPhoneNum(userEntity.getPhone());
            dbUserBrand.setSceneNum(brandEntity.getSceneNum());
            mySysUserBrandService.addRelation(dbUserBrand);
        }
    }

    public void unbindUser(Long userId,Integer brandId) {
        SysUserBrand dbUserBrand  = mySysUserBrandService.getUserBrandById(userId ,brandId);
        //解绑
        if(ObjectUtils.isEmpty(dbUserBrand)){
            log.info("用户之前未绑定，无需解绑");
            return;
        }
        dbUserBrand.setCanShow(0);
        dbUserBrand.setEnable(0);
        mySysUserBrandService.updateSysUserBrand(dbUserBrand);
    }
}
