<?php

namespace App\Mcp\Tools\TikTok;

use App\Agent\Choices;
use App\Models\Creative;
use App\Models\TikTokConnection;
use App\Services\TikTokService;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\Support\Facades\Storage;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Attributes\Description;
use Laravel\Mcp\Server\Tool;
use Throwable;

#[Description('Show completed application video creatives as selectable options, then upload the selected video to TikTok Ads and return video_id.')]
class SelectTikTokVideoCreative extends Tool
{
    public function __construct(
        private readonly Choices $choices,
        private readonly TikTokService $tiktok,
    ) {}

    public function schema(JsonSchema $schema): array
    {
        return ['creative_id' => $schema->integer()->description('Selected completed video creative ID; omit to show the video picker.')];
    }

    public function handle(Request $request): Response
    {
        $data = $request->validate(['creative_id' => ['nullable', 'integer']]);
        $user = $request->user();
        if ($user === null) {
            return Response::error('Authentication is required to select a creative.');
        }

        $videos = Creative::query()->where('user_id', $user->getAuthIdentifier())->where('type', 'video')->where('status', 'completed')->whereNotNull('asset_id')->with('asset')->latest('id')->limit(60)->get()->filter(fn (Creative $creative): bool => $creative->asset?->kind === 'video'
            && Storage::disk($creative->asset->disk ?: 'local')->exists($creative->asset->path));
        if ($videos->isEmpty()) {
            return Response::error('No completed video creatives are available. Create one in the creative library or upload a video first.');
        }

        $creativeId = $data['creative_id'] ?? null;
        if ($creativeId === null) {
            $this->choices->offer(
                field: 'tiktok_video_creative_id',
                question: 'Which completed video creative should we use for TikTok?',
                options: $videos->map(fn (Creative $creative): array => [
                    'value' => (string) $creative->id,
                    'label' => $creative->title ?: 'Video creative '.$creative->id,
                    'hint' => trim(($creative->duration ? $creative->duration.' seconds - ' : '').($creative->asset->original_name ?: 'Completed video')),
                    'sends' => 'Use TikTok video creative '.$creative->id.'.',
                ])->all(),
            );

            return Response::json(['ok' => true, 'type' => 'video', 'count' => $videos->count()]);
        }

        $creative = $videos->firstWhere('id', $creativeId);
        if ($creative === null) {
            return Response::error('Choose one of the completed video creatives shown.');
        }

        $connection = TikTokConnection::query()->where('user_id', $user->getAuthIdentifier())->first();
        if ($connection === null || blank($connection->access_token) || blank($connection->advertiser_id)) {
            return Response::error('Connect TikTok Ads and select an advertiser before uploading a video.');
        }

        try {
            $videoId = $this->tiktok->uploadCreative($connection, $creative->asset);
        } catch (Throwable $exception) {
            report($exception);

            return Response::error($exception->getMessage());
        }

        return Response::json([
            'ok' => true,
            'uploaded' => true,
            'type' => 'video',
            'creative_id' => $creative->id,
            'name' => $creative->title ?: $creative->asset->original_name,
            'video_id' => $videoId,
            'next_step' => 'Pass video_id when creating the TikTok ad.',
        ]);
    }
}
