package com.yuchen.saas.park.service.service.property;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.park.api.dto.property.PropertyFeeStandardQryDto;
import com.yuchen.saas.park.api.dto.property.PropertyFeeStandardSaveDto;
import com.yuchen.saas.park.api.entity.property.PropertyFeeStandard;
import com.yuchen.saas.park.api.enums.property.FeeMarkEnum;
import com.yuchen.saas.park.api.vo.property.PropertyFeeParentInfoVo;
import com.yuchen.saas.park.api.vo.property.PropertyFeeStandardListVo;
import com.yuchen.saas.park.service.mapper.property.PropertyFeeStandardMapper;
import com.yuchen.saas.park.service.util.ManualValidUtil;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.tool.constant.NestConstant;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.groups.Default;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class PropertyFeeStandardService extends BaseServiceImpl<PropertyFeeStandardMapper,PropertyFeeStandard> {
    @Autowired
    private ManualValidUtil manualValidUtil;
    @Autowired
    private PropertySearchParkInfoService propertySearchParkInfoService;

    /**
     * 收费标准保存
     * @param dto
     */
   public void saveFeeStandard(PropertyFeeStandardSaveDto dto) {
       this.validParam(dto);
       this.verifySave(dto);
       super.saveOrUpdate(this.assembleSaveDto(dto));
   }

    private PropertyFeeStandard assembleSaveDto(PropertyFeeStandardSaveDto dto) {
        PropertyFeeStandard po;
        if (Func.isNotEmpty(dto.getId())) {
            po = this.getById(dto.getId());
        } else {
            po = new PropertyFeeStandard();
        }
        BeanUtils.copyProperties(dto,po);
        return po;
    }

    /**
     * 参数校验
     * @param dto
     */
   private void validParam(PropertyFeeStandardSaveDto dto) {
       List<Class> groupList = CollUtil.newArrayList(Default.class);
       if (Func.isNotEmpty(dto.getFeeMark())) {
           switch (FeeMarkEnum.convert(dto.getFeeMark())) {
               case CYCLE:
                   groupList.add(PropertyFeeStandardSaveDto.Cycle.class);
                   break;
               case METER:
                   groupList.add(PropertyFeeStandardSaveDto.Meter.class);
                   break;
               case QUANTITY:
                   groupList.add(PropertyFeeStandardSaveDto.Quantity.class);
                   break;
               case FIXED:
                   groupList.add(PropertyFeeStandardSaveDto.Fixed.class);
                   break;
           }
       }
       manualValidUtil.valid(dto,groupList);
   }


    /**
     * 业务校验
     * @param dto
     */
   private void verifySave(PropertyFeeStandardSaveDto dto) {
       LambdaQueryWrapper<PropertyFeeStandard> qw = new LambdaQueryWrapper();
       qw.eq(PropertyFeeStandard::getParkId,dto.getParkId());
//       qw.eq(PropertyFeeStandard::getFeeItemId,dto.getFeeItemId());
       qw.eq(PropertyFeeStandard::getFeeName,dto.getFeeName());
       qw.eq(PropertyFeeStandard::getIsDeleted, NestConstant.DB_NOT_DELETED);
       PropertyFeeStandard po = this.getOne(qw);
       if (po != null) {
           if (Func.isEmpty(dto.getId())
                   || !dto.getId().equals(po.getId())) {
               throw new ServiceException("该收费标准名称已存在");
           }
       }
   }

    /**
     * 分页查询
     * @param qryDto
     * @return
     */
   public Page<PropertyFeeStandardListVo> selectPage(PropertyFeeStandardQryDto qryDto) {
       Page<PropertyFeeStandardListVo> page = new Page<>(qryDto.getCurrent(), qryDto.getSize());
       return baseMapper.feeStandardPage(page, this.getPageQueryParam(qryDto));
   }


    private QueryWrapper<String> getPageQueryParam(PropertyFeeStandardQryDto qryDto) {
        QueryWrapper<String> qw = new QueryWrapper<>();
        if (StringUtil.isNotBlank(qryDto.getFeeName())) {
            qw.like("fs.fee_name", qryDto.getFeeName());
        }
        if (Func.isNotEmpty(qryDto.getParkId())) {
            qw.eq("fs.park_id",qryDto.getParkId());
        } else {
            qw.in("fs.park_id",propertySearchParkInfoService.getParkIdsByCurrUser());
        }
        if (Func.isNotEmpty(qryDto.getFeeItemId())) {
            qw.eq("fs.fee_item_id",qryDto.getFeeItemId());
        }
        if (Func.isNotEmpty(qryDto.getFeeMarkList())) {
            qw.in("fs.fee_mark",qryDto.getFeeMarkList());
        }
        if (Func.isNotEmpty(qryDto.getFeeIdList())) {
            qw.in("fs.id",qryDto.getFeeIdList());
        }
        if (Func.isNotEmpty(qryDto.getFeeSubject())) {
            qw.eq("fi.fee_subject",qryDto.getFeeSubject());
        }
        qw.eq("fs.is_deleted", NestConstant.DB_NOT_DELETED);
        return qw;
    }

    /**
     * 列表List查询
     * @param qryDto
     * @return
     */
    public List<PropertyFeeStandardListVo> listPageVo(PropertyFeeStandardQryDto qryDto) {
        qryDto.setCurrent(-1);
        qryDto.setSize(-1);
        return this.selectPage(qryDto).getRecords();
    }

    /**
     * 删除
     * @param id
     */
    public void del(Long id) {
        /**
         * 判断是否生成账单，是否被房源绑定
         */
        List<Long> ids = new ArrayList<>();
        ids.add(id);
        this.deleteLogic(ids);
    }


    /**
     * 查询费用名称项目名称信息
     * @param feeIdList
     * @return
     */
    public List<PropertyFeeParentInfoVo> listFeeParentInfoVo(List<Long> feeIdList) {
        if (feeIdList == null || feeIdList.size() == 0) {
            return new ArrayList<>();
        }
        List<String> feeIds = new ArrayList<>();
        feeIdList.forEach(id->feeIds.add(String.valueOf(id)));
        return baseMapper.listFeeParentInfoList(String.join(",",feeIds));
    }

    /**
     * 根据费用项目id查询收费标准
     * @param feeItemId
     * @return
     */
    public List<PropertyFeeStandard> listFeeByFeeItemId(Long feeItemId) {
        if (feeItemId == null) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<PropertyFeeStandard> qw = new LambdaQueryWrapper<>();
        qw.eq(PropertyFeeStandard::getFeeItemId,feeItemId);
        return this.list(qw);
    }

    public Integer countByFeeItemId(Long feeItemId) {
        LambdaQueryWrapper<PropertyFeeStandard> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PropertyFeeStandard::getFeeItemId,feeItemId);
        return count(queryWrapper);
    }

    public List<PropertyFeeStandard> listByIdsAndFeeMark(List<Long> ids,Integer feeMark){
        if(Func.isEmpty(ids)){
            return Collections.emptyList();
        }
        LambdaQueryWrapper<PropertyFeeStandard> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(PropertyFeeStandard::getId,ids)
                .eq(Func.isNotEmpty(feeMark),PropertyFeeStandard::getFeeMark,feeMark);
        return list(queryWrapper);
    }
}
