package com.chushang.inspection.terminal.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chushang.common.core.constant.SecurityConstants;
import com.chushang.common.core.web.Result;
import com.chushang.common.excel.utils.ExcelUtils;
import com.chushang.common.mybatis.utils.PageResult;
import com.chushang.datascope.annotation.DataScope;
import com.chushang.inspection.project.po.PollingTask;
import com.chushang.inspection.project.service.PollingTaskService;
import com.chushang.inspection.terminal.po.FiveStore;
import com.chushang.inspection.terminal.po.Store;
import com.chushang.inspection.terminal.query.FiveUnifiedStoreDetailsQuery;
import com.chushang.inspection.terminal.service.FiveStoreService;
import com.chushang.inspection.terminal.service.StoreService;
import com.chushang.inspection.terminal.vo.FiveStoreVO;
import com.chushang.oss.entity.dto.UploadBytesDTO;
import com.chushang.oss.entity.vo.FileSourceVo;
import com.chushang.oss.feign.RemoteOssService;
import com.chushang.security.utils.SecurityUtils;
import com.chushang.task.entity.dto.CreateTaskDTO;
import com.chushang.task.enums.ServiceEnum;
import com.chushang.task.enums.TaskTypeEnum;
import com.chushang.task.feign.RemoteTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chushang.inspection.terminal.mapper.FiveStoreMapper;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 五统一商户 -- 只有建行内蒙古有
  * @auther: zhao
  * @date: 2024/6/21 16:39
  */
@Slf4j
@Service
public class FiveStoreServiceImpl extends ServiceImpl<FiveStoreMapper, FiveStore> implements FiveStoreService {

    @Resource
    PollingTaskService taskService;
    @Resource
    StoreService storeService;
    @Resource
    RemoteTaskService remoteTaskService;
    @Resource
    RemoteOssService ossService;


    /**
     * 需要使用 代码进行补偿
     * s.store_name,
     * pt1.number firstLevelBranchNumber,
     * pt1.`name` firstLevelBranchName,
     *
     * pt2.number secondaryBranchesNumber,
     * pt2.`name` secondaryBranchesName,
     */
    @Override
    public PageResult pageList(FiveUnifiedStoreDetailsQuery query) {
        Page<FiveStoreVO> page = new Page<>(query.getPage(),query.getLimit());
        List<FiveStoreVO> listFiveStores = baseMapper.pageList(query, page);
        convert(listFiveStores);
        return new PageResult(
                listFiveStores,
                page.getTotal(),
                page.getPages(),
                page.getCurrent());
    }

    /**
     * 在此处获取 dataScope
     */
    @Override
    @DataScope(deptAlias = "t")
    public void download(FiveUnifiedStoreDetailsQuery query, HttpServletResponse response) {
        remoteTaskService.createTask(CreateTaskDTO.builder()
                .params(JSON.toJSONString(query))
                .taskName("五统一商户明细导出")
                .applicationName(ServiceEnum.INSPECTION)
                .methodName("export")
                .className(this.getClass().getName())
                .deptId(SecurityUtils.getDeptId())
                .taskType(TaskTypeEnum.DOWN)
                .remark("五统一商户明细导出")
                .createBy(SecurityUtils.getUsername())
                .build(), SecurityConstants.INNER);
    }

    /**
     * todo 使用后台任务时, 可能导致无法获取对应dataScope数据
     * 参考 com.chushang.inspection.project.service.WrkProjectService#projectDataExport
     * @param params
     * @return
     */
    public Result<String> export(String params){
        FiveUnifiedStoreDetailsQuery query = JSON.parseObject(params, FiveUnifiedStoreDetailsQuery.class);
        List<FiveStoreVO> listFiveStores = baseMapper.pageList(query, null);
        convert(listFiveStores);
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            ExcelUtils.exportList(outputStream, FiveStoreVO.class, listFiveStores,  "五统一商户明细");
            // 上传到oss fileStore 是五统一的商户文件
            Result<List<FileSourceVo>> listResult = ossService.uploadBytes(UploadBytesDTO.builder()
                    .bytes(outputStream.toByteArray()).build(), "五统一商户明细导出.xlsx", false, "", "fiveStore", SecurityConstants.INNER);

            if (listResult.isSuccess() && CollectionUtil.isNotEmpty(listResult.getData())){
                List<FileSourceVo> data = listResult.getData();
                FileSourceVo fileSourceVo = data.get(0);
                String filePath = fileSourceVo.getFilePath();
                return Result.ok(filePath);
            }else {
                log.error("生成文件异常, {}, {}", listResult.getCode(), listResult.getMsg());
                return Result.failed(listResult.getCode(), listResult.getMsg());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void convert(List<FiveStoreVO> listFiveStores){
        if (CollectionUtil.isNotEmpty(listFiveStores))
        {
            // firstLevel
            Set<Long> firstLevelBranches = listFiveStores.stream().map(FiveStoreVO::getFirstLevelBranch).collect(Collectors.toSet());
            Set<Long> secondaryBranches = listFiveStores.stream().map(FiveStoreVO::getSecondaryBranch).collect(Collectors.toSet());
            Set<Long> alls = new HashSet<>();
            alls.addAll(firstLevelBranches);
            alls.addAll(secondaryBranches);
            Map<Long, PollingTask> taskMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(alls)){
                List<PollingTask> pollingTasks = taskService.listByIds(alls);
                taskMap = pollingTasks.stream().collect(Collectors.toMap(PollingTask::getId, pollingTask -> pollingTask, (oldValue, newValue) -> newValue));
            }
            Set<Long> storeIds = listFiveStores.stream().map(FiveStoreVO::getStoreId).collect(Collectors.toSet());
            Map<Long, Store> storeMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(storeIds)){
                List<Store> stores = storeService.listByIds(storeIds);
                storeMap = stores.stream().collect(Collectors.toMap(Store::getStoreId, store -> store, (oldValue, newValue) -> newValue));
            }
            for (FiveStoreVO listFiveStore : listFiveStores) {
                Long storeId = listFiveStore.getStoreId();
                Store store = storeMap.get(storeId);
                if (ObjectUtil.isNotEmpty(store)){
                    listFiveStore.setStoreName(store.getStoreName());
                }
                Long firstLevelBranch = listFiveStore.getFirstLevelBranch();
                Long secondaryBranch = listFiveStore.getSecondaryBranch();
                PollingTask firstPollingTask = taskMap.get(firstLevelBranch);
                if (ObjectUtil.isNotEmpty(firstPollingTask)){
                    listFiveStore.setFirstLevelBranchNumber(firstPollingTask.getNumber());
                    listFiveStore.setFirstLevelBranchName(firstPollingTask.getName());
                }
                PollingTask secondPollingTask = taskMap.get(secondaryBranch);
                if (ObjectUtil.isNotEmpty(secondPollingTask)){
                    listFiveStore.setFirstLevelBranchNumber(secondPollingTask.getNumber());
                    listFiveStore.setFirstLevelBranchName(secondPollingTask.getName());
                }
            }
        }
    }

}
