<?php

namespace App\Console\Commands;

use App\Models\Ad;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

/**
 * Settle budget harian campaign: reset counter harian + hitung rollover.
 *
 * Dijalankan cron 00:01 setiap hari (source of truth). Fallback lazy-settle
 * ada di LandingController::settleIfNewDay() bila cron terlewat.
 *
 * Logika per ad:
 * - yesterday_clicks = klik_tanggal==yesterday ? klik_hari_ini : 0
 * - base_cap = intdiv(budget_harian, rate)
 * - unused = (base_cap + rollover_klik) - yesterday_clicks
 * - rollover_klik = min(base_cap, max(0, unused))   // cap 1 hari, cegah akumulasi
 * - reset klik_hari_ini=0, klik_tanggal=today
 * - pause_reason='daily_cap' → is_paused=false, pause_reason=null
 * - pause_reason='no_saldo'/'manual' → biarkan paused
 */
class SettleDailyBudgets extends Command
{
    protected $signature = 'ads:settle-daily';
    protected $description = 'Reset counter klik harian & hitung rollover budget semua campaign Aktif/Draft';

    public function handle(): int
    {
        $rate = (int) config('ads.default_rate', 100);
        $today = today()->toDateString();
        $yesterday = today()->subDay()->toDateString();

        Ad::where(function ($q) use ($today) {
            $q->whereNull('klik_tanggal')
                ->orWhere('klik_tanggal', '<', $today)
                ->orWhere(fn ($q2) => $q2->where('is_paused', true)->where('pause_reason', 'daily_cap'));
        })
            ->whereNotNull('budget_harian')
            ->cursor()
            ->each(function (Ad $ad) use ($rate, $today, $yesterday): void {
                $this->settle($ad, $rate, $today, $yesterday);
            });

        $this->info('Settled daily budgets.');

        return self::SUCCESS;
    }

    public function settle(Ad $ad, int $rate, string $today, string $yesterday): void
    {
        if (! $ad->budget_harian) {
            return;
        }

        $yesterdayClicks = $ad->klik_tanggal?->toDateString() === $yesterday
            ? $ad->klik_hari_ini
            : 0;

        $baseCap = intdiv($ad->budget_harian, $rate);
        $unused = max(0, ($baseCap + $ad->rollover_klik) - $yesterdayClicks);
        $rollover = min($baseCap, $unused);

        $update = [
            'klik_hari_ini' => 0,
            'klik_tanggal' => $today,
            'rollover_klik' => $rollover,
        ];

        // Clear daily-cap pause; leave no_saldo/manual paused.
        if ($ad->is_paused && $ad->pause_reason === 'daily_cap') {
            $update['is_paused'] = false;
            $update['pause_reason'] = null;
        }

        $ad->update($update);
    }
}
