<?php

namespace App\Services\Ai;

use App\Models\GeneratedReport;
use App\Services\Reports\ReportDatasetBuilder;
use Carbon\Carbon;
use Throwable;

class ReportAiInsightGenerator
{
    public function __construct(
        private readonly AiSettingsManager $settingsManager,
        private readonly ReportDatasetBuilder $datasetBuilder,
        private readonly ReportInsightPromptBuilder $promptBuilder,
        private readonly OpenAiCompatibleInsightClient $client,
        private readonly LocalReportInsightGenerator $localGenerator,
    ) {
    }

    public function generate(GeneratedReport $report, bool $forceLocal = false): GeneratedReport
    {
        $report->update([
            'ai_status' => 'processing',
            'ai_error_message' => null,
        ]);

        try {
            $clientModel = $report->client()->firstOrFail();
            $channels = $report->channels ?: ['google_ads', 'meta_ads', 'search_console', 'ga4'];
            $dataset = $this->datasetBuilder->build(
                $clientModel,
                Carbon::parse($report->date_from),
                Carbon::parse($report->date_to),
                $channels
            );
            $summary = $report->summary ?: [];

            $settings = $this->settingsManager->all();
            $useExternal = ! $forceLocal && ! empty($settings['enabled']) && ($settings['provider'] ?? 'local') !== 'local';

            if ($useExternal) {
                $messages = $this->promptBuilder->build($dataset, $summary);
                $response = $this->client->generate($settings, $messages);
                $result = new ReportInsightResult(
                    provider: $settings['provider'] ?? 'openai_compatible',
                    executiveSummary: (string) ($response['executive_summary'] ?? ''),
                    customerNote: (string) ($response['customer_note'] ?? ''),
                    technicalNote: (string) ($response['technical_note'] ?? ''),
                    risks: $this->cleanList($response['risks'] ?? []),
                    opportunities: $this->cleanList($response['opportunities'] ?? []),
                    actions: $this->cleanList($response['actions'] ?? []),
                    rawResponse: $response['_raw'] ?? null,
                );
            } else {
                $result = $this->localGenerator->generate($dataset, $summary);
            }

            $report->update($result->toReportUpdateArray());
        } catch (Throwable $exception) {
            report($exception);

            try {
                $clientModel = $report->client()->firstOrFail();
                $dataset = $this->datasetBuilder->build(
                    $clientModel,
                    Carbon::parse($report->date_from),
                    Carbon::parse($report->date_to),
                    $report->channels ?: ['google_ads', 'meta_ads', 'search_console', 'ga4']
                );
                $fallback = $this->localGenerator->generate($dataset, $report->summary ?: []);
                $report->update(array_merge($fallback->toReportUpdateArray(), [
                    'ai_provider' => 'local_rules_fallback',
                    'ai_error_message' => 'Harici AI çalışmadı, yerel kural motoru kullanıldı: ' . $exception->getMessage(),
                ]));
            } catch (Throwable $fallbackException) {
                report($fallbackException);
                $report->update([
                    'ai_status' => 'failed',
                    'ai_error_message' => $exception->getMessage(),
                ]);
            }
        }

        return $report->refresh();
    }

    private function cleanList(mixed $items): array
    {
        if (! is_array($items)) {
            return [];
        }

        return array_values(array_filter(array_map(fn ($item) => trim((string) $item), $items)));
    }
}
