<?php

namespace App\Campaigns;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Throwable;

class CampaignPerformanceWhaleEnrichment
{
    /**
     * @param  array<string, mixed>  $snapshot
     * @return array<string, mixed>
     */
    public function enrichSnapshot(array $snapshot, string $externalCampaignId): array
    {
        $campaignId = trim($externalCampaignId);

        if (! $this->isEnabled()) {
            $snapshot['affiliate'] = ['matched' => false, 'skipped' => 'disabled'];

            return $snapshot;
        }

        if ($campaignId === '') {
            $snapshot['affiliate'] = ['matched' => false, 'skipped' => 'empty_campaign_id'];

            return $snapshot;
        }

        try {
            $windows = [
                '3d' => $this->rollup($campaignId, 3),
                '7d' => $this->rollup($campaignId, 7),
            ];
            $matched = ($windows['3d']['days_with_rows'] ?? 0) > 0
                || ($windows['7d']['days_with_rows'] ?? 0) > 0;

            if (! $matched) {
                $snapshot['affiliate'] = [
                    'matched' => false,
                    'campaign_id' => $campaignId,
                ];

                return $snapshot;
            }

            $snapshot['affiliate'] = [
                'matched' => true,
                'campaign_id' => $campaignId,
                'data_through' => $this->dataThrough($campaignId),
                '3d' => $windows['3d'],
                '7d' => $windows['7d'],
            ];
        } catch (Throwable $exception) {
            Log::warning('Campaign performance whale enrichment failed', [
                'external_campaign_id' => $campaignId,
                'error' => $exception->getMessage(),
            ]);
            $snapshot['affiliate'] = ['matched' => false, 'skipped' => 'error'];
        }

        return $snapshot;
    }

    /**
     * @return list<array{
     *     date: string,
     *     clicks: int,
     *     sum_cpc: float,
     *     orders: float,
     *     net_revenue: float
     * }>
     */
    public function dailyRows(string $externalCampaignId, int $limit = 14): array
    {
        $campaignId = trim($externalCampaignId);

        if (! $this->isEnabled() || $campaignId === '') {
            return [];
        }

        $rows = DB::connection('whale')
            ->table('arb_adops_campaign_performance')
            ->where('campaign_id', $campaignId)
            ->orderByDesc('date')
            ->orderByDesc('id')
            ->limit(max(1, $limit))
            ->get();

        return $rows->map(fn (object $row): array => [
            'date' => (string) $row->date,
            'clicks' => (int) $row->clicks,
            'sum_cpc' => round((float) $row->sum_cpc, 4),
            'orders' => round((float) $row->orders, 4),
            'net_revenue' => round((float) $row->net_revenue, 4),
        ])->all();
    }

    public function isEnabled(): bool
    {
        if (! (bool) config('campaign-performance.whale_enabled', false)) {
            return false;
        }

        try {
            return Schema::connection('whale')->hasTable('arb_adops_campaign_performance');
        } catch (Throwable) {
            return false;
        }
    }

    /**
     * @return array{
     *     from: string,
     *     to: string,
     *     clicks: int,
     *     sum_cpc: float,
     *     orders: float,
     *     net_revenue: float,
     *     days_with_rows: int
     * }
     */
    private function rollup(string $campaignId, int $days): array
    {
        $to = now()->copy()->startOfDay();
        $from = $to->copy()->subDays($days - 1);

        $summary = DB::connection('whale')
            ->table('arb_adops_campaign_performance')
            ->where('campaign_id', $campaignId)
            ->whereBetween('date', [$from->toDateString(), $to->toDateString()])
            ->selectRaw('COUNT(*) as days_with_rows')
            ->selectRaw('COALESCE(SUM(clicks), 0) as clicks')
            ->selectRaw('COALESCE(SUM(sum_cpc), 0) as sum_cpc')
            ->selectRaw('COALESCE(SUM(orders), 0) as orders')
            ->selectRaw('COALESCE(SUM(net_revenue), 0) as net_revenue')
            ->first();

        return [
            'from' => $from->toDateString(),
            'to' => $to->toDateString(),
            'clicks' => (int) ($summary->days_with_rows ? $summary->clicks : 0),
            'sum_cpc' => round((float) ($summary->sum_cpc ?? 0), 4),
            'orders' => round((float) ($summary->orders ?? 0), 4),
            'net_revenue' => round((float) ($summary->net_revenue ?? 0), 4),
            'days_with_rows' => (int) ($summary->days_with_rows ?? 0),
        ];
    }

    private function dataThrough(string $campaignId): ?string
    {
        $value = DB::connection('whale')
            ->table('arb_adops_campaign_performance')
            ->where('campaign_id', $campaignId)
            ->max('date');

        return is_string($value) && $value !== '' ? $value : null;
    }
}
