package com.jwipc.supplier.logic.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jwipc.api.constant.RestCode;
import com.jwipc.api.dto.ApiResult;
import com.jwipc.api.dto.OaFileParamDTO;
import com.jwipc.constant.DictCode;
import com.jwipc.constant.OaProcessType;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.constant.SupplierMaterialDemoStatus;
import com.jwipc.supplier.constant.SupplierOaClient;
import com.jwipc.supplier.convert.SupplierMaterialDemoConvert;
import com.jwipc.supplier.convert.SupplierMaterialDemoItemConvert;
import com.jwipc.supplier.dto.*;
import com.jwipc.supplier.entity.SupplierMaterialDemo;
import com.jwipc.supplier.entity.SupplierMaterialDemoItem;
import com.jwipc.supplier.logic.SupplierMaterialDemoLogic;
import com.jwipc.supplier.model.query.MaterialDemoQuery;
import com.jwipc.supplier.service.ISupplierMaterialDemoItemService;
import com.jwipc.supplier.service.ISupplierMaterialDemoService;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.FileClient;
import com.jwipc.sys.client.SequenceClient;
import com.jwipc.sys.client.UserPurchaseGroupClient;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.client.dto.FileResposePreviewCDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.jwipc.supplier.constant.SequenceConst.SAMPLE_DELIVERY_CODE;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class SupplierMaterialDemoLogicImpl implements SupplierMaterialDemoLogic {
    private final SupplierMaterialDemoConvert supplierMaterialDemoConvert;
    private final ISupplierMaterialDemoService supplierMaterialDemoService;
    private final SequenceClient sequenceClient;
    private final SupplierOaClient supplierOaClient;
    private final FileClient fileClient;
    private final DictClient dictClient;
    private final ISupplierMaterialDemoItemService supplierMaterialDemoItemService;
    private final SupplierMaterialDemoItemConvert supplierMaterialDemoItemConvert;
    private final UserPurchaseGroupClient userPurchaseGroupClient;

    @Override
    public PageView getList(MaterialDemoQuery query) {
        Page<SupplierMaterialDemo> page = PageUtil.toPage(query);
        if (LoginUtil.isSupplier()) {
            query.setSupplierId(LoginUtil.getSupplierId());
        }else{
            final Set<String> userPurchaseGroupCode = userPurchaseGroupClient.getUserPurchaseGroupCode(
                    LoginUtil.getUserId());
            query.setUserPurchaseGroupCodes(userPurchaseGroupCode);
        }
        final LambdaQueryWrapper<SupplierMaterialDemo> queryWrapper = getQueryWrapper(query);
        final List<SupplierMaterialDemo> list = supplierMaterialDemoService.list(page, queryWrapper);
        List<SupplierMaterialDemoBaseDTO> supplierMaterialDemoBaseDTOS = supplierMaterialDemoConvert.entities2Dtos(
                list);
        final Set<Long> ids = list.stream().map(SupplierMaterialDemo::getId).collect(Collectors.toSet());
        if (CollUtil.isNotEmpty(ids)) {
            final List<SupplierMaterialDemoItem> list1 = supplierMaterialDemoItemService.list(
                    new LambdaQueryWrapper<>(SupplierMaterialDemoItem.class).in(SupplierMaterialDemoItem::getDemoId,
                            ids));
            final Map<Long, List<SupplierMaterialDemoItem>> collect = list1.stream()
                    .collect(Collectors.groupingBy(SupplierMaterialDemoItem::getDemoId));
            for (SupplierMaterialDemoBaseDTO supplierMaterialDemoBaseDTO : supplierMaterialDemoBaseDTOS) {
                final Long id = supplierMaterialDemoBaseDTO.getId();
                final List<SupplierMaterialDemoItem> supplierMaterialDemoItems = collect.get(id);
                if (CollUtil.isNotEmpty(supplierMaterialDemoItems)) {
                    supplierMaterialDemoBaseDTO.setExpressNumber(
                            supplierMaterialDemoItems.stream().filter(a -> StrUtil.isNotEmpty(a.getExpressNumber()))
                                    .map(SupplierMaterialDemoItem::getExpressNumber).collect(
                                            Collectors.joining(StrUtil.COMMA)));
                }
            }
        }
        return PageUtil.getPV(supplierMaterialDemoBaseDTOS, page.getTotal());
    }

    private LambdaQueryWrapper<SupplierMaterialDemo> getQueryWrapper(MaterialDemoQuery query)
    {
        final LambdaQueryWrapper<SupplierMaterialDemo> queryWrapper =
                new LambdaQueryWrapper<SupplierMaterialDemo>().like(
                                StrUtil.isNotEmpty(query.getCode()), SupplierMaterialDemo::getCode,
                                SqlUtils.concatLike(query.getCode(), SqlLike.DEFAULT))
                        .and(StrUtil.isNotEmpty(query.getSupplierlNameOrCode()),
                                a -> a.like(SupplierMaterialDemo::getSupplierCode,
                                                SqlUtils.concatLike(query.getSupplierlNameOrCode(), SqlLike.DEFAULT)).or()
                                        .like(SupplierMaterialDemo::getSupplierName,
                                                SqlUtils.concatLike(query.getSupplierlNameOrCode(), SqlLike.DEFAULT)))
                        .exists(StrUtil.isNotEmpty(query.getMaterialNameOrCode()),
                                "select it.id,it.express_number from t_supplier_material_demo_item it where it" +
                                        ".demo_id=t_supplier_material_demo.id and (it.material_code LIKE {0} OR it" +
                                        ".material_name LIKE {1})",
                                SqlUtils.concatLike(query.getMaterialNameOrCode(), SqlLike.DEFAULT),
                                SqlUtils.concatLike(query.getMaterialNameOrCode(), SqlLike.DEFAULT)
                        )
                        .ge(StrUtil.isNotEmpty(query.getStartTime()), SupplierMaterialDemo::getCreateTime,
                                query.getStartTime())
                        .le(StrUtil.isNotEmpty(query.getEndTime()), SupplierMaterialDemo::getCreateTime,
                                query.getEndTime())
                        .eq(StrUtil.isNotEmpty(query.getPurchaseGroupCode()),
                                SupplierMaterialDemo::getPurchaseGroupCode,
                                query.getPurchaseGroupCode())
                        .eq(Objects.nonNull(query.getSupplierId()), SupplierMaterialDemo::getSupplierId,
                                query.getSupplierId())
                        .in(StrUtil.isNotEmpty(query.getState()), SupplierMaterialDemo::getState, query.getStates())
                        .in(Objects.nonNull(query.getUserPurchaseGroupCodes()), SupplierMaterialDemo::getPurchaseGroupCode, query.getUserPurchaseGroupCodes())
                        .orderBy(true, false, SupplierMaterialDemo::getCreateTime);
        return queryWrapper;
    }

    @Override
    public void saveOrUpdate(SupplierMaterialDemoSaveDTO saveDTO) {
        SupplierMaterialDemo supplierMaterialDemo = supplierMaterialDemoConvert.dto2Entity(saveDTO);
//        if (saveDTO.getState() == SupplierMaterialDemoStatus.SUBMITTED.getCode()) {
//            supplierMaterialDemo.setState(SupplierMaterialDemoStatus.SUBMITTED.getCode());
//        }
//        if (!LoginUtil.isSupplier()) {
//            supplierMaterialDemo.setState(SupplierMaterialDemoStatus.SUBMITTED.getCode());
//        }

        if (ObjectUtil.isNull(supplierMaterialDemo.getId())) {
            final String code = sequenceClient.createSequenceNo(SAMPLE_DELIVERY_CODE.getCode());
            supplierMaterialDemo.setCode(code);
            supplierMaterialDemo.setCreateId(LoginUtil.getUserId());
            supplierMaterialDemo.setCreateTime(LocalDateTime.now());
            supplierMaterialDemo.setUpdateId(LoginUtil.getUserId());
            supplierMaterialDemo.setUpdateTime(LocalDateTime.now());
            supplierMaterialDemo.setSubmitTime(LocalDateTime.now());
        } else {
            supplierMaterialDemo.setUpdateId(LoginUtil.getUserId());
            supplierMaterialDemo.setUpdateTime(LocalDateTime.now());
            supplierMaterialDemo.setSubmitTime(LocalDateTime.now());
            supplierMaterialDemoItemService.remove(
                    new LambdaQueryWrapper<SupplierMaterialDemoItem>().eq(SupplierMaterialDemoItem::getDemoId,
                            supplierMaterialDemo.getId()));
        }
        supplierMaterialDemoService.saveOrUpdate(supplierMaterialDemo);
        //需要保存明细，删除之前保存的明细
        if (CollUtil.isNotEmpty(saveDTO.getItems())) {
            final List<SupplierMaterialDemoItem> items = supplierMaterialDemoItemConvert.dto2EntityList(
                    saveDTO.getItems());
            for (SupplierMaterialDemoItem item : items) {
                item.setDemoId(supplierMaterialDemo.getId());
            }
            supplierMaterialDemoItemService.saveBatch(items);
        }
    }

    @Override
    public void remove(List<String> idList) {
        supplierMaterialDemoService.removeBatchByIds(idList);
    }

    @Override
    public void examine(SupplierMaterialDemoExamineDTO examineDto) {
        SupplierMaterialDemo demo = supplierMaterialDemoService.getById(examineDto.getId());
        demo.setExamineId(LoginUtil.getUserId());
        demo.setExamineName(LoginUtil.getName());
        demo.setState(examineDto.getState());
        demo.setExamineFileIds(examineDto.getExamineFileIds());
        demo.setExamineRemark(examineDto.getExamineRemark());
        if (examineDto.getState() == SupplierMaterialDemoStatus.OA_APPROVEING.getCode()) {
            //需要推送oa
            final List<DictDTO> dicByType = dictClient.getDicByType(DictCode.SAMPLE_TYPE.getCode());
            final Map<String, String> dicCache = dicByType.stream()
                    .collect(Collectors.toMap(DictDTO::getCode, DictDTO::getName));
            MaterialDemoOaParamDTO materialDemoOaParamDTO = new MaterialDemoOaParamDTO();
            final MaterialDemoOaParamDTO.Head head = new MaterialDemoOaParamDTO.Head();
            head.setFd_gongYingShangDaiMa(demo.getSupplierCode());
            head.setFd_gongYingShangMingChen(demo.getSupplierName());
            head.setFd_srmType(OaProcessType.MATERIAL_DEMO.getType());
            head.setFd_qianYangLeiXing(dicCache.get(demo.getSampleType()));
            head.setFd_shenQingDanHao(demo.getCode());
            head.setFd_gongYingShangPCNHao(demo.getPcnNo());
            head.setFd_teShuXuQiuShuoMing(demo.getRemark());
            head.setFd_yangPinShiFuGeiGongYingShan(demo.getReturnFlag() == 1 ? "需要" : "不需要");
            head.setFd_shenQingRenXingMing(LoginUtil.getAccount());
            //再次发起流程的，如果processId存在，则传入驳回的oa流程id重启审批旧流程 2024-08-07 邓京术
            if (StringUtils.isNotEmpty(demo.getOaId())) {
                head.setProcessId(demo.getOaId());
            }

            //需要获取附件
            final String fileIds1 = demo.getFileIds();
            final String fileIds = demo.getSupplierFileIds();
            final List<String> split1 = StrUtil.split(fileIds1, StrUtil.COMMA);
            final List<String> split = StrUtil.split(fileIds, StrUtil.COMMA);
            split.addAll(split1);
            final List<FileResposePreviewCDTO> previewUrl = fileClient.getPreviewUrl(split);
            if (CollUtil.isNotEmpty(previewUrl)) {
                List<OaFileParamDTO> fileParamDTOS = Lists.newArrayList();
                for (FileResposePreviewCDTO fileResposePreviewDTO : previewUrl) {
                    final OaFileParamDTO build = OaFileParamDTO.builder().fileName(fileResposePreviewDTO.getFileName())
                            .url(fileResposePreviewDTO.getPreviewUrl())
                            .downloadUrl(fileResposePreviewDTO.getDownloadUrl()).build();
                    fileParamDTOS.add(build);
                }
                head.setFd_chenRenShu(JSON.toJSONString(fileParamDTOS));
            }
            materialDemoOaParamDTO.setHead(head);
            final MaterialDemoOaParamDTO.Item item = new MaterialDemoOaParamDTO.Item();
            item.setItem(Lists.newArrayList());
            final Long id = demo.getId();
            final List<SupplierMaterialDemoItem> list = supplierMaterialDemoItemService.list(
                    new LambdaQueryWrapper<SupplierMaterialDemoItem>().eq(SupplierMaterialDemoItem::getDemoId, id));
            for (SupplierMaterialDemoItem supplierMaterialDemoItem : list) {
                final MaterialDemoOaParamDTO.Item1 item1 = new MaterialDemoOaParamDTO.Item1();
                item1.setFd_wuLiaoLiaoHao(supplierMaterialDemoItem.getMaterialCode());
                item1.setFd_wuLiaoMiaoShu(supplierMaterialDemoItem.getMaterialName());
                item1.setFd_wuLiaoZu(StrUtil.format("{}_{}", supplierMaterialDemoItem.getMaterialGroupCode(),
                        supplierMaterialDemoItem.getMaterialGroupName()));
                item1.setFd_tiGongYangPinShuLiang(String.valueOf(supplierMaterialDemoItem.getSampleCount()));
                item1.setFd_yangPinXuQiuShuLiang(String.valueOf(supplierMaterialDemoItem.getNeedCount()));
                item1.setFd_shiFuXuChuLiHuanBao(supplierMaterialDemoItem.getEnvProtectionFlag());
                item.getItem().add(item1);
            }
            materialDemoOaParamDTO.setItem(item);
            final ApiResult<String> stringApiResult = supplierOaClient.materailDemo(materialDemoOaParamDTO);
            if (Objects.equals(stringApiResult.getCode(), RestCode.SAP_SUCCESS.getCode())) {
                demo.setOaId(stringApiResult.getData());
            }
        }
        supplierMaterialDemoService.updateById(demo);

    }

    @Override
    public SupplierMaterialDemoBaseDTO getDetail(Long id) {
        final SupplierMaterialDemo materialDemo = supplierMaterialDemoService.getById(id);
        if (Objects.nonNull(materialDemo)) {
            return supplierMaterialDemoConvert.entity2Dto(materialDemo);
        }
        SupplierMaterialDemoBaseDTO supplierMaterialDemoBaseDTO = new SupplierMaterialDemoBaseDTO();
        if (LoginUtil.isSupplier()) {
            supplierMaterialDemoBaseDTO.setSupplierId(LoginUtil.getSupplierId());
            supplierMaterialDemoBaseDTO.setSupplierCode(LoginUtil.getSupplierCode());
            supplierMaterialDemoBaseDTO.setSupplierName(LoginUtil.getName());
        }
        return supplierMaterialDemoBaseDTO;
    }

    @Override
    public List<SupplierMaterialDemoBaseDTO> listAll(MaterialDemoQuery materialDemoQuery) {
        if (LoginUtil.isSupplier()) {
            materialDemoQuery.setSupplierId(LoginUtil.getSupplierId());
        }else{
            final Set<String> userPurchaseGroupCode = userPurchaseGroupClient.getUserPurchaseGroupCode(
                    LoginUtil.getUserId());
            materialDemoQuery.setUserPurchaseGroupCodes(userPurchaseGroupCode);
        }
        final LambdaQueryWrapper<SupplierMaterialDemo> queryWrapper = getQueryWrapper(materialDemoQuery);
        final List<SupplierMaterialDemo> list = supplierMaterialDemoService.list(queryWrapper);
        return supplierMaterialDemoConvert.entities2Dtos(list);
    }

    @Override
    public PageView listBySupplierId(MaterialDemoQuery query) {
        Page<SupplierMaterialDemo> page = PageUtil.toPage(query);
        final LambdaQueryWrapper<SupplierMaterialDemo> queryWrapper = getQueryWrapper(query);
        final List<SupplierMaterialDemo> list = supplierMaterialDemoService.list(page, queryWrapper);
        List<SupplierMaterialDemoBaseDTO> supplierMaterialDemoBaseDTOS = supplierMaterialDemoConvert.entities2Dtos(
                list);
        return PageUtil.getPV(supplierMaterialDemoBaseDTOS, page.getTotal());
    }

    @Override
    public PageView listByHeader(Long id) {
        if (Objects.isNull(id)) {
            return PageUtil.getPV(Collections.emptyList());
        }
        final List<SupplierMaterialDemoItem> list = supplierMaterialDemoItemService.list(
                new LambdaQueryWrapper<SupplierMaterialDemoItem>()
                        .eq(SupplierMaterialDemoItem::getDemoId, id));
        List<SupplierMaterialDemoItemBaseDTO> supplierMaterialDemoItemBaseDTOS =
                supplierMaterialDemoItemConvert.entities2Dtos(
                        list);
        return PageUtil.getPV(supplierMaterialDemoItemBaseDTOS);
    }

    @Override
    public void confirm(Long id) {
        supplierMaterialDemoService.update(
                new LambdaUpdateWrapper<SupplierMaterialDemo>().eq(SupplierMaterialDemo::getId, id)
                        .set(SupplierMaterialDemo::getState, SupplierMaterialDemoStatus.CONFIRM_OK.getCode()));
    }
}