<?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 identities authorized for the selected TikTok advertiser. Automatically selects one identity; offers choices when multiple identities are available.')]
class ListIdentities extends Tool
{
    public function __construct(
        private readonly TikTokService $tiktok,
        private readonly Choices $choices,
    ) {}

    public function schema(JsonSchema $schema): array
    {
        return [];
    }

    public function handle(Request $request): Response
    {
        $connection = TikTokConnection::query()->where('user_id', $request->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 listing identities.');
        }

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

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

        $connection->forceFill(['identities' => $identities])->save();
        if (count($identities) === 1) {
            $identity = $identities[0];
            $this->persist($connection, $identity);

            return Response::json(['ok' => true, 'identities' => $identities, 'selected_identity' => $identity, 'auto_selected' => true]);
        }

        if ($identities === []) {
            $connection->forceFill(['identity_id' => null, 'identity_authorized_bc_id' => null, 'identity_type' => null, 'identity_name' => null, 'tiktok_posts' => null, 'tiktok_item_id' => null])->save();

            return Response::error('No TikTok identities are authorized for the selected advertiser.');
        }

        $connection->forceFill(['identity_id' => null, 'identity_authorized_bc_id' => null, 'identity_type' => null, 'identity_name' => null, 'tiktok_posts' => null, 'tiktok_item_id' => null])->save();
        $this->choices->offer(
            field: 'tiktok_identity',
            question: 'Which TikTok identity should the ad use?',
            options: array_map(fn (array $identity): array => [
                'value' => $identity['identity_type'].'|'.$identity['identity_id'],
                'label' => $identity['identity_name'],
                'hint' => $identity['identity_type'],
                'sends' => 'Select TikTok identity '.$identity['identity_name'].'.',
            ], $identities),
        );

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

    /** @param array{identity_id: string, identity_type: string, identity_name: string, identity_authorized_bc_id: ?string} $identity */
    private function persist(TikTokConnection $connection, array $identity): void
    {
        $connection->forceFill([
            'identity_id' => $identity['identity_id'],
            'identity_authorized_bc_id' => $identity['identity_authorized_bc_id'],
            'identity_type' => $identity['identity_type'],
            'identity_name' => $identity['identity_name'],
            'tiktok_posts' => null,
            'tiktok_item_id' => null,
        ])->save();
    }
}
