package com.kym.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.github.pagehelper.PageHelper;
import com.kym.common.utils.CommUtil;
import com.kym.entity.StationAccount;
import com.kym.entity.WithdrawnRecord;
import com.kym.entity.common.PageBean;
import com.kym.entity.queryParams.WithdrawnQueryParam;
import com.kym.entity.vo.WithdrawnRecordVo;
import com.kym.mapper.WithdrawnRecordMapper;
import com.kym.service.StationAccountService;
import com.kym.service.WithdrawnRecordService;
import com.kym.service.cache.KymCache;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * <p>
 * 站点账户提现记录表 服务实现类
 * </p>
 *
 * @author skyline
 * @since 2025-04-19
 */
@Service
public class WithdrawnRecordServiceImpl extends MyBaseServiceImpl<WithdrawnRecordMapper, WithdrawnRecord> implements WithdrawnRecordService {

    private final StationAccountService stationAccountService;

    public WithdrawnRecordServiceImpl(@Lazy StationAccountService stationAccountService) {
        this.stationAccountService = stationAccountService;
    }

    @Override
    public WithdrawnRecordVo detail(String id) {
        WithdrawnRecord record;
        try {
            record = getById(Long.valueOf(id));
        } catch (NumberFormatException e) {
            return null;
        }
        if (record == null) {
            return null;
        }
        var vo = new WithdrawnRecordVo();
        BeanUtils.copyProperties(record, vo);
        vo.setStationName(KymCache.INSTANCE.getStationNameById(record.getStationId()));
        return vo;
    }

    @Override
    public PageBean<WithdrawnRecordVo> listWithdrawnRecords(WithdrawnQueryParam params) {
        PageHelper.startPage(params.getPageNum(), params.getPageSize());
        var res = lambdaQuery()
                .eq(CommUtil.isNotEmptyAndNull(params.getStationId()), WithdrawnRecord::getStationId, params.getStationId())
                .eq(CommUtil.isNotEmptyAndNull(params.getStatus()), WithdrawnRecord::getStatus, params.getStatus())
                .eq(CommUtil.isNotEmptyAndNull(params.getPaymentStatus()), WithdrawnRecord::getPaymentStatus, params.getPaymentStatus())
                .orderByDesc(WithdrawnRecord::getId)
                .list();
        var voList = res.stream().map(item -> {
            var vo = new WithdrawnRecordVo();
            BeanUtils.copyProperties(item, vo);
            vo.setStationName(KymCache.INSTANCE.getStationNameById(item.getStationId()));
            return vo;
        }).toList();
        return new PageBean<>(voList);
    }

    @Override
    @Transactional
    public void reviewWithdrawn(WithdrawnQueryParam params) {
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(params.getStatus()), "审核异常");
        lambdaUpdate()
                .set(WithdrawnRecord::getStatus, params.getStatus())
                .set(WithdrawnRecord::getReviewer, StpUtil.getSession().getString("username"))
                .set(WithdrawnRecord::getReviewTime, LocalDateTime.now())
                .eq(WithdrawnRecord::getId, params.getId())
                .update();
    }

    @Override
    @Transactional
    public void confirmWithdrawnPayment(WithdrawnQueryParam params) {
        CommUtil.asserts(CommUtil.isNotEmptyAndNull(params.getPaymentStatus()), "确认打款异常");
        var record = getById(params.getId());
        lambdaUpdate()
                .set(WithdrawnRecord::getPaymentStatus, params.getPaymentStatus())
                .set(WithdrawnRecord::getPayer, StpUtil.getSession().getString("username"))
                .set(WithdrawnRecord::getPaymentTime, LocalDateTime.now())
                .eq(WithdrawnRecord::getId, params.getId())
                .update();
        // 打款确认后扣减提现冻结金额，增加已提现金额
        stationAccountService.lambdaUpdate()
                .setSql("withdrawn_frozen_amount = withdrawn_frozen_amount - {0}, withdrawn_amount = withdrawn_amount + {0}", record.getWithdrawnAmount())
                .eq(StationAccount::getStationId, record.getStationId())
                .update();
    }
}
