<?php

namespace App\Mcp\Tools\TikTok;

use App\Agent\Workspace;
use App\Models\Campaign;
use App\Models\TikTokConnection;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\Http\Request as HttpRequest;
use Laravel\Ai\Models\Conversation;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Attributes\Description;
use Laravel\Mcp\Server\Tool;

#[Description('Save a completed TikTok campaign brief as a local paused draft in this application. This does not create anything on TikTok. Use after the user explicitly chooses Save as draft.')]
class SaveTikTokDraft extends Tool
{
    public function __construct(
        private readonly Workspace $workspace,
        private readonly HttpRequest $httpRequest,
    ) {}

    public function schema(JsonSchema $schema): array
    {
        return [
            'name' => $schema->string()->description('Campaign name')->required(),
            'objective' => $schema->string()->description('TikTok campaign objective')->required(),
            'daily_budget' => $schema->number()->description('Daily budget in account currency')->required(),
            'campaign_budget' => $schema->number()->description('Campaign budget in account currency when CBO is on'),
            'destination' => $schema->string()->description('Campaign destination'),
            'landing_url' => $schema->string()->description('Landing page URL, when applicable'),
            'country' => $schema->string()->description('Target country or countries'),
            'campaign_type' => $schema->string()->description('TikTok campaign type'),
            'optimization_goal' => $schema->string()->description('Optimization goal'),
            'placement' => $schema->string()->description('Selected placement'),
            'targeting' => $schema->string()->description('Audience and targeting summary'),
            'bidding_strategy' => $schema->string()->description('Bidding strategy'),
            'schedule' => $schema->string()->description('Campaign schedule'),
            'creative_summary' => $schema->string()->description('Selected creative details'),
            'settings' => $schema->string()->description('JSON summary of the full campaign draft settings'),
            'conversation_id' => $schema->string()->description('Active TikTok conversation containing the validated draft'),
        ];
    }

    public function handle(Request $request): Response
    {
        $user = $request->user();
        if ($user === null) {
            return Response::error('Authentication is required.');
        }

        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'objective' => ['required', 'string', 'max:100'],
            'daily_budget' => ['nullable', 'numeric', 'min:0.01', 'required_without:campaign_budget'],
            'campaign_budget' => ['nullable', 'numeric', 'min:0.01', 'required_without:daily_budget'],
            'destination' => ['nullable', 'string', 'max:100'],
            'landing_url' => ['nullable', 'url', 'max:2048'],
            'country' => ['nullable', 'string', 'max:255'],
            'campaign_type' => ['nullable', 'string', 'max:100'],
            'optimization_goal' => ['nullable', 'string', 'max:100'],
            'placement' => ['nullable', 'string', 'max:255'],
            'targeting' => ['nullable', 'string', 'max:2000'],
            'bidding_strategy' => ['nullable', 'string', 'max:100'],
            'schedule' => ['nullable', 'string', 'max:500'],
            'creative_summary' => ['nullable', 'string', 'max:2000'],
            'settings' => ['nullable', 'json', 'max:12000'],
            'conversation_id' => ['nullable', 'string', 'max:36'],
        ]);

        $connection = TikTokConnection::query()->where('user_id', $user->getAuthIdentifier())->first();
        if ($connection === null || blank($connection->access_token)) {
            return Response::error('Connect TikTok Ads before saving a TikTok campaign draft.');
        }

        if (blank($connection->advertiser_id)) {
            return Response::error('Select a TikTok advertiser before saving a campaign draft.');
        }

        $conversationId = $data['conversation_id'] ?? $this->httpRequest->input('conversation');
        $conversation = is_string($conversationId)
            ? Conversation::query()
                ->whereKey($conversationId)
                ->where('chat_type', 'tiktok_ads')
                ->where('participant_type', $user->getMorphClass())
                ->where('participant_id', $user->getKey())
                ->first()
            : null;
        if ($conversation === null) {
            return Response::error('TikTok campaign conversation not found.');
        }

        $settings = json_decode((string) $conversation->tiktok_campaign_draft, true);
        $settings = is_array($settings) ? $settings : null;
        if (! is_array($settings) || ($settings['validation_status'] ?? null) !== 'passed') {
            return Response::error('Validate the complete campaign preview before saving the campaign draft.');
        }
        if (($settings['preview_confirmed'] ?? null) !== 'yes') {
            return Response::error('Obtain approval for the complete campaign preview before saving the draft.');
        }
        // Calling this tool is the explicit local-save decision. Older drafts
        // may predate the creation_mode checkpoint, so normalize them here.
        if (($settings['creation_mode'] ?? null) !== 'draft' || ($settings['draft_confirmed'] ?? null) !== 'yes') {
            $settings['creation_mode'] = 'draft';
            $settings['draft_confirmed'] = 'yes';
            $conversation->update(['tiktok_campaign_draft' => json_encode($settings)]);
        }

        $campaign = Campaign::query()->create([
            'user_id' => $user->getAuthIdentifier(),
            'name' => $data['name'],
            'platform' => 'tiktok',
            'objective' => $data['objective'],
            'budget' => $data['campaign_budget'] ?? $data['daily_budget'],
            'status' => 'draft',
            'ad_account_id' => $connection->advertiser_id,
            'landing_url' => $data['landing_url'] ?? null,
            'optimization_goal' => $data['optimization_goal'] ?? null,
            'locations' => filled($data['country'] ?? null) ? ['country' => $data['country']] : null,
            'placements' => filled($data['placement'] ?? null) ? ['placement' => $data['placement']] : null,
            'bid_strategy' => $data['bidding_strategy'] ?? null,
            'schedule' => filled($data['schedule'] ?? null) ? ['summary' => $data['schedule']] : null,
            'meta' => [
                'campaign_type' => $data['campaign_type'] ?? null,
                'destination' => $data['destination'] ?? null,
                'targeting' => $data['targeting'] ?? null,
                'creative_summary' => $data['creative_summary'] ?? null,
                'campaign_budget_optimization' => isset($data['campaign_budget']) ? 'on' : 'off',
                'campaign_budget' => $data['campaign_budget'] ?? null,
                'settings' => $settings,
                'advertiser_name' => $connection->advertiser_name,
                'delivery_mode' => 'paused',
                'save_type' => 'local_draft',
            ],
        ]);

        $this->workspace->produced($campaign);

        return Response::json([
            'ok' => true,
            'saved_locally' => true,
            'campaign' => [
                'id' => $campaign->getKey(),
                'name' => $campaign->name,
                'platform' => $campaign->platform,
                'status' => $campaign->status,
                'delivery_mode' => 'paused',
                'created_on_tiktok' => false,
                'advertiser_id' => $connection->advertiser_id,
            ],
        ]);
    }
}
