<?php

namespace App\Services\Meet;

use App\Models\ActionItem;
use App\Models\AiSummary;
use App\Models\Transcript;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use RuntimeException;

class MeetAiService
{
    public function enabled(): bool
    {
        return (bool) config('meet.ai.enabled', true)
            && ((string) config('meet.ai.api_key') !== '' || $this->hasPlatformRelay());
    }

    public function summarize(Transcript $transcript): AiSummary
    {
        $transcript->loadMissing('session.room');

        if ($transcript->session) {
            app(TranscriptService::class)->refreshContent($transcript, $transcript->session);
            $transcript->refresh();
        }

        $summary = AiSummary::query()
            ->where('transcript_id', $transcript->id)
            ->first();

        if ($summary) {
            $summary->actionItems()->delete();
            $summary->update([
                'status' => 'processing',
                'summary' => '',
                'decisions' => [],
            ]);
        } else {
            $summary = AiSummary::create([
                'owner_ref' => $transcript->owner_ref,
                'session_id' => $transcript->session_id,
                'transcript_id' => $transcript->id,
                'status' => 'processing',
            ]);
        }

        try {
            $result = $this->generateSummary($transcript);
            $summary->update([
                'status' => 'ready',
                'summary' => $result['summary'] ?? '',
                'decisions' => $result['decisions'] ?? [],
            ]);

            foreach ($result['action_items'] ?? [] as $item) {
                ActionItem::create([
                    'owner_ref' => $transcript->owner_ref,
                    'ai_summary_id' => $summary->id,
                    'assignee_name' => $item['assignee'] ?? null,
                    'description' => $item['description'] ?? '',
                    'due_date' => $item['due_date'] ?? null,
                    'status' => 'open',
                ]);
            }
        } catch (\Throwable $e) {
            report($e);
            $summary->update(['status' => 'failed', 'summary' => 'AI summary could not be generated.']);
        }

        app(MeetNotificationService::class)->aiSummaryReady($summary->fresh());

        return $summary->fresh();
    }

    /**
     * @return array{summary: string, decisions: array, action_items: array}
     */
    protected function generateSummary(Transcript $transcript): array
    {
        $content = trim((string) $transcript->content);

        if (! $this->enabled()) {
            return $this->stubSummary($content);
        }

        $prompt = $this->buildPrompt($transcript, $content);

        $reply = $this->hasLocalKey()
            ? $this->viaOpenAi($prompt)
            : $this->viaPlatform($prompt);

        $parsed = json_decode($reply, true);
        if (! is_array($parsed)) {
            return ['summary' => $reply, 'decisions' => [], 'action_items' => []];
        }

        return $parsed;
    }

    protected function buildPrompt(Transcript $transcript, string $content): string
    {
        $session = $transcript->session;
        $room = $session?->room;
        $title = $room?->title ?? 'Meeting';
        $duration = 'unknown';

        if ($session?->started_at && $session?->ended_at) {
            $minutes = max(1, $session->started_at->diffInMinutes($session->ended_at));
            $duration = $minutes.' minutes';
        }

        $participantCount = $session?->participants()->where('status', 'joined')->count() ?? 0;
        $segments = $transcript->segments ?? [];
        $chatLineCount = collect($segments)->where('source', 'chat')->count();
        $captionLineCount = collect($segments)->filter(
            fn (array $segment) => ($segment['source'] ?? 'caption') === 'caption',
        )->count();

        $isSparse = $content === ''
            || $content === 'No transcript content available.'
            || strlen($content) < 120;

        $sourceNote = "The transcript combines in-meeting chat ({$chatLineCount} messages) "
            ."and live speech captions ({$captionLineCount} lines). "
            ."Caption lines are the primary record of spoken conversation — use them when chat is minimal.\n\n";

        $sparseNote = $isSparse
            ? "IMPORTANT: The transcript below is very limited and does not include a full audio transcription. "
                ."If it does not contain enough detail to summarize the meeting accurately, say so clearly in the summary. "
                ."Do not invent topics, decisions, or action items that are not supported by the transcript.\n\n"
            : "Only summarize what is explicitly supported by the transcript below.\n\n";

        return <<<PROMPT
{$sourceNote}{$sparseNote}Meeting context:
- Title: {$title}
- Duration: {$duration}
- Participants in call: {$participantCount}

Analyze this meeting transcript and respond in JSON with keys:
- summary (string, 2-4 paragraphs)
- decisions (array of strings)
- action_items (array of {assignee, description, due_date or null})

Transcript:
{$content}
PROMPT;
    }

    protected function stubSummary(string $transcript): array
    {
        $preview = Str::limit($transcript, 500);

        return [
            'summary' => "Meeting summary (AI not configured).\n\nTranscript preview:\n".$preview,
            'decisions' => [],
            'action_items' => [],
        ];
    }

    protected function viaOpenAi(string $prompt): string
    {
        $res = Http::withToken((string) config('meet.ai.api_key'))->acceptJson()->timeout(120)
            ->post('https://api.openai.com/v1/chat/completions', [
                'model' => config('meet.ai.model', 'gpt-4o-mini'),
                'temperature' => 0.2,
                'response_format' => ['type' => 'json_object'],
                'messages' => [
                    [
                        'role' => 'system',
                        'content' => 'You summarize Ladill Meet sessions from text transcripts. Return valid JSON only. Never fabricate content missing from the transcript.',
                    ],
                    ['role' => 'user', 'content' => $prompt],
                ],
            ]);

        if ($res->failed()) {
            throw new RuntimeException('OpenAI request failed: '.$res->status());
        }

        return trim((string) $res->json('choices.0.message.content', ''));
    }

    protected function viaPlatform(string $prompt): string
    {
        $base = rtrim((string) config('meet.ai.platform_api_url'), '/');
        $res = Http::withToken((string) config('meet.ai.platform_api_key'))->acceptJson()->timeout(120)
            ->post($base.'/afia/chat', [
                'product' => 'meet',
                'message' => $prompt,
                'history' => [],
                'system_prompt' => 'You summarize Ladill Meet sessions from text transcripts. Return valid JSON only. Never fabricate content missing from the transcript.',
            ]);

        if ($res->failed()) {
            throw new RuntimeException('Platform AI relay failed.');
        }

        return trim((string) $res->json('reply', ''));
    }

    protected function hasLocalKey(): bool
    {
        return (string) config('meet.ai.api_key') !== '';
    }

    protected function hasPlatformRelay(): bool
    {
        return rtrim((string) config('meet.ai.platform_api_url'), '/') !== ''
            && (string) config('meet.ai.platform_api_key') !== '';
    }
}
