package com.ningdatech.carapi.driver.manage;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.carapi.common.contants.DefValConstants;
import com.ningdatech.carapi.common.model.FileBasicInfo;
import com.ningdatech.carapi.driver.constant.MaterialStatusEnum;
import com.ningdatech.carapi.driver.constant.MaterialTypeEnum;
import com.ningdatech.carapi.driver.constants.DriverConstant;
import com.ningdatech.carapi.driver.entity.TrainingMaterial;
import com.ningdatech.carapi.driver.entity.TrainingOrganizationMaterial;
import com.ningdatech.carapi.driver.model.po.ReqSaveTrainingMaterialPO;
import com.ningdatech.carapi.driver.model.po.ReqTrainingMaterialListPO;
import com.ningdatech.carapi.driver.model.vo.ResSaveTrainingMaterialVO;
import com.ningdatech.carapi.driver.model.vo.ResTrainingMaterialListVO;
import com.ningdatech.carapi.driver.model.vo.ResTrainingMaterialVO;
import com.ningdatech.carapi.driver.service.ITrainingMaterialService;
import com.ningdatech.carapi.driver.service.ITrainingOrganizationMaterialService;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import lombok.RequiredArgsConstructor;

/**
 * @author liuxinxin
 * @date 2022/10/9 下午3:32
 */
@Component
@RequiredArgsConstructor
public class TrainingMaterialManage {

    private final ITrainingMaterialService iTrainingMaterialService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final ITrainingOrganizationMaterialService iTrainingOrganizationMaterialService;

    public PageVo<ResTrainingMaterialListVO> trainingMaterialsList(ReqTrainingMaterialListPO request) {
        Integer pageNumber = request.getPageNumber();
        Integer pageSize = request.getPageSize();
        LambdaQueryWrapper<TrainingMaterial> wrapper = Wrappers.lambdaQuery(TrainingMaterial.class);

        buildTrainingMaterialsQuery(wrapper, request);
        Page<TrainingMaterial> page = iTrainingMaterialService.page(new Page<>(pageNumber, pageSize),wrapper);

        PageVo<ResTrainingMaterialListVO> pageVo = new PageVo<>();
        long total = page.getTotal();
        pageVo.setTotal(total);
        if (total == 0) {
            return pageVo;
        }
        // 装配培训材料列表VO 下载文件通过文件id 下载
        List<TrainingMaterial> records = page.getRecords();
        List<ResTrainingMaterialListVO> resVOList = records.stream().map(r -> {
            ResTrainingMaterialListVO resVO = new ResTrainingMaterialListVO();
            resVO.setTrainingMaterialId(r.getId());
            resVO.setTitle(r.getTitle());
            resVO.setMaterialType(MaterialTypeEnum.valueOf(r.getMaterialType()));
            if (Objects.nonNull(r.getRegionId())) {
                resVO.setRegionId(r.getRegionId());
                resVO.setRegionName(regionsCacheHelper.getDisplayName(r.getRegionId()));
            }else {
                resVO.setRegionId(DefValConstants.ZJREGION_ID);
                resVO.setRegionName(regionsCacheHelper.getDisplayName(DefValConstants.ZJREGION_ID));
            }
            resVO.setMaterialStatus(MaterialStatusEnum.valueOf(r.getMaterialStatus()));
            resVO.setCreateTime(r.getCreateOn());
            resVO.setContent(r.getContent());
            List<FileBasicInfo> appendixList = Lists.newArrayList();
            String appendix = r.getAppendixListJson();
            if (StringUtils.isNotBlank(appendix)) {
                List<String> array = JSON.parseArray(appendix, String.class);
                if (CollUtil.isNotEmpty(array)) {
                    for (String fileInfo : array) {
                        JSONObject jsonObject = JSON.parseObject(fileInfo, JSONObject.class);
                        FileBasicInfo basicInfo = new FileBasicInfo();
                        Long fileId = jsonObject.getLong(DriverConstant.FILE_ID);
                        String fileName = jsonObject.getString(DriverConstant.FILE_NAME);
                        basicInfo.setFileId(fileId);
                        basicInfo.setFileName(fileName);
                        appendixList.add(basicInfo);
                    }
                    resVO.setAppendixList(appendixList);
                }
            }
            return resVO;
        }).collect(Collectors.toList());
        pageVo.setRecords(resVOList);
        return pageVo;
    }

    //@LambdaDataScope
    private void buildTrainingMaterialsQuery(LambdaQueryWrapper<TrainingMaterial> wrapper, ReqTrainingMaterialListPO request) {
        // 获取入参
        String title = request.getTitle();
        MaterialTypeEnum materialType = request.getMaterialType();
        Long regionId = request.getRegionId();
        // 入参转换查询参数
        List<Long> regionIdList = new ArrayList<>();
        if (Objects.nonNull(regionId)) {
            regionIdList = regionsCacheHelper.listChildRegionId(regionId);
        }
        String materialTypeStr = null;
        if (Objects.nonNull(materialType)) {
            materialTypeStr = materialType.name();
        }
        wrapper.like(StringUtils.isNotBlank(title), TrainingMaterial::getTitle, title)
                .in(CollectionUtil.isNotEmpty(regionIdList), TrainingMaterial::getRegionId, regionId)
                .eq(StringUtils.isNotBlank(materialTypeStr), TrainingMaterial::getMaterialType, materialTypeStr)
                .orderByDesc(TrainingMaterial::getUpdateOn);
    }

    public ResSaveTrainingMaterialVO createTrainingMaterial(ReqSaveTrainingMaterialPO request) {
        // 获取入参
        List<FileBasicInfo> appendixList = request.getAppendixList();
        String title = request.getTitle();
        MaterialStatusEnum materialStatus = request.getMaterialStatus();
        MaterialTypeEnum materialType = request.getMaterialType();
        String content = request.getContent();

        // 获取登陆者信息
        UserInfoDetails loginUser = LoginUserUtil.loginUserDetail();

        // 装配培训材料
        TrainingMaterial saveRecord = new TrainingMaterial();
        saveRecord.setCreateOn(LocalDateTime.now());
        saveRecord.setUpdateOn(LocalDateTime.now());
        saveRecord.setCreateBy(loginUser.getUserId());
        saveRecord.setTitle(title);
        saveRecord.setContent(content);
        saveRecord.setMaterialType(materialType.name());
        saveRecord.setMaterialStatus(materialStatus.name());
        saveRecord.setAppendixListJson(JSONObject.toJSONString(appendixList));
        saveRecord.setRegionId(loginUser.getRegionId());
        saveRecord.setCompanyId(loginUser.getCompanyId());
        iTrainingMaterialService.save(saveRecord);

        ResSaveTrainingMaterialVO resSaveTrainingMaterialVO = new ResSaveTrainingMaterialVO();
        resSaveTrainingMaterialVO.setTrainingMaterialId(saveRecord.getId());
        return resSaveTrainingMaterialVO;
    }

    public ResSaveTrainingMaterialVO saveTrainingMaterial(ReqSaveTrainingMaterialPO request) {
        // 获取入参
        List<FileBasicInfo> appendixList = request.getAppendixList();
        String title = request.getTitle();
        MaterialStatusEnum materialStatus = request.getMaterialStatus();
        MaterialTypeEnum materialType = request.getMaterialType();
        String content = request.getContent();
        Long trainingMaterialId = request.getId();

        if (Objects.isNull(trainingMaterialId)) {
            // 获取登陆者信息
            UserInfoDetails loginUser = LoginUserUtil.loginUserDetail();

            // 装配培训材料
            TrainingMaterial saveRecord = new TrainingMaterial();
            saveRecord.setCreateOn(LocalDateTime.now());
            saveRecord.setUpdateOn(LocalDateTime.now());
            saveRecord.setCreateBy(loginUser.getUserId());
            saveRecord.setTitle(title);
            saveRecord.setContent(content);
            saveRecord.setMaterialType(materialType.name());
            saveRecord.setMaterialStatus(materialStatus.name());
            saveRecord.setAppendixListJson(JSONObject.toJSONString(appendixList));
            saveRecord.setRegionId(loginUser.getRegionId());
            saveRecord.setCompanyId(loginUser.getCompanyId());
            iTrainingMaterialService.save(saveRecord);

            trainingMaterialId = saveRecord.getId();
        } else {
            TrainingMaterial trainingMaterial = iTrainingMaterialService.getById(trainingMaterialId);
            if (Objects.isNull(trainingMaterial)) {
                throw new BizException("培训材料不存在");
            }

            trainingMaterial.setUpdateOn(LocalDateTime.now());
            trainingMaterial.setTitle(title);
            trainingMaterial.setContent(content);
            trainingMaterial.setMaterialType(materialType.name());
            trainingMaterial.setMaterialStatus(materialStatus.name());
            trainingMaterial.setAppendixListJson(JSONObject.toJSONString(appendixList));
            iTrainingMaterialService.saveOrUpdate(trainingMaterial);
        }

        ResSaveTrainingMaterialVO resSaveTrainingMaterialVO = new ResSaveTrainingMaterialVO();
        resSaveTrainingMaterialVO.setTrainingMaterialId(trainingMaterialId);
        return resSaveTrainingMaterialVO;
    }

    public ResTrainingMaterialVO getTrainingMaterialDetail(Long trainingMaterialId) {
        TrainingMaterial trainingMaterial = iTrainingMaterialService.getById(trainingMaterialId);
        if (Objects.isNull(trainingMaterial)) {
            throw new BizException("培训材料不存在");
        }

        ResTrainingMaterialVO resTrainingMaterialVO = new ResTrainingMaterialVO();
        resTrainingMaterialVO.setId(trainingMaterial.getId());
        resTrainingMaterialVO.setTitle(trainingMaterial.getTitle());
        resTrainingMaterialVO.setContent(trainingMaterial.getContent());
        if (StringUtils.isNotBlank(trainingMaterial.getMaterialStatus())) {
            resTrainingMaterialVO.setMaterialStatus(MaterialStatusEnum.valueOf(trainingMaterial.getMaterialStatus()));
        }
        if (StringUtils.isNotBlank(trainingMaterial.getMaterialType())) {
            resTrainingMaterialVO.setMaterialType(MaterialTypeEnum.valueOf(trainingMaterial.getMaterialType()));
        }
        if (StringUtils.isNotBlank(trainingMaterial.getAppendixListJson())) {
            resTrainingMaterialVO.setAppendixList(JSONObject.parseArray(trainingMaterial.getAppendixListJson(), FileBasicInfo.class));
        }
        return resTrainingMaterialVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeTrainingMaterial(Long trainingMaterialId) {
        List<TrainingOrganizationMaterial> trainingOrganizationMaterialList = iTrainingOrganizationMaterialService.list(
                Wrappers.lambdaQuery(TrainingOrganizationMaterial.class)
                        .eq(TrainingOrganizationMaterial::getTrainingMaterialId, trainingMaterialId));
        if (CollectionUtil.isEmpty(trainingOrganizationMaterialList)) {
            iTrainingMaterialService.removeById(trainingMaterialId);
        } else {
            throw new BizException("当前材料有培训组织正在使用，无法删除");
        }
    }
}
