package com.jeesharp.business.modules.finance.platformrevenue.application;

import com.jeesharp.business.modules.finance.merchantreceivable.service.MerchantReceivableService;
import com.jeesharp.business.modules.finance.platformrevenue.dto.PlatformRevenueRollupDTO;
import com.jeesharp.business.modules.finance.platformrevenue.service.PlatformRevenueService;
import com.jeesharp.business.modules.finance.platformrevenue.support.PlatformRevenueConstants;
import com.jeesharp.business.modules.finance.platformrevenue.vo.PlatformRevenueRollupAggregateVO;
import com.jeesharp.business.modules.finance.platformrevenue.vo.PlatformRevenueRollupResultVO;
import com.jeesharp.business.modules.finance.platformrevenue.vo.PlatformRevenueRollupResultVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 平台收入日汇总应用服务：编排应收账聚合与汇总表落库。
 *
 * @author jeesharp
 * @since 2026-06-29
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class PlatformRevenueApplicationService {

    private final PlatformRevenueService platformRevenueService;
    private final MerchantReceivableService merchantReceivableService;

    /**
     * 汇总并落库指定自然日（幂等覆盖）。
     */
    @Transactional(readOnly = false)
    public void rollupDaily(LocalDate statDate) {
        rollupDaily(statDate, PlatformRevenueConstants.DEFAULT_PLATFORM_TENANT_ID);
    }

    @Transactional(readOnly = false)
    public void rollupDaily(LocalDate statDate, String platformTenantId) {
        LocalDateTime windowStart = statDate.atStartOfDay();
        LocalDateTime windowEnd = statDate.plusDays(1).atStartOfDay();
        PlatformRevenueRollupAggregateVO aggregate =
                merchantReceivableService.summarizeForDailyRollup(windowStart, windowEnd);
        platformRevenueService.upsertDailyRollup(statDate, platformTenantId, aggregate);
    }

    /**
     * 汇总昨日平台收入。
     *
     * @return 是否执行（恒为 1 表示已处理）
     */
    @Transactional(readOnly = false)
    public int rollupYesterday() {
        rollupDaily(LocalDate.now().minusDays(1));
        return 1;
    }

    /**
     * 补跑最近若干自然日（含昨日），用于首次上线回填。
     */
    @Transactional(readOnly = false)
    public int rollupRecentDays(int days) {
        if (days <= 0) {
            return 0;
        }
        int capped = Math.min(days, 90);
        LocalDate end = LocalDate.now().minusDays(1);
        LocalDate start = end.minusDays(capped - 1L);
        int count = 0;
        for (LocalDate cursor = start; !cursor.isAfter(end); cursor = cursor.plusDays(1)) {
            rollupDaily(cursor);
            count++;
        }
        return count;
    }

    /**
     * 管理端手动触发日汇总：指定单日、最近 N 日或默认昨日。
     */
    @Transactional(readOnly = false)
    public PlatformRevenueRollupResultVO rollupManually(PlatformRevenueRollupDTO dto) {
        PlatformRevenueRollupResultVO result = new PlatformRevenueRollupResultVO();
        if (dto != null && dto.getStatDate() != null) {
            rollupDaily(dto.getStatDate());
            result.setRolledUpDays(1);
            result.setMessage("已汇总 " + dto.getStatDate());
            return result;
        }
        if (dto != null && dto.getRecentDays() != null && dto.getRecentDays() > 0) {
            int count = rollupRecentDays(dto.getRecentDays());
            result.setRolledUpDays(count);
            result.setMessage("已回填最近 " + count + " 个自然日（至昨日）");
            return result;
        }
        rollupYesterday();
        result.setRolledUpDays(1);
        result.setMessage("已汇总昨日平台收入");
        return result;
    }
}
