package cn.com.ctop.kuaishou.modules.ai.service.impl;

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.service.ISysRoleExtService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
import cn.com.ctop.common.module.utils.LoadFileUtil;
import cn.com.ctop.common.module.utils.PropertiesUtils;
import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAppPackage;
import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAppPackageRel;
import cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouAppGroupMapper;
import cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouAppPackageMapper;
import cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouAppPackageRelMapper;
import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAppPackageService;
import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouMaterialPoolOperationRecordService;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 项目绑定的应用
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2021-05-12
 */
@Service
public class KuaishouAppPackageServiceImpl extends ServiceImpl<KuaishouAppPackageMapper, KuaishouAppPackage> implements IKuaishouAppPackageService {

    @Autowired
    private KuaishouAppPackageMapper appPackageMapper;
    @Autowired
    private ISysRoleExtService sysRoleService;
    @Autowired
    private KuaishouAppPackageRelMapper relMapper;
    @Autowired
    private IKuaishouMaterialPoolOperationRecordService kuaishouMaterialPoolOperationRecordService;
    @Autowired
    private KuaishouAppGroupMapper appGroupMapper;

    @Autowired
    private ICtopOauthTokenService tokenService;
    @Autowired
    private IKuaiShouMaterialUploadService materialUploadService;
    @Autowired
    private IKuaiShouImageGetService imageGetService;
    @Autowired
    private IKuaiShouMaterialUploadService uploadService;
    @Value("${zip.local.download-path}")
    private String downloadPath;

    @Override
    public Result<Object> importExcel(MultipartFile file, Long projectId, Integer platform, String imageUrl) throws Exception {
        JSONObject returnJson = new JSONObject();
        Workbook workbook = null;
        String fileName = file.getOriginalFilename();
        String substring = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
        if ("XLS".equals(substring)) {
            workbook = new HSSFWorkbook(file.getInputStream());
        } else if ("XLSX".equals(substring)) {
            workbook = new XSSFWorkbook(file.getInputStream());
        } else {
            throw new Exception("文件不是Excel文件");
        }
        Sheet sheet = workbook.getSheet("Sheet1");
        if (Check.isNull(sheet)) {
            throw new Exception("Sheet标题不是默认的Sheet1");
        }
        int rows = sheet.getLastRowNum();// 指的行数，一共有多少行+
        if (rows == 0) {
            throw new Exception("请填写数据");
        }
        String newFileUrl = getDownloadPath(imageUrl);
        if (Check.isNull(newFileUrl)) {
            return Result.error("本地下载文件失败，路径：" + imageUrl);
        }
        String md5 = null;
        try {
            md5 = LoadFileUtil.getMD5(newFileUrl);
        } catch (IOException e) {
            log.error("获取MD5签名失败", e);
        }
        //查询项目下的应用标记（同一账户下应用标记不能重复），在此视为同一项目不可重复
        List<String> appVersions = appPackageMapper.queryAppVersions(projectId);
        StringBuffer errAppVersions = new StringBuffer();
        List<KuaishouAppPackage> appList = new ArrayList<>();
        for (int i = 1; i <= rows + 1; i++) {
            Row row = sheet.getRow(i);
            if (row != null) {
                KuaishouAppPackage appPackage = new KuaishouAppPackage();
                String appName = getCellValue(row.getCell(0));
                String packageName = getCellValue(row.getCell(1));
                String appVersion = getCellValue(row.getCell(2));
                String appPrivacyUrl = getCellValue(row.getCell(3));
                String url = getCellValue(row.getCell(4));
                String trackUrl = getCellValue(row.getCell(5));
                String useSdk = getCellValue(row.getCell(6));
                if ((platform == 1 || platform == 2) && Check.isNull(appPrivacyUrl)) {
                    return Result.error("执行失败，您选择的是安卓类应用，请填写隐私政策链接");
                } else if (Check.isNull(appVersion)) {
                    return Result.error("解析失败，文档中应用标记列缺失数据");
                } else if (platform == 1 && Check.isNull(packageName)) {
                    return Result.error("解析失败，选择Android应用下载时，文档中应用包名列缺失数据");
                } else if (Check.isNull(appName)) {
                    return Result.error("解析失败，文档中应用名称列缺失数据");
                } else if (Check.isNull(url)) {
                    return Result.error("解析失败，文档中下载链接列缺失数据");
                }
                if (appVersions.contains(appVersion)) {
                    errAppVersions.append(appVersion).append("、");
                }
                appPackage.setProjectId(projectId);
                appPackage.setAppName(appName);
                appPackage.setAppVersion(appVersion);
                appPackage.setAppIconUrl(imageUrl);
                appPackage.setPackageName(packageName);
                appPackage.setPlatform(platform);
                appPackage.setImageMd5(md5);
                appPackage.setTrackUrl(trackUrl);
                appPackage.setAppPrivacyUrl(appPrivacyUrl);
                appPackage.setDataStatus(1);//有效
                appPackage.setUrl(url);
                String appmd5 = MD5Util.getMd5(url);
                if (!Check.isNull(appmd5)) {
                    appPackage.setAppMd5(appmd5);
                }
                if (!Check.isNull(useSdk)) {
                    appPackage.setUseSdk(Integer.valueOf(useSdk));
                }
                appList.add(appPackage);
            }
        }
        LoadFileUtil.delFile(newFileUrl);
        String errVersion = errAppVersions.toString();
        if (!Check.isNull(errVersion)) {
            return Result.error("数据异常，重复的应用标记：" + errVersion.substring(0, errVersion.length() - 1));
        }
        appPackageMapper.replaceBatch(appList);
        for (KuaishouAppPackage aPackage : appList) {
            kuaishouMaterialPoolOperationRecordService.addRecord(JSONObject.parseObject(JSONObject.toJSONString(aPackage)).toJavaObject(JSONObject.class), "/importAppExcel", 3, "add");
        }
        return Result.ok("文件导入成功");
    }

    @Override
    public String getDownloadPath(String url) {
        StringBuffer path = new StringBuffer();
        path.append(downloadPath).append(DateUtils.getNowDate(DateUtils.WEB_FORMAT)).append("/").append(UUID.randomUUID().toString()).append("/");
        if (!url.contains("http")) {
            url = "https:".concat(url);
        }
        return LoadFileUtil.downLoadFromUrl(url, path.toString());
    }

    @Override
    public Result<Object> getProjectAppList(Long projectId) {
        List<KuaishouAppPackage> list = appPackageMapper.getProjectAppList(projectId);
        return Result.ok(list);
    }

    @Override
    public Result<Object> getAppsDetail(List<Long> ids) {
        List<JSONObject> list = relMapper.getAppsDetail(ids);
        return Result.ok(list);
    }

    @Override
    public JSONObject queryAppId(Long appTemId, Long accountId) {
        return relMapper.queryAppId(appTemId, accountId);
    }

    private String getCellValue(Cell cell) {
        String value = "";
        if (cell != null) {
            // 以下是判断数据的类型
            switch (cell.getCellType()) {
                case HSSFCell.CELL_TYPE_NUMERIC: // 数字
                    value = cell.getNumericCellValue() + "";
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        if (date != null) {
                            value = new SimpleDateFormat("yyyy-MM-dd").format(date);
                        } else {
                            value = "";
                        }
                    } else {
                        value = new DecimalFormat("0").format(cell.getNumericCellValue());
                    }
                    break;
                case HSSFCell.CELL_TYPE_STRING: // 字符串
                    value = cell.getStringCellValue();
                    break;
                case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
                    value = cell.getBooleanCellValue() + "";
                    break;
                case HSSFCell.CELL_TYPE_FORMULA: // 公式
                    value = cell.getCellFormula() + "";
                    break;
                case HSSFCell.CELL_TYPE_BLANK: // 空值
                    value = "";
                    break;
                case HSSFCell.CELL_TYPE_ERROR: // 故障
                    value = "非法字符";
                    break;
                default:
                    value = "未知类型";
                    break;
            }
        }
        return value.trim();
    }

    @Override
    public Result<Object> pushAppPackage(Long id, JSONArray accountIds, JSONObject object) {
        KuaishouAppPackage appPackage = appPackageMapper.selectById(id);
        if (Check.isNull(appPackage)) {
            return Result.error("未获取到应用信息");
        }
        KuaishouAppPackageRel rel = new KuaishouAppPackageRel();
        rel.setApptemId(appPackage.getId());
        rel.setProjectId(appPackage.getProjectId());
        rel.setAppVersion(appPackage.getAppVersion());
        List<KuaishouAppPackageRel> list = new ArrayList<>();
        for (Object account : accountIds) {
            try {
                Long accountId = Long.valueOf(String.valueOf(account));
                rel.setAccountId(accountId);
                KuaishouAppPackageRel entity = relMapper.queryEntityByAccountId(accountId, appPackage.getAppVersion());
                if (!Check.isNull(entity)) {
                    continue;
                }
                CtopOauthToken oauthToken = tokenService.getTokenByAccountId(accountId);
                JSONObject dataJson = getImageToken(appPackage.getImageMd5(), accountId, oauthToken);
                String imageToken = dataJson.getString("image_token");
                if (Check.isNull(imageToken)) {
                    rel.setMessage(dataJson.getString("message"));
                    rel.setDataStatus(0);
                    list.add(rel);
                    continue;
                }
                JSONObject requestJson = new JSONObject();
                requestJson.put("advertiser_id", accountId);
                requestJson.put("app_version", appPackage.getAppVersion());
                requestJson.put("app_name", appPackage.getAppName());
                requestJson.put("image_token", imageToken);
                requestJson.put("package_name", appPackage.getPackageName());
                requestJson.put("platform", appPackage.getPlatform());
                requestJson.put("url", appPackage.getUrl());
                requestJson.put("use_sdk", appPackage.getUseSdk());
                requestJson.put("app_privacy_url", appPackage.getAppPrivacyUrl());
                String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.APP_CREATE;
                Map<String, String> headerMap = new HashMap<>();
                headerMap.put("Content-Type", "multipart/form-data");
                headerMap.put("Access-Token", oauthToken.getAccessToken());
                String result = materialUploadService.exceptInfoForRestTemplate(url, requestJson, headerMap);
                JSONObject resultJson = JSONObject.parseObject(result);

                if (!Check.isNull(resultJson)) {
                    Integer code = resultJson.getInteger("code");
                    if (code == 0) {
                        JSONObject data = resultJson.getJSONObject("data");
                        rel.setAppId(data.getLong("app_id"));
                        rel.setReturnUrl(data.getString("url"));
                        rel.setMessage(resultJson.getString("message"));
                        rel.setDataStatus(1);
                    } else {
                        rel.setDataStatus(0);
                        rel.setMessage(resultJson.getString("message"));
                    }
                } else {
                    rel.setDataStatus(0);
                    rel.setMessage("上传应用返回结果为空");
                }
            } catch (Exception e) {
                rel.setDataStatus(0);
                rel.setMessage("上传应用异常");
                log.error("上传应用异常,accountId=" + account, e);
            }
            list.add(rel);
        }
        if (!list.isEmpty()) {
            relMapper.replaceBatch(list);
        }
        if (!Check.isNull(object)) {
            object.put("projectId", appPackage.getProjectId());
            kuaishouMaterialPoolOperationRecordService.addRecord(object, "/pushAppPackage", 3, "push");
        }
        return Result.ok("推送完成");
    }

    /**
     * 获取图片token
     */
    @Override
    public JSONObject getImageToken(String md5, Long accountId, CtopOauthToken oauthToken) {
        JSONObject request = new JSONObject();
        if (!Check.isNull(md5)) {
            QueryWrapper<KuaiShouImageGet> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            queryWrapper.eq("signature", md5);
            queryWrapper.last("limit 1");
            KuaiShouImageGet imageGet = imageGetService.getOne(queryWrapper);
            if (!Check.isNull(imageGet)) {
                request.put("image_token", imageGet.getImageToken());
                return request;
            } else {
                String url = appPackageMapper.getUrlByMd5(md5);
                JSONObject resultJson = uploadService.kuauiShouImageUploadOnly(url, md5, accountId, oauthToken.getAccessToken());
                if (resultJson.getInteger("code") == 0) {
                    return resultJson.getJSONObject("data");
                }
                return resultJson;
            }
        }
        return request;
    }

    @Override
    public Result<Object> queryPushResults(String id, JSONArray accountIds, String status) {
        List<JSONObject> lsit = relMapper.queryPushResults(id, accountIds, status);
        return Result.ok(new PageInfo<JSONObject>(lsit));
    }

    @Override
    public List<Long> queryByAppVersion(Long projectId, String appVersion, Integer dataStatus) {
        return appPackageMapper.queryByAppVersion(projectId, appVersion, dataStatus);
    }

    @Override
    public void createAppAndGroupRel(JSONObject request) {
        try {
            appGroupMapper.replaceBatch(request);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("添加广告组和应用绑定关系异常");
        }
    }

    @Override
    public Result<Object> queryPageList(KuaishouAppPackage kuaishouAppPackage, Integer pageNo, Integer pageSize) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = null;
        if (!Check.isNull(user)) {
            userId = user.getId();
            String roleCode = sysRoleService.getRoleCodeByUserId(userId);
            //角色为管理员、销售、媒介可以查看所有项目信息
            if ("admin".equals(roleCode) || roleCode.contains("sale") || "meidaManager".equals(roleCode)) {
                userId = null;
            }
        }
        PageHelper.startPage(pageNo, pageSize);

        List<JSONObject> list = appPackageMapper.queryPageList(userId, kuaishouAppPackage.getAppName(), kuaishouAppPackage.getAppVersion(), kuaishouAppPackage.getProjectId(), kuaishouAppPackage.getPlatform());
        for (JSONObject object : list) {
            object.put("unitCount", appPackageMapper.queryUnitCount(object.getLong("id")));
        }
        return Result.ok(new PageInfo<JSONObject>(list));
    }

    @Override
    public Result<Object> getRelatedAccounts(Long id) {
        JSONObject result = new JSONObject();
        KuaishouAppPackage appPackage = appPackageMapper.selectById(id);
        List<JSONObject> list = relMapper.getRelatedAccounts(id);
        result.put("app", appPackage);
        result.put("page", new PageInfo<>(list));
        return Result.ok(result);
    }

    @Override
    public Result<Object> getRelatedGroups(Long id, Long accountId) {
        JSONObject result = new JSONObject();
        KuaishouAppPackage appPackage = appPackageMapper.selectById(id);
        List<JSONObject> list = appPackageMapper.getRelatedGroups(id, accountId);
        result.put("app", appPackage);
        result.put("page", new PageInfo<>(list));
        return Result.ok(result);
    }

    @Override
    public Result<Object> getAccountByProjectId(Long projectId, String id) {
        List<JSONObject> list = relMapper.getAccountByProjectId(projectId, id);
        return Result.ok(new PageInfo<>(list));
    }


}
