<?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 image creatives as selectable previews, then upload the selected image to TikTok Ads and return image_id.')]
class SelectTikTokImageCreative 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 image creative ID; omit to show the image 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.');
        }

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

        $creativeId = $data['creative_id'] ?? null;
        if ($creativeId === null) {
            $this->choices->offer(
                field: 'tiktok_image_creative_id',
                question: 'Which completed image creative should we use for TikTok?',
                options: $images->map(fn (Creative $creative): array => [
                    'value' => (string) $creative->id,
                    'label' => $creative->title ?: 'Image creative '.$creative->id,
                    'hint' => $creative->asset->original_name ?: 'Completed image',
                    'image' => route('assets.preview', $creative->asset),
                    'sends' => 'Use TikTok image creative '.$creative->id.'.',
                ])->all(),
            );

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

        $creative = $images->firstWhere('id', $creativeId);
        if ($creative === null) {
            return Response::error('Choose one of the completed image 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 an image.');
        }

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

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

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