<?php

namespace App\Services\Admin\Member;

use App\Repositories\Admin\Member\MemberMarketingBatchRepository;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

final class MemberMarketingBatchService
{
    public function __construct(
        private readonly MemberMarketingBatchRepository $repo
    ) {}

    public function run(string $asOfDate): array
    {
        // 방어: 같은 날 중복 실행 방지(스케줄 withoutOverlapping + 추가 안전장치)
        $lockKey = "lock:marketing:members:build-stats:{$asOfDate}";
        $lock = Cache::lock($lockKey, 3600);

        if (!$lock->get()) {
            Log::warning('[marketing-batch] skipped by lock', ['as_of_date' => $asOfDate]);
            return ['skipped' => true, 'as_of_date' => $asOfDate];
        }

        try {
            $this->repo->upsertBatchRunStart($asOfDate);

            Log::info('[marketing-batch] step A upsertDaily start', ['as_of_date' => $asOfDate]);
            $dailyRows = $this->repo->upsertDaily($asOfDate);
            Log::info('[marketing-batch] step A upsertDaily done', ['daily_rows' => $dailyRows]);

            Log::info('[marketing-batch] step B rebuildPurchaseTotal start', ['as_of_date' => $asOfDate]);
            $totalRows = $this->repo->rebuildPurchaseTotal($asOfDate);
            Log::info('[marketing-batch] step B rebuildPurchaseTotal done', ['total_rows' => $totalRows]);

            Log::info('[marketing-batch] step C rebuildStats start', ['as_of_date' => $asOfDate]);
            $statsRows = $this->repo->rebuildStats($asOfDate);
            Log::info('[marketing-batch] step C rebuildStats done', ['stats_rows' => $statsRows]);

            $this->repo->markBatchRunSuccess($asOfDate, $dailyRows, $totalRows, $statsRows);

            return [
                'skipped' => false,
                'as_of_date' => $asOfDate,
                'daily_rows' => $dailyRows,
                'total_rows' => $totalRows,
                'stats_rows' => $statsRows,
            ];
        } catch (\Throwable $e) {
            $this->repo->markBatchRunFailed($asOfDate, $e->getMessage());
            Log::error('[marketing-batch] failed', ['as_of_date' => $asOfDate, 'err' => $e->getMessage()]);
            throw $e;
        } finally {
            optional($lock)->release();
        }
    }
}
