package org.dromara.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.domain.houseInfo.PropertyFee;
import org.dromara.domain.houseInfo.bo.PropertyFeeBo;
import org.dromara.domain.houseInfo.vo.PropertyFeeVo;
import org.dromara.domain.residentInfo.bo.ResidentInfoBo;
import org.dromara.domain.residentInfo.vo.ResidentInfoVo;
import org.dromara.mapper.PropertyFeeMapper;
import org.dromara.service.IPropertyFeeService;
import org.dromara.service.IResidentInfoService;
import org.dromara.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 物业费管理Service业务层处理
 *
 * @author boman
 * @date 2025-04-11
 */
@RequiredArgsConstructor
@Service
public class PropertyFeeServiceImpl implements IPropertyFeeService {

    private final PropertyFeeMapper baseMapper;

    @Autowired
    private IResidentInfoService residentInfoService;

    /**
     * 查询物业费管理
     *
     * @param propertyId 主键
     * @return 物业费管理
     */
    @Override
    public PropertyFeeVo queryById(Long propertyId){
        return baseMapper.selectVoById(propertyId);
    }

    /**
     * 分页查询物业费管理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 物业费管理分页列表
     */
    @Override
    public TableDataInfo<PropertyFeeVo> queryPageList(PropertyFeeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PropertyFee> lqw = buildQueryWrapper(bo);
        Page<PropertyFeeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的物业费管理列表
     *
     * @param bo 查询条件
     * @return 物业费管理列表
     */
    @Override
    public List<PropertyFeeVo> queryList(PropertyFeeBo bo) {
        LambdaQueryWrapper<PropertyFee> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PropertyFee> buildQueryWrapper(PropertyFeeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PropertyFee> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(PropertyFee::getPropertyId);
        lqw.eq(bo.getHouseId() != null, PropertyFee::getHouseId, bo.getHouseId());
        lqw.like(StringUtils.isNotBlank(bo.getOwnerName()), PropertyFee::getOwnerName, bo.getOwnerName());
        lqw.eq(StringUtils.isNotBlank(bo.getLocation()), PropertyFee::getLocation, bo.getLocation());
        lqw.eq(bo.getArea() != null, PropertyFee::getArea, bo.getArea());
        lqw.eq(StringUtils.isNotBlank(bo.getPropertyUnitNumber()), PropertyFee::getPropertyUnitNumber, bo.getPropertyUnitNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getDetailedAddress()), PropertyFee::getDetailedAddress, bo.getDetailedAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getHasParkingSpace()), PropertyFee::getHasParkingSpace, bo.getHasParkingSpace());
        lqw.eq(StringUtils.isNotBlank(bo.getParkingNumber()), PropertyFee::getParkingNumber, bo.getParkingNumber());
        lqw.like(StringUtils.isNotBlank(bo.getCommunityName()), PropertyFee::getCommunityName, bo.getCommunityName());
        lqw.eq(StringUtils.isNotBlank(bo.getYear()), PropertyFee::getYear, bo.getYear());
        lqw.eq(StringUtils.isNotBlank(bo.getTime()), PropertyFee::getTime, bo.getTime());
        lqw.eq(bo.getTenementExpense() != null, PropertyFee::getTenementExpense, bo.getTenementExpense());
        lqw.eq(bo.getParkingExpense() != null, PropertyFee::getParkingExpense, bo.getParkingExpense());
        lqw.eq(bo.getEnergyExpense() != null, PropertyFee::getEnergyExpense, bo.getEnergyExpense());
        lqw.eq(bo.getTotalExpense() != null, PropertyFee::getTotalExpense, bo.getTotalExpense());
        lqw.eq(StringUtils.isNotBlank(bo.getIsExpense()), PropertyFee::getIsExpense, bo.getIsExpense());
        return lqw;
    }

    /**
     * 新增物业费管理
     *
     * @param bo 物业费管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(PropertyFeeBo bo) {
        PropertyFee add = MapstructUtils.convert(bo, PropertyFee.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setPropertyId(add.getPropertyId());
        }
        return flag;
    }

    /**
     * 修改物业费管理
     *
     * @param bo 物业费管理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(PropertyFeeBo bo) {
        PropertyFee update = MapstructUtils.convert(bo, PropertyFee.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PropertyFee entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除物业费管理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public R<Map<String, BigDecimal>> statistics(PropertyFeeBo bo) {
        Map<String,BigDecimal> map = new HashMap<>();
        //物业费
        BigDecimal yjwyf = new BigDecimal("0.00");
        BigDecimal wjwyf = new BigDecimal("0.00");

        //车位费
        BigDecimal yjcwf = new BigDecimal("0.00");
        BigDecimal wjcwf = new BigDecimal("0.00");

        //能耗费
        BigDecimal yjnhf = new BigDecimal("0.00");
        BigDecimal wjnhf = new BigDecimal("0.00");

        //查询本年份所有数据并统计
        if(StringUtils.isEmpty(bo.getYear())){
            bo.setYear(DateUtils.getYear());
        }

        List<PropertyFeeVo> propertyFees = queryList(bo);
        if(propertyFees!=null && propertyFees.size()>0){
            for (PropertyFeeVo fee : propertyFees) {
                if("Y".equals(fee.getIsExpense())){
                    yjwyf = yjwyf.add(fee.getTenementExpense());
                    yjcwf = yjcwf.add(fee.getParkingExpense());
                    yjnhf = yjnhf.add(fee.getEnergyExpense());
                }else{
                    wjwyf = wjwyf.add(fee.getTenementExpense());
                    wjcwf = wjcwf.add(fee.getParkingExpense());
                    wjnhf = wjnhf.add(fee.getEnergyExpense());
                }
            }
        }
        map.put("yjwyf",yjwyf);
        map.put("wjwyf",wjwyf);
        map.put("yjcwf",yjcwf);
        map.put("wjcwf",wjcwf);
        map.put("yjnhf",yjnhf);
        map.put("wjnhf",wjnhf);
        return R.ok(map);
    }

    @Override
    public R<Void> CallPayment(Long houseId) {
        //查询户主信息
        ResidentInfoBo bo = new ResidentInfoBo();
        bo.setHouseId(houseId);
        bo.setIsHouseholder("Y");
        List<ResidentInfoVo> residentInfos = residentInfoService.queryList(bo);
        if(residentInfos!=null && residentInfos.size()>0){
            //todo 拿到户主手机号发送短信

            return R.ok("催缴成功，已通知户主缴费");
        }
        return R.fail("催缴失败，当前房屋无户主信息");
    }

    @Override
    public R<Void> CallPaymentAll(PropertyFeeBo bo) {
        //查询所有未缴费信息
        bo.setIsExpense("N");
        List<PropertyFeeVo> propertyFees = queryList(bo);
        //todo 通过房屋id拿到户主手机号发送短信


        return R.ok("催缴成功，已通知户主缴费");
    }
}
