package com.caimei.www.service.page.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.caimei.www.mapper.DocumentAuthDao;
import com.caimei.www.pojo.JsonModel;
import com.caimei.www.pojo.document.CookieBuilder;
import com.caimei.www.pojo.document.OssArchive;
import com.caimei.www.pojo.document.OssArchivePdf;
import com.caimei.www.pojo.document.OssAuthorization;
import com.caimei.www.service.page.DocumentAuthService;
import com.caimei.www.service.redis.RedisService;
import com.caimei.www.utils.ImageUtil;
import com.caimei.www.utils.RandomCodeGenerator;
import com.caimei.www.utils.SMSUtils;
import com.caimei.www.utils.VerifyCodeUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description
 *
 * @author : plf
 * @date : 2020/11/10
 */
@Slf4j
@Service
public class DocumentAuthServiceImpl implements DocumentAuthService {
    @Resource
    private DocumentAuthDao documentAuthDao;

    @Resource
    private RedisService redisService;

    @Value("${caimei.wwwDomain}")
    private String domain;

    @Override
    public Boolean getAuthorizationCookie(String authorizationMobile) {
        if (!StringUtils.isEmpty(authorizationMobile)) {
            OssAuthorization ossAuthorization = documentAuthDao.findOssAuthorizationByMobile(authorizationMobile);
            return ossAuthorization != null;
        }
        return false;
    }

    @Override
    public Mono<JsonModel> getImgVerifyCode() {
        Map<String, Object> jsonResult = new HashMap<>(2);
        try {
            VerifyCodeUtils.VerifyCode verifyCode = null;
            String verifyCodeKey = "";
            while (true) {
                verifyCode = VerifyCodeUtils.createVerifyCode(200, 80, 4);
                verifyCodeKey = "www:oss:" + verifyCode.getMd5Code();
                boolean exists = redisService.exists(verifyCodeKey);
                // 不存在，为了防止重复的图片验证码
                if (!exists) {
                    // 保存5分钟
                    redisService.set(verifyCodeKey, verifyCode.getCode(), 5 * 60L);
                    break;
                }
            }
            jsonResult.put("baseImage", verifyCode.getBase64Image());
            jsonResult.put("token", verifyCode.getMd5Code());
            return Mono.just(JsonModel.success(jsonResult));
        } catch (Exception e) {
            return Mono.just(JsonModel.error("验证码获取失败"));
        }
    }

    @Override
    public Mono<JsonModel> ossNote(String mobile, String imgCode, String token) {
        String code = (String) redisService.get("www:oss:" + token);
        String mobileCode = RandomCodeGenerator.generateCodeInt(6);
        //手机验证码,30分钟有效
        redisService.set(mobile + ":mobileCode", mobileCode, 30 * 60L);
        String content = "采美资料库访问授权验证码：" + mobileCode + "，30分钟内有效";
        if (!StringUtils.isEmpty(code) && code.equals(imgCode)) {
            log.info("采美资料库访问授权验证码>>>>>" + mobileCode);
            boolean sms = SMSUtils.sendSms(mobile, content);
            if (sms) {
                return Mono.just(JsonModel.success());
            }
        } else {
            boolean exists = redisService.exists(mobile + ":mobileCode");
            if (exists) {
                redisService.remove(mobile + ":mobileCode");
            }
        }
        return Mono.just(JsonModel.error("验证码不正确"));
    }

    @Override
    public ResponseEntity<JsonModel> mobileCodeLogin(OssAuthorization authorization) {
        HttpHeaders headers = new HttpHeaders();
        if (StringUtils.isEmpty(authorization.getMobile()) || StringUtils.isEmpty(authorization.getCode())) {
            return new ResponseEntity<>(JsonModel.error("参数异常"), headers, HttpStatus.OK);
        }
        String mobileCode = (String) redisService.get(authorization.getMobile() + ":mobileCode");
        if (!StringUtils.isEmpty(mobileCode) && authorization.getCode().equals(mobileCode)) {
            OssAuthorization ossAuthorization = documentAuthDao.findOssAuthorizationByMobile(authorization.getMobile());
            if (ossAuthorization != null) {
                String cookie = new CookieBuilder().setKey("authorizationMobile")
                        .setValue(authorization.getMobile())
                        .setMaxAge(60 * 60 * 24 * 30 * 1000L)
                        .setPath("/")
                        .build();
                headers.add("Set-Cookie", cookie);
                return new ResponseEntity<>(JsonModel.success(), headers, HttpStatus.OK);
            } else {
                return new ResponseEntity<>(JsonModel.error(-2, "登录失败,您可能没有查看资料的权限"), headers, HttpStatus.OK);
            }
        } else {
            return new ResponseEntity<>(JsonModel.error("短信验证码不正确"), headers, HttpStatus.OK);
        }
    }

    @Override
    public Mono<JsonModel> dataList(String name, Integer pageNum, Integer pageSize) {
        pageNum = pageNum == null ? 1 : pageNum;
        pageSize = pageSize == null ? 20 : pageSize;
        PageHelper.startPage(pageNum, pageSize);
        List<OssArchive> ossArchiveList = documentAuthDao.findOssArchive(name);
        PageInfo<OssArchive> pageInfo = null;
        if (ossArchiveList != null && ossArchiveList.size() > 0) {
            for (OssArchive ossArchive : ossArchiveList) {
                if (!StringUtils.isEmpty(ossArchive.getMainImage())) {
                    ossArchive.setMainImage(ImageUtil.getImageURL("product", ossArchive.getMainImage(), 0, domain));
                }
                List<OssArchivePdf> pdfList = documentAuthDao.findOssArchivePdf(ossArchive.getId());
                if (pdfList != null && pdfList.size() > 0) {
                    ossArchive.setIsShowDowns(false);
                } else {
                    ossArchive.setIsShowDowns(true);
                }
                ossArchive.setPdfList(pdfList);
            }
            pageInfo = new PageInfo<>(ossArchiveList);
        }
        return Mono.just(JsonModel.success(pageInfo));
    }

    @Override
    public Mono<JsonModel> dataDetails(Integer pdfId) {
        String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
        String accessKeyId = "LTAI4GBL3o4YkWnbKYgf2Xia";
        String accessKeySecret = "dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK";
        String bucketName = "caimei-oss";
        Map<String, Object> map = new HashMap<>(2);
        OssArchivePdf ossArchivePdf = documentAuthDao.findOssArchivePdfById(pdfId);
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 设置URL过期时间为1个小时
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000);
        String url = ossClient.generatePresignedUrl(bucketName, ossArchivePdf.getOssName(), expiration).toString();
        ossArchivePdf.setUrl(url);
        OssArchive ossArchive = documentAuthDao.getOssArchive(ossArchivePdf.getArchiveId());
        map.put("ossArchivePdf", ossArchivePdf);
        map.put("ossArchive", ossArchive);
        ossClient.shutdown();
        return Mono.just(JsonModel.success(map));
    }

    @Override
    public Mono<JsonModel> moreData(Integer archiveId) {
        OssArchive ossArchive = documentAuthDao.getOssArchive(archiveId);
        if (ossArchive != null) {
            List<OssArchivePdf> pdfList = documentAuthDao.findOssArchivePdf(ossArchive.getId());
            ossArchive.setPdfList(pdfList);
        }
        return Mono.just(JsonModel.success(ossArchive));
    }
}
