<?php

namespace App\Library\CampaignDecision;

use App\Campaigns\PerformanceAdvice;
use App\Campaigns\PerformanceVerdict;
use App\Models\CampaignPerformanceSuggestion;
use App\Services\AI\CampaignPerformanceAdvisor;

class CampaignDecisionMapper
{
    public function __construct(
        private readonly CampaignPerformanceDataAssembler $assembler,
        private readonly CampaignDecisionEngine $engine,
        private readonly CampaignDecisionRecorder $recorder,
        private readonly CampaignPerformanceAdvisor $advisor,
    ) {}

    /**
     * @param  array<string, mixed>  $group
     * @return array{verdict: string, verdict_label: string, reason: string}
     */
    public function mapOne(array $group, string $trigger = 'scheduled_hourly'): array
    {
        $context = $this->assembler->assemble($group, $trigger);
        $decision = $this->engine->evaluate($context);
        $this->recorder->record($group, $decision);

        $verdict = CampaignDecisionVerdict::from($decision['verdict']);
        $snapshot = $decision;
        $snapshot['data_source'] = 'whale_adops';
        $snapshot['decision_engine'] = 'v2';

        $php = new PerformanceAdvice(
            status: $this->legacyVerdict($verdict),
            reason: (string) $decision['reason'],
            source: 'php',
        );

        $advice = config('campaign-performance.llm_enabled', true)
            ? $this->advisor->explain($snapshot, $php)
            : $php;

        $row = CampaignPerformanceSuggestion::query()
            ->where('platform', $group['platform'])
            ->where('external_campaign_id', $group['external_campaign_id'])
            ->first() ?? new CampaignPerformanceSuggestion;

        $row->fill([
            'user_id' => $group['user_id'],
            'platform' => $group['platform'],
            'external_campaign_id' => $group['external_campaign_id'],
            'local_campaign_id' => $group['local_campaign_id'] ?? null,
            'local_google_ads_campaign_id' => $group['local_google_ads_campaign_id'] ?? null,
            'status' => $verdict->value,
            'source' => $advice->source,
            'reason' => $advice->reason,
            'confidence' => (string) ($decision['confidence'] ?? ''),
            'action_state' => 'pending',
            'snapshot' => $snapshot,
            'model' => $advice->model,
            'last_error' => $advice->lastError,
            'suggested_at' => now(),
        ]);
        $row->save();

        return [
            'verdict' => $verdict->value,
            'verdict_label' => $verdict->label(),
            'reason' => (string) $decision['reason'],
        ];
    }

    private function legacyVerdict(CampaignDecisionVerdict $verdict): PerformanceVerdict
    {
        return match ($verdict) {
            CampaignDecisionVerdict::Pause => PerformanceVerdict::Pause,
            CampaignDecisionVerdict::Maintain, CampaignDecisionVerdict::ScaleUp => PerformanceVerdict::Continue,
            CampaignDecisionVerdict::DecreaseBudget => PerformanceVerdict::ActionRequired,
            CampaignDecisionVerdict::DataIssue => PerformanceVerdict::ActionRequired,
            CampaignDecisionVerdict::Learning, CampaignDecisionVerdict::InsufficientData => PerformanceVerdict::NoAction,
            CampaignDecisionVerdict::Watch => PerformanceVerdict::NoAction,
        };
    }
}
