<?php

namespace App\Mcp\Tools\TikTok;

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

#[Description('List posts from the authorized TikTok account. Automatically select one post or offer visual choices when several posts are available.')]
class ListTikTokPosts extends Tool
{
    public function __construct(
        private readonly TikTokService $tiktok,
        private readonly Choices $choices,
    ) {}

    public function schema(JsonSchema $schema): array
    {
        return ['item_id' => $schema->string()->description('Selected TikTok post ID; omit to list or auto-select posts')];
    }

    public function handle(Request $request): Response
    {
        $data = $request->validate(['item_id' => ['nullable', 'string']]);
        $connection = TikTokConnection::query()->where('user_id', $request->user()?->getAuthIdentifier())->first();
        if ($connection === null || blank($connection->access_token) || blank($connection->identity_id)) {
            return Response::error('Connect TikTok Ads and select an authorized TikTok account first.');
        }

        try {
            $posts = $this->tiktok->identityPosts($connection);
        } catch (Throwable $exception) {
            report($exception);

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

        $connection->forceFill(['tiktok_posts' => $posts])->save();
        $itemId = $data['item_id'] ?? null;
        if ($itemId !== null) {
            $post = collect($posts)->firstWhere('item_id', $itemId);
            if (! is_array($post)) {
                return Response::error('Choose a TikTok post returned for the authorized account.');
            }
            $connection->forceFill(['tiktok_item_id' => $itemId])->save();

            return Response::json(['ok' => true, 'selected_post' => $post]);
        }

        if (count($posts) === 1) {
            $connection->forceFill(['tiktok_item_id' => $posts[0]['item_id']])->save();

            return Response::json(['ok' => true, 'selected_post' => $posts[0], 'auto_selected' => true]);
        }

        if ($posts === []) {
            $connection->forceFill(['tiktok_item_id' => null])->save();

            return Response::error('No authorized TikTok posts are available for Spark ad creation.');
        }

        $connection->forceFill(['tiktok_item_id' => null])->save();
        $this->choices->offer(
            field: 'tiktok_item_id',
            question: 'Which authorized TikTok post should we promote?',
            options: array_map(fn (array $post): array => [
                'value' => $post['item_id'],
                'label' => $post['text'] !== '' ? $post['text'] : 'TikTok post '.$post['item_id'],
                'hint' => $post['duration'] !== null ? round($post['duration'], 1).' seconds' : null,
                'image' => $post['poster_url'],
                'sends' => 'Use TikTok post '.$post['item_id'].'.',
            ], $posts),
        );

        return Response::json(['ok' => true, 'posts' => $posts, 'selection_required' => true]);
    }
}
