package com.fuint.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuint.common.Constants;
import com.fuint.common.dto.AccountInfo;
import com.fuint.common.dto.MaterialTypeSearchDto;
import com.fuint.common.util.AuthUserUtil;
import com.fuint.common.vo.MaterialTypeVo;
import com.fuint.framework.FrameworkConstants;
import com.fuint.framework.annoation.OperationServiceLog;
import com.fuint.framework.exception.BusinessCheckException;
import com.fuint.framework.pagination.PaginationRequest;
import com.fuint.framework.pagination.PaginationResponse;
import com.fuint.framework.web.PageResult;
import com.fuint.framework.web.ResponseObject;
import com.fuint.repository.mapper.MtStoreMapper;
import com.fuint.repository.mapper.TAccountMapper;
import com.fuint.repository.model.MtMaterialType;
import com.fuint.common.service.MaterialTypeService;
import com.fuint.common.enums.StatusEnum;
import com.fuint.repository.mapper.MtMaterialTypeMapper;
import com.fuint.repository.model.MtStore;
import com.fuint.repository.model.TAccount;
import com.fuint.utils.PropertiesUtil;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.pagehelper.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 材料类型表服务接口
 *
 * Created by PZG
 * CopyRight https://www.fuint.cn
 */
@Service
@AllArgsConstructor
public class MaterialTypeServiceImpl extends ServiceImpl<MtMaterialTypeMapper, MtMaterialType> implements MaterialTypeService {

    private static final Logger logger = LoggerFactory.getLogger(MaterialTypeServiceImpl.class);

    private MtMaterialTypeMapper mtMaterialTypeMapper;

    private MtStoreMapper storeMapper;

    private TAccountMapper accountMapper;



    /**
     * 分页查询数据列表
     *
     * @param paginationRequest
     * @return
     */
    @Override
    public PaginationResponse<MtMaterialType> queryMaterialTypeListByPagination(PaginationRequest paginationRequest) {
        Page<MtMaterialType> pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        LambdaQueryWrapper<MtMaterialType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.ne(MtMaterialType::getDeleteFlag, 0);

        lambdaQueryWrapper.orderByAsc(MtMaterialType::getId);
        List<MtMaterialType> dataList = mtMaterialTypeMapper.selectList(lambdaQueryWrapper);

        PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal());
        PaginationResponse<MtMaterialType> paginationResponse = new PaginationResponse(pageImpl, MtMaterialType.class);
        paginationResponse.setTotalPages(pageHelper.getPages());
        paginationResponse.setTotalElements(pageHelper.getTotal());
        paginationResponse.setContent(dataList);

        return paginationResponse;
    }

    /**
     * 添加材料类型表
     *
     * @param mtMaterialType 材料类型表信息
     * @return
     */
    @Override
    @OperationServiceLog(description = "新增材料类型表")
    public ResponseObject addMaterialType(MtMaterialType mtMaterialType) throws BusinessCheckException {
        mtMaterialType.setDeleteFlag(0);
        mtMaterialType.setUpdateTime(new Date());
        mtMaterialType.setCreateTime(new Date());
        mtMaterialType.setCreateUserId(String.valueOf(AuthUserUtil.get().getId()));
        mtMaterialType.setUpdateUserId(String.valueOf(AuthUserUtil.get().getId()));
        Integer count = mtMaterialTypeMapper.selectCount(new LambdaQueryWrapper<MtMaterialType>()
                .eq(MtMaterialType::getName, mtMaterialType.getName())
                .eq(MtMaterialType::getStoreId, mtMaterialType.getStoreId()));
        if (count>0){
            return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, "操作成功",null);
        }
        int id = mtMaterialTypeMapper.insert(mtMaterialType);
        if (id > 0) {
            return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, "操作成功",null);
        } else {
            throw new BusinessCheckException("新增材料类型表数据失败");
        }
    }

    /**
     * 根据ID获材料类型表取息
     *
     * @param id 材料类型表ID
     * @return
     */
    @Override
    public MtMaterialType queryMaterialTypeById(Long id) {
        return mtMaterialTypeMapper.selectById(id);
    }

    /**
     * 根据ID删除材料类型表
     *
     * @param id 材料类型表ID
     * @param operator 操作人
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperationServiceLog(description = "删除材料类型表")
    public void deleteMaterialType(Long id, String operator) {
        MtMaterialType mtMaterialType = queryMaterialTypeById(id);
        if (null == mtMaterialType) {
            return;
        }
        mtMaterialType.setDeleteFlag(1);
        mtMaterialType.setUpdateTime(new Date());
        mtMaterialTypeMapper.updateById(mtMaterialType);
    }

    /**
     * 修改材料类型表数据
     *
     * @param mtMaterialType
     * @throws BusinessCheckException
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @OperationServiceLog(description = "更新材料类型表")
    public MtMaterialType updateMaterialType(MtMaterialType mtMaterialType) throws BusinessCheckException {
        mtMaterialType.setUpdateTime(new Date());
        mtMaterialType.setUpdateUserId(String.valueOf(AuthUserUtil.get().getId()));
        mtMaterialTypeMapper.updateById(mtMaterialType);
        return mtMaterialType;
    }

   /**
    * 根据条件搜索材料类型表
    *
    * @param  params 查询参数
    * @throws BusinessCheckException
    * @return
    * */
    @Override
    public List<MtMaterialType> queryMaterialTypeListByParams(Map<String, Object> params) {
        String status =  params.get("status") == null ? StatusEnum.ENABLED.getKey(): params.get("status").toString();
        String storeId =  params.get("storeId") == null ? "" : params.get("storeId").toString();

        LambdaQueryWrapper<MtMaterialType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(status)) {
            lambdaQueryWrapper.eq(MtMaterialType::getDeleteFlag, status);
        }
        if (StringUtils.isNotBlank(storeId)) {
            lambdaQueryWrapper.and(wq -> wq
                    .eq(MtMaterialType::getStoreId, 0)
                    .or()
                    .eq(MtMaterialType::getStoreId, storeId));
        }

        lambdaQueryWrapper.orderByAsc(MtMaterialType::getId);
        List<MtMaterialType> dataList = mtMaterialTypeMapper.selectList(lambdaQueryWrapper);
        return dataList;
    }

    /**
     * 材料类型表列表查询
     *
     * @return 材料类型表列表
     */
    @SneakyThrows
    @Override
    public PageResult<MaterialTypeVo> selectMaterialTypeList(MaterialTypeSearchDto materialTypeSearchDto) {
        LambdaQueryWrapper<MtMaterialType> queryWrapper = new LambdaQueryWrapper<>();
        //获取查询条件信息
        String name = materialTypeSearchDto.getName();
        Integer enable = materialTypeSearchDto.getEnable();
        int pageNo = materialTypeSearchDto.getPageNo() == null ? Constants.PAGE_NUMBER : materialTypeSearchDto.getPageNo();
        int pageSize = materialTypeSearchDto.getPageSize() == null ? Constants.PAGE_SIZE : materialTypeSearchDto.getPageSize();
       //如果材料分类名称不为空
        if (StringUtils.isNotBlank(name)){
            queryWrapper.eq(MtMaterialType::getName,name);
        }
        //如果是否启用字段不为空
        if (Objects.nonNull(enable)){
            queryWrapper.eq(MtMaterialType::getEnable,enable);
        }
        Long storeId = AuthUserUtil.get().getStoreId();
        if (Objects.nonNull(storeId) && storeId>0){
            queryWrapper.eq(MtMaterialType::getStoreId,storeId);
        }
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> this.baseMapper.selectCount(queryWrapper));
        //构建分页
        PageHelper.startPage(pageNo,pageSize);
        //获取数据
        List<MtMaterialType> mtMaterialTypes = this.baseMapper.selectList(queryWrapper);
       //填充剩余字段
        List<MaterialTypeVo> typeVoList = mtMaterialTypes.stream().map(mtMaterialType -> {
            MaterialTypeVo materialTypeVo = new MaterialTypeVo();
            BeanUtils.copyProperties(mtMaterialType, materialTypeVo);
            //获取创建人
            TAccount tAccount = accountMapper.selectById(mtMaterialType.getCreateUserId());
            if (Objects.nonNull(tAccount)) {
                //填充
                materialTypeVo.setUpdateUserName(tAccount.getRealName());
            }
            //获取店铺
            MtStore mtStore = storeMapper.selectById(mtMaterialType.getStoreId());
            if (Objects.nonNull(mtStore)) {
                //填充
                materialTypeVo.setStoreName(mtStore.getName());
            }
            return materialTypeVo;
        }).collect(Collectors.toList());
        return PageResult.<MaterialTypeVo>builder().data(typeVoList).total(future.get()).build();
    }

    /**
     * 根据id删除材料类型数据
     *
     * @return 结果
     */
    @Override
    public ResponseObject deleteHandler(Long id) throws BusinessCheckException {

        MtMaterialType materialType = this.baseMapper.selectById(id);
        AccountInfo accountInfo = AuthUserUtil.get();
        Long storeId = accountInfo.getStoreId();
        //校验是否在账号下的店铺操作
        if (Objects.nonNull(storeId) && storeId>0){
            if (!Long.valueOf(storeId).equals(materialType.getStoreId())){
                throw new BusinessCheckException("该售后订单状态异常");
            }
        }
        //更新数据（逻辑删除）
        materialType.setDeleteFlag(1);
        materialType.setUpdateUserId(String.valueOf(accountInfo.getId()));
        boolean updateById = this.updateById(materialType);
        return updateById?new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, "操作成功", null):
                new ResponseObject(1001, PropertiesUtil.getResponseErrorMessageByCode(1001), null);
    }
}
