package com.ai.da.service.impl;

import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.TransactionPageResponse;
import com.ai.da.common.response.ResultEnum;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.mapper.primary.*;
import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.Organization;
import com.ai.da.mapper.primary.entity.Questionnaire;
import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.*;
import com.ai.da.model.enums.Language;
import com.ai.da.model.vo.*;
import com.ai.da.service.*;
import com.alibaba.fastjson.JSON;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mysql.cj.util.StringUtils;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import io.minio.http.Method;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ConvenientInquiryServiceImpl extends ServiceImpl<QuestionnaireMapper, Questionnaire> implements ConvenientInquiryService {

    @Resource
    private AccountService accountService;
    @Resource
    private AccountLoginLogService accountLoginLogService;
    @Resource
    private GenerateMapper generateMapper;
    @Resource
    private ToProductImageResultMapper toProductImageResultMapper;
    @Resource
    private DesignService designService;
    @Resource
    private DesignItemService designItemService;
    @Resource
    private ChatRobotService chatRobotService;
    @Resource
    private TrialOrderMapper trialOrderMapper;
    @Resource
    private PaymentInfoMapper paymentInfoMapper;
    @Resource
    private DesignMapper designMapper;

    @Value("${minio.bucketName.users}")
    private String userBucket;

    private static final List<Long> ADMIN_IDS = Arrays.asList(4L, 6L, 31L, 73L, 83L, 87L);
    private static final List<Long> ADMIN_IDS_READ_ONLY = Arrays.asList(12592L, 23534L, 23705L);

    public IPage<TrialOrder> getTrial(QueryUserConditionsVO queryUserConditionsVO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        log.info("getTrial parameter : {},page:{}, size:{}", queryUserConditionsVO, queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize());
        /* 添加按条件查询试用用户 */
        // 按用户邮箱/用户名/用户id查指定用户
        QueryWrapper<TrialOrder> queryWrapper = new QueryWrapper<>();
        if (!Objects.isNull(queryUserConditionsVO.getIds()) && !queryUserConditionsVO.getIds().isEmpty()) {
            queryWrapper.in("id", queryUserConditionsVO.getIds());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getUserName())) {
            queryWrapper.eq("user_name", queryUserConditionsVO.getUserName());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getEmail())) {
            queryWrapper.eq("email", queryUserConditionsVO.getEmail());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getCountry())) {
            queryWrapper.eq("country", queryUserConditionsVO.getCountry());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getOccupation())) {
            queryWrapper.eq("occupation", queryUserConditionsVO.getOccupation());
        }

        // 按时间区间查
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getStartTime())) {
            queryWrapper.gt("create_time", queryUserConditionsVO.getStartTime());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getEndTime())) {
            queryWrapper.lt("create_time", queryUserConditionsVO.getEndTime());
        }

        // 排序
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrder()) && !StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrderBy())) {
            String orderBy = "id";
            if (queryUserConditionsVO.getOrderBy().equals("time")) {
                orderBy = "create_time";
            }
            switch (queryUserConditionsVO.getOrder()) {
                case "Ascending":
                    queryWrapper.orderByAsc(orderBy);
                    break;
                case "Descending":
                    queryWrapper.orderByDesc(orderBy);
                    break;
            }
        }

        // 分页查询
        return trialOrderMapper.selectPage(new Page<>(queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize()), queryWrapper);
//        List<TrialOrder> trialOrders = trialOrderMapper.selectList(null);
    }

    public List<UserDesignStatisticDTO> getDesignStatistic(String startTime, String endTime, List<Long> ids,
                                                           String email, String organizationName) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (Objects.nonNull(account.getSystemUser())
                && (account.getSystemUser().equals(5)
                || account.getSystemUser().equals(7)
                || ADMIN_IDS.contains(account.getId())
                || ADMIN_IDS_READ_ONLY.contains(account.getId())
        )) {
            if (StringUtil.isNullOrEmpty(startTime)) startTime = "2024-02-01 00:00:00";
            if (StringUtil.isNullOrEmpty(endTime)) {
                // yyyy-MM-dd HH:mm:ss "HH"表示24小时制  "hh"表示12小时制
                endTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            if (!StringUtil.isNullOrEmpty(email)) {
                email = email.trim();
            }
            String role;
            switch (account.getSystemUser()) {
                case 5:
                    role = "corp";
                    break;
                case 7:
                    role = "edu";
                    break;
                case 1:
                    role = "prsn";
                    // 如果时个人版的管理员，允许查看所有人的信息，并可以查看指定组织的design数据
                    account.setOrganizationName(organizationName);
                    break;
                default:
                    throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
            }
            return designMapper.getDesignStatistic(startTime, endTime, ids, email, role, account.getOrganizationName());
        } else {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
    }


    public QuestionnaireFeedbackVO getQuestionnaireInfo() {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        String title = "AiDA_3.0 Feedback Survey--06/2024";
        List<Questionnaire> questionnaires = queryByTitle(title);
        List<Integer> ageValue = new ArrayList<>(Collections.nCopies(4, 0));
        List<Integer> question1Value = new ArrayList<>(Collections.nCopies(12, 0));
        List<Integer> question2Value = new ArrayList<>(Collections.nCopies(11, 0));
        List<Integer> question3Value = new ArrayList<>(Collections.nCopies(2, 0));
        List<String> question4Value = new ArrayList<>();
        ArrayList<String> othersReason1 = new ArrayList<>();
        ArrayList<String> othersReason2 = new ArrayList<>();
        ArrayList<String> othersReason3 = new ArrayList<>();

        for (Questionnaire questionnaire : questionnaires) {
            QuestionnaireVO questionnaireVO = JSON.parseObject(questionnaire.getQuestionnaireInfo(), QuestionnaireVO.class);
            // 统计年龄区间
            String age = questionnaireVO.getAge();
            if (age.contains("20-30")) {
                Integer num = ageValue.get(1);
                ageValue.set(1, ++num);
            } else if (age.contains("30-40")) {
                Integer num = ageValue.get(2);
                ageValue.set(2, ++num);
            } else if (age.contains("40+")) {
                Integer num = ageValue.get(3);
                ageValue.set(3, ++num);
            } else {
                Integer num = ageValue.get(0);
                ageValue.set(0, ++num);
            }

            // How has AiDA been helpful to you? 统计
            List<String> helpful = questionnaireVO.getHelpful();
            helpful.forEach(item -> {
                if (item.matches("\\d+")) {
                    Integer num = question1Value.get(Integer.parseInt(item) - 1);
                    question1Value.set(Integer.parseInt(item) - 1, ++num);
                } else {
                    Integer num = question1Value.get(11);
                    question1Value.set(11, ++num);
                    othersReason1.add(item);
                }
            });

            // What do you think AiDA should improve? 统计
            List<String> improve = questionnaireVO.getImprove();
            improve.forEach(item -> {
                if (item.matches("\\d+")) {
                    Integer num = question2Value.get(Integer.parseInt(item) - 1);
                    question2Value.set(Integer.parseInt(item) - 1, ++num);
                } else {
                    Integer num = question2Value.get(10);
                    question2Value.set(10, ++num);
                    othersReason2.add(item);
                }
            });

            // Will you subscribe to AiDA 3.0?
            String isSubscribe = questionnaireVO.getIsSubscribe();
            if (isSubscribe.equals("yes")) {
                Integer num = question3Value.get(0);
                question3Value.set(0, ++num);
            } else {
                Integer num = question3Value.get(1);
                question3Value.set(1, ++num);
                othersReason3.add(String.join(",", questionnaireVO.getReasonForNotSubscribe()));
            }
            if (!StringUtil.isNullOrEmpty(questionnaireVO.getDesignTools())) {
                question4Value.add(questionnaireVO.getDesignTools());
            }
        }

        String language = UserContext.getUserHolder().getLanguage();
        List<String> ageName;
        List<String> question1Name;
        List<String> question2Name;
        if (language.equals("English")) {
            ageName = CommonConstant.AGES_EN;
            question1Name = CommonConstant.IF_HELPFUL_EN;
            question2Name = CommonConstant.IF_IMPROVE_EN;
        } else {
            ageName = CommonConstant.AGES_CN;
            question1Name = CommonConstant.IF_HELPFUL_CN;
            question2Name = CommonConstant.IF_IMPROVE_CN;
        }
        return new QuestionnaireFeedbackVO(
                new QuestionnaireFeedbackVO.Info(ageName, ageValue),
                new QuestionnaireFeedbackVO.Info(question1Name, question1Value, othersReason1),
                new QuestionnaireFeedbackVO.Info(question2Name, question2Value, othersReason2),
                new QuestionnaireFeedbackVO.Info(CommonConstant.IS_SUBSCRIBE, question3Value, othersReason3),
                question4Value
        );
    }

    private List<Questionnaire> queryByTitle(String title) {
        QueryWrapper<Questionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title", title);
        return baseMapper.selectList(queryWrapper);
    }

    public List<QuestionnaireVO> getAllQuestionnaire() {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        String title = "AiDA_3.0 Feedback Survey--06/2024";
        List<Questionnaire> questionnaires = queryByTitle(title);
        ArrayList<QuestionnaireVO> questionnaireVOS = new ArrayList<>();

        questionnaires.forEach(item -> {
                    QuestionnaireVO questionnaireVO = JSON.parseObject(item.getQuestionnaireInfo(), QuestionnaireVO.class);
                    questionnaireVOS.add(questionnaireVO);
                }
        );

        return questionnaireVOS;
    }

    /**
     * 近期新增用户
     */
    public IPage<Account> recentNewUser(QueryUserConditionsVO queryUserConditionsVO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        log.info("recentActiveUser parameter : {}, page:{}, size:{}", queryUserConditionsVO, queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize());
        if (StringUtil.isNullOrEmpty(queryUserConditionsVO.getStartTime()) && StringUtil.isNullOrEmpty(queryUserConditionsVO.getEndTime())) {
            return null;
        }
        if (!StringUtil.isNullOrEmpty(queryUserConditionsVO.getStartTime()) && StringUtil.isNullOrEmpty(queryUserConditionsVO.getEndTime())) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            queryUserConditionsVO.setEndTime(LocalDateTime.now().format(formatter));
        }
        Integer type = null;
        if (!Objects.isNull(queryUserConditionsVO.getSystemUser())) {
            type = queryUserConditionsVO.getSystemUser();
        }

        return accountService.getPageByDateAndUserType(queryUserConditionsVO.getStartTime(),
                queryUserConditionsVO.getEndTime(),
                type,
                queryUserConditionsVO.getPage(),
                queryUserConditionsVO.getSize());
    }

    // 图表数据
    public Map<String, Object> recentNewUserChart(String startTime, String endTime, Integer userType) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        log.info("recentNewUserChart startTime : {},endTime : {},userType:{}", startTime, endTime, userType);
        if (StringUtil.isNullOrEmpty(startTime) && StringUtil.isNullOrEmpty(endTime)) {
            return null;
        }
        if (!StringUtil.isNullOrEmpty(startTime) && StringUtil.isNullOrEmpty(endTime)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            endTime = LocalDateTime.now().format(formatter);
        }

        Map<String, Long> countMap = accountService.getByDateAndUserType(startTime, endTime, userType);
        long type1 = countMap.get("1") == null ? 0L : countMap.get("1");
        long type2 = countMap.get("2") == null ? 0L : countMap.get("2");
        long type3 = countMap.get("3") == null ? 0L : countMap.get("3");
        long type4 = countMap.get("4") == null ? 0L : countMap.get("4");
        List<String> names = Arrays.asList("Visitor", "Trials", "Official");
        List<Long> values = Arrays.asList(countMap.get("0") == null ? 0L : countMap.get("0"),
                type3 + type4,
                type1 + type2);

        HashMap<String, Object> resp = new HashMap<>();
        resp.put("names", names);
        resp.put("values", values);

        return resp;
    }

    // 近期活跃用户
    public IPage<Account> recentActiveUser(QueryUserConditionsVO queryUserConditionsVO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        log.info("recentActiveUser parameter : {}, page:{}, size:{}", queryUserConditionsVO, queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize());
        if (!StringUtil.isNullOrEmpty(queryUserConditionsVO.getStartTime()) && StringUtil.isNullOrEmpty(queryUserConditionsVO.getEndTime())) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            queryUserConditionsVO.setEndTime(LocalDateTime.now().format(formatter));
        }
        List<Long> accountIds = accountLoginLogService.getByDate(queryUserConditionsVO.getStartTime(), queryUserConditionsVO.getEndTime());
        return accountService.getPageByIds(accountIds, queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize());
    }

    // 图表数据
    public int recentActiveUserChart(String startTime, String endTime) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        if (!StringUtil.isNullOrEmpty(startTime) && StringUtil.isNullOrEmpty(endTime)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            endTime = LocalDateTime.now().format(formatter);
        }
        List<Long> accountIds = accountLoginLogService.getByDate(startTime, endTime);
        return accountIds.size();
    }

    public Map<String, List<Object>> getActiveUserFunc(String startTime, String endTime, List<Long> ids) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (Objects.isNull(account.getSystemUser())
                || (account.getSystemUser() != 5
                && account.getSystemUser() != 7
                && !ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId()))) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }

        if ((ids == null || ids.isEmpty()) && (account.getSystemUser() == 5 || account.getSystemUser() == 7)) {
            QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(Account::getParentId, accountId).eq(Account::getOrganizationName, account.getOrganizationName());
            List<Account> accounts = accountMapper.selectList(queryWrapper);
            ids = (accounts != null) ?
                    accounts.stream()
                            .map(Account::getId)
                            .collect(Collectors.toList()) :
                    new ArrayList<>();
        }

        log.info("getActiveUserFunc ==> startTime:{}, endTime:{}, accountList:{}", startTime, endTime, ids);
        // 必须指定时间区间
        if (StringUtil.isNullOrEmpty(startTime) && StringUtil.isNullOrEmpty(endTime)) {
            return null;
        } else if (!StringUtil.isNullOrEmpty(startTime) && StringUtil.isNullOrEmpty(endTime)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            endTime = LocalDateTime.now().format(formatter);
        }

        // design
        Long designTimes = designService.getCountByUserAndTime(startTime, endTime, ids);

        // single design
        Long singleDesignTimes = designItemService.getCountByUserAndTime(startTime, endTime, ids);

        // generate -> MoodBoard\PrintBoard\SketchBoard
//        List<Map<String, Object>> countGenerate = generateService.getCountByUserAndTime(startTime, endTime, ids);
        List<Map<String, Object>> countGenerate = generateMapper.getByTypeAndTime(startTime, endTime, ids);
        // 使用Stream API和lambda表达式将数据合并到一个Map中
        Map<String, Long> countGenerateMerge = countGenerate.stream()
                .collect(Collectors.toMap(
                        map -> (String) map.get("type"),
                        map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count")));

        // toProductImage\ReLight
        List<Map<String, Object>> countProduct = toProductImageResultMapper.getByTypeAndTime(startTime, endTime, ids);
        Map<String, Long> countProductMerge = countProduct.stream()
                .collect(Collectors.toMap(
                        map -> (String) map.get("type"),
                        map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count")));

        // chatRobot
        Long chatTimes = chatRobotService.getCountByUserAndTime(startTime, endTime, ids);

        List<Object> names = Arrays.asList("Design", "SingleDesign", "MoodBoard", "PrintBoard", "SketchBoard", "Pattern", "Logo", "Slogan", "ToProductImage", "Relight", "ChatRobot");
        List<Object> values = Arrays.asList(designTimes, singleDesignTimes,
                countGenerateMerge.get("Moodboard") == null ? 0L : countGenerateMerge.get("Moodboard"),
                countGenerateMerge.get("Printboard") == null ? 0L : countGenerateMerge.get("Printboard"),
                countGenerateMerge.get("Sketchboard") == null ? 0L : countGenerateMerge.get("Sketchboard"),
                countGenerateMerge.get("Pattern") == null ? 0L : countGenerateMerge.get("Pattern"),
                countGenerateMerge.get("Logo") == null ? 0L : countGenerateMerge.get("Logo"),
                countGenerateMerge.get("Slogan") == null ? 0L : countGenerateMerge.get("Slogan"),
                countProductMerge.get("ToProductImage") == null ? 0L : countProductMerge.get("ToProductImage"),
                countProductMerge.get("Relight") == null ? 0L : countProductMerge.get("Relight"),
                chatTimes);

        HashMap<String, List<Object>> resp = new HashMap<>();
        resp.put("names", names);
        resp.put("values", values);

        return resp;
    }

    // 试用用户到正式用户的转化率
    public Map<String, Object> conversionRate(String startTime, String endTime) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        QueryWrapper<TrialOrder> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isNullOrEmpty(startTime)) {
            queryWrapper.gt("create_time", startTime);
        }
        if (!StringUtils.isNullOrEmpty(endTime)) {
            queryWrapper.lt("create_time", endTime);
        }
        // 获取试用用户总数
        queryWrapper.select("count(distinct email) as count");

        List<Map<String, Object>> trialMaps = trialOrderMapper.selectMaps(queryWrapper);
        Long totalTrials = (Long) trialMaps.get(0).get("count");

        // 获取从试用用户转为正式用户的用户数量
        List<String> paidCustomerEmail = accountService.getPaidCustomerEmail();
        QueryWrapper<TrialOrder> qw = new QueryWrapper<>();
        if (!StringUtils.isNullOrEmpty(startTime)) {
            qw.gt("create_time", startTime);
        }
        if (!StringUtils.isNullOrEmpty(endTime)) {
            qw.lt("create_time", endTime);
        }
        qw.in("email", paidCustomerEmail);
        List<TrialOrder> paidTrialUsers = trialOrderMapper.selectList(qw);

//        Map<String, Long> officialMaps = trialOrderMapper.countOfficialUser();
//        Long trialToOfficial = officialMaps.get("count");

        // 计算转化率
        HashMap<String, Object> resp = new HashMap<>();
        resp.put("trialUserCount", totalTrials.floatValue());
        resp.put("trialToOfficialCount", (float) paidTrialUsers.size());
        resp.put("conversionRate", new BigDecimal(paidTrialUsers.size()).divide(new BigDecimal(totalTrials), 6, RoundingMode.HALF_UP).floatValue());
        resp.put("paidTrialUser", paidTrialUsers);
        return resp;

    }

    // 试用用户地区统计
    public Map<String, List<Object>> trialUserCountry(String startTime, String endTime) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        QueryWrapper<TrialOrder> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isNullOrEmpty(startTime)) {
            queryWrapper.gt("create_time", startTime);
        }
        if (!StringUtils.isNullOrEmpty(endTime)) {
            queryWrapper.lt("create_time", endTime);
        }

        queryWrapper.select("country, count(id) as count")
                .groupBy("country");
        List<Map<String, Object>> countryCount = trialOrderMapper.selectMaps(queryWrapper);

        Map<Object, Object> countryCountMap = countryCount.stream().collect(Collectors.toMap(
                map -> map.get("country") == null ? "Not provided" : map.get("country"),
                map -> map.get("count")
        ));
        HashMap<String, List<Object>> resp = new HashMap<>();
        resp.put("names", new ArrayList<>(countryCountMap.keySet()));
        resp.put("values", new ArrayList<>(countryCountMap.values()));

        return resp;
    }

    // 新增用户
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUser(AccountAddDTO accountAddDTO) {
        if (Objects.isNull(accountAddDTO.getSystemUser())) {
            throw new BusinessException("Please choose an user type.");
        }
        // 如果是学校或者企业身份，组织名不能为空
        if (Arrays.asList(5, 6, 7, 8).contains(accountAddDTO.getSystemUser())
                && StringUtil.isNullOrEmpty(accountAddDTO.getOrganizationName())) {
            throw new BusinessException("The organization name cannot be empty.");
        }

        // 需要给的数据 用户邮箱、用户名、账号有效期截止时间、账号类型
        Account account = CopyUtil.copyObject(accountAddDTO, Account.class);
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_email", account.getUserEmail());

        Account existsAccount = accountMapper.selectOne(queryWrapper);
        if (!Objects.isNull(existsAccount)) {
            throw new BusinessException("The email address already exists. One email address can only register one AiDA account");
        }

        // 添加正式用户或企业/教育版的管理员
        if (Objects.isNull(accountAddDTO.getSystemUser())) {
            throw new BusinessException("you have to choose user type");
        } else {
            switch (accountAddDTO.getSystemUser()) {
                case 0:
                    account.setCredits(new BigDecimal(0));
                    account.setIsTrial(0);
                    break;
                case 1:
                    account.setCredits(new BigDecimal(CreditsEventsEnum.INIT_YEARLY.getValue()));
                    account.setIsTrial(0);
                    break;
                case 2:
                    account.setCredits(new BigDecimal(CreditsEventsEnum.INIT_MONTHLY.getValue()));
                    account.setIsTrial(0);
                    break;
                case 3:
                    account.setCredits(new BigDecimal(CreditsEventsEnum.INIT_TRIAL.getValue()));
                    account.setIsTrial(1);
                    break;
                case 5:
                    account.setCreditsUsageLimit(BigDecimal.ZERO);
                    account.setCredits(BigDecimal.ZERO);
                    account.setCreditsUsage(BigDecimal.ZERO);
                    account.setSystemUser(5);
                    account.setSubAccountNum(0);
                    break;
                case 7:
                    account.setCreditsUsageLimit(BigDecimal.ZERO);
                    account.setCredits(BigDecimal.ZERO);
                    account.setCreditsUsage(BigDecimal.ZERO);
                    account.setSystemUser(7);
                    account.setSubAccountNum(0);
                    break;
            }
        }

        if (Objects.nonNull(accountAddDTO.getCredits())) {
            account.setCredits(accountAddDTO.getCredits());
            account.setCreditsUsage(BigDecimal.ZERO);
            account.setCreditsUsageLimit(accountAddDTO.getCredits());
        }
        if (Objects.nonNull(accountAddDTO.getSubAccountNum())) {
            account.setSubAccountNum(accountAddDTO.getSubAccountNum());
        }
        if (!StringUtil.isNullOrEmpty(accountAddDTO.getOrganizationName())) {
            checkAndSetOrganization(accountAddDTO, account);
        }
        account.setValidStartTime(Long.parseLong(accountAddDTO.getValidStartTime()));
        account.setValidEndTime(Long.parseLong(accountAddDTO.getValidEndTime()));
        account.setUserPassword("Third-000000");
        account.setLanguage(Language.ENGLISH.name());
        account.setCreateDate(new Date());
        account.setIsBeginner(1);

        log.info("管理员：{}，添加用户账号：{}", UserContext.getUserHolder().getUsername(), accountAddDTO.getUserEmail());
        return accountService.save(account);
    }

    private void checkAndSetOrganization(AccountAddDTO accountAddDTO, Account account){
        Organization organization = checkOrganization(accountAddDTO.getSystemUser(), accountAddDTO.getOrganizationName());
        if (Objects.nonNull(organization)){
            account.setOrganizationId(organization.getId());
        } else {
            String type = accountService.getOrganizationTypeByRole(account.getSystemUser());
            organization = addOrganization(accountAddDTO.getOrganizationName(), type);
            account.setOrganizationName(accountAddDTO.getOrganizationName());
            account.setOrganizationId(organization.getId());
        }
    }

    public Organization checkOrganization(Integer systemUser, String organizationName){
        String type ;
        switch (systemUser){
            case 5:
                type = "Enterprise";
                break;
            case 7:
                type = "Education";
                break;
            default:
                return null;
        }
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Organization::getType, type).eq(Organization::getName, organizationName);

        return organizationMapper.selectOne(queryWrapper);
    }


    // 修改用户信息
    public Boolean modifyUser(Long accountId, Long validEndTime, Integer systemUser, Long credits) {
        log.info("modifyUser ==> accountId:{}, validEndTime:{}, systemUser:{}, systemUser:{}", accountId, validEndTime, systemUser, credits);
        if (Objects.isNull(accountId) && Objects.isNull(validEndTime) && Objects.isNull(systemUser) && Objects.isNull(credits)) {
            return null;
        } else if (Objects.isNull(accountId)) {
            throw new BusinessException("you have to choose a user");
        }

        String username = UserContext.getUserHolder().getUsername();
        Account account = new Account();
        // 修改用户有效期截止日期、用户类型、积分
        if (!Objects.isNull(validEndTime)) {
            account.setValidEndTime(validEndTime);
            log.info("管理员：{}，修改用户 {} 信息，将账号到期时间置为：{}", username, accountId, validEndTime);
        }
        if (!Objects.isNull(systemUser)) {
            account.setSystemUser(systemUser);
            log.info("管理员：{}，修改用户 {} 信息，将账号身份置为：{}", username, accountId, systemUser);
        }
        /*if (!StringUtils.isNullOrEmpty(systemUser)) {
            int systemUser = 0;
            switch (systemUser) {
                case "yearly":
                    systemUser = 1;
                    break;
                case "monthly":
                    systemUser = 2;
                    break;
                case "trial":
                    systemUser = 3;
                    break;
                case "visitor":
                    systemUser = 0;
                    break;
            }
            account.setSystemUser(systemUser);
        }*/
        if (!Objects.isNull(credits)) {
            account.setCredits(new BigDecimal(credits));
            log.info("管理员：{}，修改用户 {} 信息，将账号积分置为：{}", username, accountId, credits);
        }

        // todo 如果修改管理员账号的积分上限或子账号数量，则其所有子账号的积分上限需要重新计算
        account.setId(accountId);
        account.setUpdateDate(new Date());
        return accountMapper.updateById(account) == 1;
//         accountService.update(account,null);
    }

    @Resource
    private AccountMapper accountMapper;

    // 按条件查询用户信息
    public IPage<Account> getUserInfo(QueryUserConditionsVO queryUserConditionsVO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        log.info("getUserInfo parameter : {},page:{}, size:{}", queryUserConditionsVO, queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize());
        // 按用户邮箱/用户名/用户id查指定用户
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        if (!Objects.isNull(queryUserConditionsVO.getIds()) && !queryUserConditionsVO.getIds().isEmpty()) {
            queryWrapper.in("id", queryUserConditionsVO.getIds());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getUserName())) {
            queryWrapper.eq("user_name", queryUserConditionsVO.getUserName());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getEmail())) {
            queryWrapper.eq("user_email", queryUserConditionsVO.getEmail());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getCountry())) {
            queryWrapper.eq("country", queryUserConditionsVO.getCountry());
        }
        if (!Objects.isNull(queryUserConditionsVO.getSystemUser())) {
            queryWrapper.eq("system_user", queryUserConditionsVO.getSystemUser());
        }

        // 按时间区间查
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getStartTime())) {
            queryWrapper.gt("create_date", queryUserConditionsVO.getStartTime());
        }
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getEndTime())) {
            queryWrapper.lt("create_date", queryUserConditionsVO.getEndTime());
        }

        // 排序
        if (!StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrder()) && !StringUtils.isNullOrEmpty(queryUserConditionsVO.getOrderBy())) {
            String orderBy = "id";
            switch (queryUserConditionsVO.getOrderBy()) {
                case "time":
                    orderBy = "create_date";
                    break;
                case "credits":
                    orderBy = "credits";
                    break;
            }
            switch (queryUserConditionsVO.getOrder()) {
                case "Ascending":
                    queryWrapper.orderByAsc(orderBy);
                    break;
                case "Descending":
                    queryWrapper.orderByDesc(orderBy);
                    break;
            }
        }
        // 分页查询
        return accountMapper.selectPage(new Page<>(queryUserConditionsVO.getPage(), queryUserConditionsVO.getSize()), queryWrapper);
    }

    public List<Map<String, Object>> getAllUserIdList() {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountMapper.selectById(accountId);
        // 允许查看数据的用户id
        if (Objects.nonNull(account.getSystemUser())
                && (account.getSystemUser().equals(5)
                || account.getSystemUser().equals(7)
                || ADMIN_IDS.contains(account.getId())
                || ADMIN_IDS_READ_ONLY.contains(account.getId())
        )) {
            QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id as value, user_name as label");
            if ((account.getSystemUser().equals(7) || account.getSystemUser().equals(5))
                    && !StringUtil.isNullOrEmpty(account.getOrganizationName())) {
                queryWrapper.lambda().eq(Account::getOrganizationName, account.getOrganizationName());
            }
            return accountMapper.selectMaps(queryWrapper);
        } else {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
//        return maps.stream().map(map -> (Long)map.get("id")).collect(Collectors.toList());
    }

    /**
     * 查询交易记录
     * 允许按日期，支付方式，支付金额，商品种类，交易状态，付款人的国家或城市查询，需要分页查询
     */
    public PageBaseResponse<PaymentInfoVO> queryTransactionRecords(QueryPaymentInfoDTO queryPaymentInfoDTO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        Integer size = queryPaymentInfoDTO.getSize();
        int offset = (queryPaymentInfoDTO.getPage() - 1) * size;
        String order = "DESC";
        if (!StringUtil.isNullOrEmpty(queryPaymentInfoDTO.getOrder()) && queryPaymentInfoDTO.getOrder().equals("ASC")) {
            order = "ASC";
        }
        List<PaymentInfoVO> paymentInfoVOS = paymentInfoMapper.queryPaymentInfo(queryPaymentInfoDTO.getPlatform(), queryPaymentInfoDTO.getPayerTotal(),
                queryPaymentInfoDTO.getType(), queryPaymentInfoDTO.getStatus(),
                queryPaymentInfoDTO.getCountry(), queryPaymentInfoDTO.getCity(),
                queryPaymentInfoDTO.getStartTime(), queryPaymentInfoDTO.getEndTime(),
                size, offset, order, queryPaymentInfoDTO.getPayer());
        // 查询数据总量
        Long total = paymentInfoMapper.queryPaymentInfoCount(queryPaymentInfoDTO.getPlatform(), queryPaymentInfoDTO.getPayerTotal(),
                queryPaymentInfoDTO.getType(), queryPaymentInfoDTO.getStatus(),
                queryPaymentInfoDTO.getCountry(), queryPaymentInfoDTO.getCity(),
                queryPaymentInfoDTO.getStartTime(), queryPaymentInfoDTO.getEndTime(), queryPaymentInfoDTO.getPayer());
        // 查询符合查询条件的总金额
        BigDecimal payerTotal = paymentInfoMapper.queryTotalPaymentAmount(queryPaymentInfoDTO.getPlatform(), queryPaymentInfoDTO.getPayerTotal(),
                queryPaymentInfoDTO.getType(), queryPaymentInfoDTO.getStatus(),
                queryPaymentInfoDTO.getCountry(), queryPaymentInfoDTO.getCity(),
                queryPaymentInfoDTO.getStartTime(), queryPaymentInfoDTO.getEndTime(), queryPaymentInfoDTO.getPayer());
        // 总页数
        double totalPage = Math.ceil((double) total / size);
        // 组装返回参数
        TransactionPageResponse<PaymentInfoVO> response = new TransactionPageResponse<>();
        response.setContent(paymentInfoVOS);
        response.setPage(queryPaymentInfoDTO.getPage());
        response.setSize(size);
        response.setTotal(total);
        response.setPages((long) totalPage);
        response.setTotalAmount(Objects.isNull(payerTotal) ? BigDecimal.ZERO : payerTotal);
        return response;
    }

    public Map<String, List<String>> getCities() {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())
                && !ADMIN_IDS_READ_ONLY.contains(account.getId())
        ) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        List<Map<String, String>> cities = paymentInfoMapper.getCities();
        List<Map<String, String>> countries = paymentInfoMapper.getCountries();
        List<String> cityCollect = cities.stream()
                .map(cityEntry -> cityEntry.get("city"))
                .collect(Collectors.toList());
        List<String> countryCollect = countries.stream()
                .map(cityEntry -> cityEntry.get("country"))
                .collect(Collectors.toList());

        return new HashMap<String, List<String>>() {{
            put("city", cityCollect);
            put("country", countryCollect);
        }};
    }

    public String exportTransactionRecords(QueryPaymentInfoDTO queryPaymentInfoDTO, HttpServletResponse response) {
//        QueryPaymentInfoDTO queryPaymentInfoDTO = JSONObject.parseObject(params, QueryPaymentInfoDTO.class);

        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }
        // 查询数据总量
        Long total = paymentInfoMapper.queryPaymentInfoCount(queryPaymentInfoDTO.getPlatform(), queryPaymentInfoDTO.getPayerTotal(),
                queryPaymentInfoDTO.getType(), queryPaymentInfoDTO.getStatus(),
                queryPaymentInfoDTO.getCountry(), queryPaymentInfoDTO.getCity(),
                queryPaymentInfoDTO.getStartTime(), queryPaymentInfoDTO.getEndTime(), queryPaymentInfoDTO.getPayer());
        List<PaymentInfoVO> paymentInfoVOS = paymentInfoMapper.queryPaymentInfo(queryPaymentInfoDTO.getPlatform(), queryPaymentInfoDTO.getPayerTotal(),
                queryPaymentInfoDTO.getType(), queryPaymentInfoDTO.getStatus(),
                queryPaymentInfoDTO.getCountry(), queryPaymentInfoDTO.getCity(),
                queryPaymentInfoDTO.getStartTime(), queryPaymentInfoDTO.getEndTime(),
                total.intValue(), 0, "ASC", queryPaymentInfoDTO.getPayer());
        try {
            return excelExport(paymentInfoVOS, response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Resource
    private MinioClient minioClient;

    public String excelExport(List<PaymentInfoVO> paymentInfoVOS, HttpServletResponse response) throws IOException {
        if (paymentInfoVOS == null || paymentInfoVOS.isEmpty()) {
            log.info("无数据，直接返回，不生成空文件");
            return null;
        }

        // 文件名称
        String time = DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_hh_mm_ss);
        String fileName = "paymentInfo_" + time + ".xlsx";

        // 创建Excel文件
        try (XSSFWorkbook workBook = new XSSFWorkbook()) {
            // 创建Excel工作表（Table）,之后的数据都添加到该表中
            XSSFSheet sheet = workBook.createSheet("数据导出");
            // 设置列宽
            sheet.setDefaultColumnWidth(16);

            // 创建标题行
            XSSFRow titleRow = sheet.createRow(0);
            String[] title = new String[]{"id", "payer", "platform", "payerTotal", "type", "status",
                    "country", "city", "paymentMethod", "last4", "createTime"};
            //设置标题字体样式
            XSSFCellStyle cellStyle = workBook.createCellStyle();
            XSSFFont font = workBook.createFont();
            font.setBold(true);//加粗
            font.setFontHeightInPoints((short) 14);//设置字体大小
            cellStyle.setFont(font);
            //设置标题列
            for (int i = 0; i < title.length; i++) {
                //创建标题的单元格
                XSSFCell titleCell = titleRow.createCell(i);
                //填充标题数值
                titleCell.setCellValue(title[i]);
                //设置样式
                titleCell.setCellStyle(cellStyle);
            }

            // 填充数据
            //第一行是标题所以要从第二行开始
            for (int i = 0; i < paymentInfoVOS.size(); i++) {
                PaymentInfoVO paymentInfoVO = paymentInfoVOS.get(i);
                XSSFRow row = sheet.createRow(i + 1);
                for (int j = 0; j < title.length; j++) {
                    XSSFCell cell = row.createCell(j);
                    String exportKey = title[j];
                    switch (exportKey) {
                        case "id":
                            cell.setCellValue(paymentInfoVO.getId());
                            break;
                        case "payer":
                            cell.setCellValue(paymentInfoVO.getPayer());
                            break;
                        case "platform":
                            cell.setCellValue(paymentInfoVO.getPlatform());
                            break;
                        case "payerTotal":
                            cell.setCellValue(paymentInfoVO.getPayerTotal());
                            break;
                        case "type":
                            cell.setCellValue(paymentInfoVO.getType());
                            break;
                        case "status":
                            cell.setCellValue(paymentInfoVO.getStatus());
                            break;
                        case "country":
                            cell.setCellValue(paymentInfoVO.getCountry());
                            break;
                        case "city":
                            cell.setCellValue(paymentInfoVO.getCity());
                            break;
                        case "paymentMethod":
                            cell.setCellValue(paymentInfoVO.getPaymentMethod());
                            break;
                        case "last4":
                            cell.setCellValue(paymentInfoVO.getLast4());
                            break;
                        case "createTime":
                            cell.setCellValue(paymentInfoVO.getCreateTime());
                            break;
                    }
                }
            }

            // 将workBook转换为字节数组 直接以文件流的形式返回
            /*try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                workBook.write(byteArrayOutputStream);
                byte[] bytes = byteArrayOutputStream.toByteArray();

                // 设置响应头
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));

                // 将字节数组写入响应流
                try (OutputStream responseOut = response.getOutputStream()) {
                    responseOut.write(bytes);
                    responseOut.flush();
                }
            }*/

            String filePath = UserContext.getUserHolder().getId() + "/transactionDownload" + "/" + fileName;
            // 将workBook转换为字节数组
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            workBook.write(byteArrayOutputStream);
            byte[] bytes = byteArrayOutputStream.toByteArray();

            // 上传到 MinIO
            try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
                try {
                    minioClient.putObject(PutObjectArgs.builder()
                            .bucket(userBucket)
                            .object(filePath)
                            .stream(inputStream, bytes.length, -1)
                            .contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                            .build());
                } catch (InvalidKeyException | NoSuchAlgorithmException e) {
                    throw new RuntimeException(e);
                }
            } catch (MinioException e) {
                log.error("文件上传失败: " + e);
                throw new RuntimeException(e);
            }

            // 获取下载链接
            String downloadUrl = null;
            try {
                downloadUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                        .bucket(userBucket)
                        .object(filePath)
                        .method(Method.GET)
                        .expiry(60 * 60 * 24) // 设置链接有效期为24小时
                        .build());
            } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                     InvalidResponseException | NoSuchAlgorithmException | XmlParserException | ServerException e) {
                throw new RuntimeException(e);
            }

            return downloadUrl; // 返回下载链接
        }
    }

    /**
     * 查询generate使用频次
     *
     * @param queryDTO
     * @return
     */
    public PageBaseResponse<AccountCreditsUsageDTO> getGenerateFrequency(AccountCreditsUsageQueryDTO queryDTO) {
        Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (Objects.nonNull(account.getSystemUser())
                && (account.getSystemUser().equals(5)
                || account.getSystemUser().equals(7)
                || ADMIN_IDS.contains(account.getId())
                || ADMIN_IDS_READ_ONLY.contains(account.getId())
        )) {
            boolean groupByEvent = !StringUtil.isNullOrEmpty(queryDTO.getChangeEvent());
            String role;
            switch (account.getSystemUser()) {
                case 5:
                    role = "corp";
                    break;
                case 7:
                    role = "edu";
                    break;
                case 1:
                    role = "prsn";
                    break;
                default:
                    throw new BusinessException("have.no.permission");
            }
            Integer size = queryDTO.getSize();
            int offset = (queryDTO.getPage() - 1) * size;
            List<AccountCreditsUsageDTO> creditsUsageDTOS = accountMapper.selectCreditUsage(
                    groupByEvent, queryDTO.getChangeEvent(), role, queryDTO.getUserEmail(), queryDTO.getId(),
                    queryDTO.getStartTime(), queryDTO.getEndTime(), size, offset, account.getOrganizationName());
            if (!creditsUsageDTOS.isEmpty()) {
                int total = accountMapper.countCreditUsage(
                        groupByEvent, queryDTO.getChangeEvent(), role, queryDTO.getUserEmail(), queryDTO.getId(),
                        queryDTO.getStartTime(), queryDTO.getEndTime(), account.getOrganizationName());
                // 总页数
                double totalPage = Math.ceil((double) total / size);
                // 组装返回参数
                PageBaseResponse<AccountCreditsUsageDTO> response = new PageBaseResponse<>();
                response.setContent(creditsUsageDTOS);
                response.setPage(queryDTO.getPage());
                response.setSize(size);
                response.setTotal(total);
                response.setPages((long) totalPage);
                return response;
            } else {
                return new PageBaseResponse<>();
            }
        } else {
            throw new BusinessException("have.no.permission");
        }
    }

    public List<String> getAllGenerateFuncName() {
        return CreditsEventsEnum.generateFunctionNames();
    }

    @Resource
    private OrganizationMapper organizationMapper;

    public Organization addOrganization(String name, String type) {
        // 用户登录时没有携带token,故无法获取用户信息
        /*Long accountId = UserContext.getUserHolder().getId();
        Account account = accountService.getById(accountId);
        // 允许查看数据的用户id
        if (!ADMIN_IDS.contains(account.getId())) {
            throw new BusinessException("have.no.permission", ResultEnum.PROMPT.getCode());
        }*/
        Organization organization = new Organization();
        organization.setName(name);
        organization.setType(type);
        organization.setCategoryType("root");
        organization.setStatus(1);
        organization.setCreateTime(LocalDateTime.now());
        organizationMapper.insert(organization);
        return organization;
    }

    public IPage<Organization> queryOrganization(QueryOrganizationPageDTO queryDTO) {
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        // 按时间区间查
        if (!StringUtils.isNullOrEmpty(queryDTO.getStartTime())) {
            queryWrapper.lambda().gt(Organization::getCreateTime, queryDTO.getStartTime());
        }
        if (!StringUtils.isNullOrEmpty(queryDTO.getEndTime())) {
            queryWrapper.lambda().lt(Organization::getCreateTime, queryDTO.getEndTime());
        }
        if (Objects.nonNull(queryDTO.getId())){
            queryWrapper.lambda().eq(Organization::getId, queryDTO.getId());
        }
        // 按类型查
        if (!StringUtil.isNullOrEmpty(queryDTO.getType())){
            if (!queryDTO.getType().equals("Enterprise") && !queryDTO.getType().equals("Education")) {
                throw new BusinessException("Unknown type");
            }
            queryWrapper.lambda().eq(Organization::getType, queryDTO.getType());
        }
        // 按机构名查
        if (!StringUtil.isNullOrEmpty(queryDTO.getName())){
            queryWrapper.lambda().like(Organization::getName, queryDTO.getName());
        }

        return organizationMapper.selectPage(new Page<>(queryDTO.getPage(), queryDTO.getSize()), queryWrapper);
    }

}
