<?php

namespace App\Mcp\Tools\TikTok;

use App\Campaigns\TikTokCampaignFlow;
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 one confirmed TikTok campaign, ad-group, or ad field to the active staged draft. Call after every field decision.')]
class UpdateCampaignDraft extends Tool
{
    public function __construct(
        private readonly HttpRequest $httpRequest,
        private readonly TikTokCampaignFlow $flow,
    ) {}

    public function schema(JsonSchema $schema): array
    {
        return [
            'field' => $schema->string()->description('Draft field name')->required(),
            'value' => $schema->string()->description('Confirmed field value')->required(),
        ];
    }

    public function handle(Request $request): Response
    {
        $user = $request->user();
        $data = $request->validate([
            'field' => ['required', 'string', 'max:80', 'regex:/^[a-z][a-z0-9_]*$/'],
            'value' => ['required', 'string', 'max:4000'],
        ]);
        $conversationId = $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 ($user === null || $conversation === null) {
            return Response::error('TikTok chat conversation not found.');
        }

        $draft = json_decode((string) $conversation->tiktok_campaign_draft, true);
        $draft = is_array($draft) ? $draft : [];
        $connection = TikTokConnection::query()->where('user_id', $user->getAuthIdentifier())->first();
        $draft['advertiser_id'] = $connection?->advertiser_id;
        $draft['identity_id'] = $connection?->identity_id;
        if (filled($connection?->identity_type)) {
            $draft['identity_mode'] = $connection->identity_type === 'BC_AUTH_TT' ? 'spark' : 'non_spark';
        }
        $field = $this->normalizeField($data['field']);
        if ($field === 'validation_status') {
            return Response::error('Use validate-tiktok-campaign-draft to record the validation result.');
        }
        $next = $this->flow->next($draft);
        if (! array_key_exists($field, $draft) && $field !== ($next['field'] ?? null)) {
            $required = $next ? $next['stage_label'].' / '.$next['label'] : 'the current TikTok campaign flow';

            return Response::error('Complete '.$required.' before saving a later field.');
        }

        $draft[$field] = $data['value'];
        if (! in_array($field, ['validation_status', 'created_campaign_id', 'created_adgroup_id', 'created_ad_id', 'api_status'], true)) {
            unset($draft['validation_status'], $draft['created_campaign_id'], $draft['created_adgroup_id'], $draft['created_ad_id'], $draft['api_status']);
        }
        $conversation->update(['tiktok_campaign_draft' => json_encode($draft)]);

        return Response::json([
            'ok' => true,
            'field' => $field,
            'value' => $data['value'],
            'next' => $this->flow->next($draft),
        ]);
    }

    private function normalizeField(string $field): string
    {
        return match ($field) {
            'campaign_objective' => 'objective',
            'budget' => 'daily_budget',
            'destination' => 'promotion_type',
            'campaign_budget' => 'campaign_budget',
            'country', 'location', 'location_ids' => 'location_id',
            'final_url' => 'landing_page_url',
            'post_id' => 'tiktok_item_id',
            default => $field,
        };
    }
}
