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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuchen.saas.park.api.dto.property.CreateBillDto;
import com.yuchen.saas.park.api.dto.property.PropertyDepositCreateBillDto;
import com.yuchen.saas.park.api.entity.property.PropertyBill;
import com.yuchen.saas.park.api.entity.property.PropertyBillSub;
import com.yuchen.saas.park.api.entity.property.PropertyFeeStandard;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.enums.property.BillStatusEnum;
import com.yuchen.saas.park.api.enums.property.PayStatusEnum;
import com.yuchen.saas.park.api.enums.property.YesOrNoEnum;
import com.yuchen.saas.park.service.mapper.property.PropertyBillMapper;
import com.yuchen.saas.park.service.service.property.PropertyBillSubService;
import com.yuchen.saas.park.service.service.property.PropertyFeeStandardService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 押金账单
 */
@Slf4j
@Service
public class DepositBillServiceImpl extends BasePropertyBillService implements IPropertyBillService {
    @Resource
    private PropertyBillMapper billMapper;
    @Resource
    private PropertyFeeStandardService propertyFeeStandardService;
    @Resource
    private PropertyBillSubService propertyBillSubService;
    @Resource
    private PropertyHousesService propertyHousesService;


    /**
     * 周期性账单生成
     *
     * @param createBillDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createBill(CreateBillDto createBillDto) {
        PropertyDepositCreateBillDto dto = createBillDto.getDepositCreateBillDto();
        super.validParam(createBillDto);
        if (!this.verifyBiz(dto)) {
            return;
        }
        PropertyFeeStandard fee = propertyFeeStandardService.getById(dto.getFeeId());
        PropertyBill bill = this.assembleBill(createBillDto,fee);
        billMapper.insert(bill);

        PropertyBillSub sub = super.assembleBillSub(fee);
        sub.setBillId(bill.getId());
        propertyBillSubService.save(sub);
    }


    /**
     * 账单信息组装
     *
     * @param dto
     * @return
     */
    private PropertyBill assembleBill(CreateBillDto dto, PropertyFeeStandard fee) {
        PropertyBill bill = super.assembleBaseBill(fee, dto.getCreateBillTypeEnum());
        PropertyDepositCreateBillDto billDto = dto.getDepositCreateBillDto();
        Date startDate = billDto.getStartDate();
        Date endDate = billDto.getEndDate();
        long receivableAmt = billDto.getDepositAmtFen();
        Date receivableDate = super.getReceivableDate(startDate, endDate, fee);

        if (billDto.getChargeType() == YesOrNoEnum.NO.getValue()) {
            bill.setBillStatus(BillStatusEnum.YES_OUT.getValue());
        } else {
            bill.setBillStatus(BillStatusEnum.PAID.getValue());
            bill.setPayStatus(PayStatusEnum.PAID.getValue());
        }

        if (Func.isNotEmpty(billDto.getHouseId())) {
            //如果一笔押金交的是多个房间的，那这个字段为空
            PropertyHouses houses = propertyHousesService.getById(billDto.getHouseId());
            bill.setBuildingId(houses.getBuildingId());
            bill.setHouseId(billDto.getHouseId());
        }

        bill.setOutBillTime(new Date());//线上，线下都是直接出账
        bill.setStartDate(startDate);
        bill.setEndDate(endDate);
        bill.setReceivableAmtFen(super.decimalPoint(fee.getParkId(),receivableAmt));
        bill.setReceivableDate(receivableDate);
        bill.setBreachDate(super.getBreachDate(receivableDate, startDate, endDate, fee));
        bill.setRetraceId(billDto.getDepositId());

        bill.setTaxAmtFen(super.calcTaxAmtFen(fee.getFeeItemId(),bill.getReceivableAmtFen()));
        bill.setCustomerId(billDto.getCustomerId());

        return bill;
    }


    /**
     * 业务校验，校验是否符合账单生成规则
     *
     * @param dto
     */
    private boolean verifyBiz(PropertyDepositCreateBillDto dto) {
        LambdaQueryWrapper<PropertyBill> qw = new LambdaQueryWrapper<>();
        qw.eq(PropertyBill::getRetraceId, dto.getDepositId());
        PropertyBill bill = billMapper.selectOne(qw);
        if (bill != null) {
            throw new ServiceException("该笔押金已生成账单，请检查押金id=" + dto.getDepositId());
        }
        return true;
    }



}
