<?php

namespace App\Domains\AI\Actions;

use App\Domains\Catalog\Models\Product;
use App\Domains\Conversations\Models\Conversation;
use App\Domains\Leads\Models\Lead;
use App\Domains\Leads\Models\PipelineStage;
use App\Domains\Orders\Models\Order;
use App\Domains\Quotes\Models\Quote;
use App\Models\User;
use Illuminate\Support\Collection;

class GenerateSalesCopilotAction
{
    public function __construct(
        protected GenerateReplySuggestionAction $generateReplySuggestion,
        protected GenerateOrderDraftAction $generateOrderDraft,
    ) {
    }

    public function execute(User $user): array
    {
        $conversation = $this->focusConversation($user);

        if (! $conversation) {
            return [
                'data' => [
                    'available' => false,
                    'reason' => 'No live conversations are available for AI copilot analysis yet.',
                ],
            ];
        }

        $conversation->loadMissing(['contact', 'messages', 'assignee']);
        $products = $this->relevantProducts($user, $conversation);
        $latestInbound = $conversation->messages
            ->where('direction', 'inbound')
            ->sortByDesc('created_at')
            ->first();

        $reply = $this->generateReplySuggestion->execute(
            user: $user,
            conversationId: $conversation->id,
            payload: [
                'latest_customer_message' => (string) ($latestInbound?->body_text ?? $conversation->messages->last()?->body_text ?? ''),
                'language' => 'en',
                'recent_history' => $conversation->messages
                    ->sortByDesc('created_at')
                    ->take(4)
                    ->reverse()
                    ->map(fn ($message) => sprintf('%s: %s', $message->direction, $message->body_text))
                    ->values()
                    ->all(),
                'relevant_products' => $products->map(fn (Product $product) => [
                    'name' => $product->name,
                    'price' => '$'.number_format((float) $product->price, 2),
                    'stock' => $product->stock_quantity,
                ])->all(),
            ],
        )['data'];

        $orderDraft = $this->generateOrderDraft->execute($user, $conversation)['data'];
        $lead = Lead::query()
            ->with(['stage'])
            ->where('tenant_id', $user->tenant_id)
            ->where('conversation_id', $conversation->id)
            ->latest('created_at')
            ->first();
        $quote = Quote::query()
            ->where('tenant_id', $user->tenant_id)
            ->where('contact_id', $conversation->contact_id)
            ->latest('created_at')
            ->first();
        $order = Order::query()
            ->where('tenant_id', $user->tenant_id)
            ->where('contact_id', $conversation->contact_id)
            ->latest('created_at')
            ->first();
        $nextStage = $lead ? PipelineStage::query()
            ->where('pipeline_id', $lead->pipeline_id)
            ->where('position', '>', $lead->stage?->position ?? 0)
            ->orderBy('position')
            ->first() : null;

        $riskFlags = array_values(array_filter([
            $conversation->unread_count > 0 ? 'Customer is still waiting for a response.' : null,
            $conversation->priority === 'urgent' ? 'Conversation is marked urgent.' : null,
            $orderDraft['order_signal_detected'] && ! $orderDraft['ready_to_create'] ? 'Order intent detected but key details still need confirmation.' : null,
            empty($orderDraft['warnings']) ? null : 'AI draft contains warnings that should be reviewed before action.',
            $lead && $lead->status === 'active' ? 'Lead is still active and should be progressed.' : null,
        ]));

        $nextBestAction = match (true) {
            $orderDraft['ready_to_create'] => 'Confirm the extracted order details and create the order from chat.',
            $orderDraft['order_signal_detected'] => 'Ask for the missing delivery or payment details, then create the order.',
            ($reply['detected_intent'] ?? null) === 'wholesale_inquiry' => 'Prepare or send a quote for the wholesale request.',
            ($reply['detected_intent'] ?? null) === 'ask_price' => 'Reply with price and offer delivery/order confirmation.',
            ($reply['detected_intent'] ?? null) === 'ask_stock' => 'Confirm stock availability before sending a commitment.',
            default => 'Reply quickly, qualify the lead, and move it to the right pipeline stage.',
        };

        $followUp = match (true) {
            $orderDraft['ready_to_create'] => 'If the customer confirms, create the order and send the payment or delivery confirmation.',
            $orderDraft['order_signal_detected'] => 'Request missing order details and follow up within the same conversation.',
            default => 'Keep the conversation moving with one clear question and update the pipeline.',
        };

        return [
            'data' => [
                'available' => true,
                'focusConversation' => [
                    'id' => $conversation->id,
                    'customerName' => $conversation->contact?->primary_name,
                    'channel' => str($conversation->channel_type)->replace('_', ' ')->title()->value(),
                    'city' => $conversation->contact?->city,
                    'priority' => $conversation->priority,
                    'status' => $conversation->status,
                    'unreadCount' => $conversation->unread_count,
                    'assignee' => $conversation->assignee?->full_name ?? 'Unassigned',
                    'latestCustomerMessage' => $latestInbound?->body_text,
                    'recentTimeline' => $conversation->messages
                        ->sortByDesc('created_at')
                        ->take(4)
                        ->reverse()
                        ->map(fn ($message) => [
                            'direction' => $message->direction,
                            'text' => $message->body_text,
                            'time' => $message->created_at?->format('M d, H:i'),
                        ])->values()->all(),
                ],
                'lead' => $lead ? [
                    'id' => $lead->id,
                    'title' => $lead->title,
                    'status' => $lead->status,
                    'stage' => $lead->stage?->name,
                    'value' => $lead->estimated_value ? '$'.number_format((float) $lead->estimated_value, 2) : null,
                    'nextStage' => $nextStage ? [
                        'id' => $nextStage->id,
                        'name' => $nextStage->name,
                    ] : null,
                ] : null,
                'quote' => $quote ? [
                    'id' => $quote->id,
                    'quoteNumber' => $quote->quote_number,
                    'status' => $quote->status,
                    'total' => '$'.number_format((float) $quote->total, 2),
                ] : null,
                'order' => $order ? [
                    'id' => $order->id,
                    'orderNumber' => $order->order_number,
                    'status' => $order->status,
                    'paymentStatus' => $order->payment_status,
                    'total' => '$'.number_format((float) $order->total, 2),
                ] : null,
                'replySuggestion' => $reply,
                'orderDraft' => $orderDraft,
                'copilot' => [
                    'headline' => $this->headline($reply, $orderDraft, $conversation),
                    'nextBestAction' => $nextBestAction,
                    'followUpRecommendation' => $followUp,
                    'riskFlags' => $riskFlags,
                ],
            ],
        ];
    }

    protected function focusConversation(User $user): ?Conversation
    {
        $query = Conversation::query()
            ->where('tenant_id', $user->tenant_id);

        if (! $user->can('conversations.view_all') && $user->can('conversations.view_assigned')) {
            $query->where(function ($builder) use ($user) {
                $builder->where('assigned_user_id', $user->id)
                    ->orWhereNull('assigned_user_id');
            });
        }

        return $query
            ->orderByDesc('unread_count')
            ->orderByRaw("CASE WHEN priority = 'urgent' THEN 4 WHEN priority = 'high' THEN 3 WHEN priority = 'medium' THEN 2 ELSE 1 END DESC")
            ->orderByDesc('last_message_at')
            ->first();
    }

    protected function relevantProducts(User $user, Conversation $conversation): Collection
    {
        $conversationText = mb_strtolower(
            $conversation->messages->pluck('body_text')->implode(' ')
        );

        return Product::query()
            ->where('tenant_id', $user->tenant_id)
            ->where('status', 'active')
            ->get()
            ->filter(fn (Product $product) => str_contains($conversationText, mb_strtolower($product->name))
                || (str_contains($conversationText, 'perfume') && str_contains(mb_strtolower($product->name), 'perfume'))
                || (str_contains($conversationText, 'bag') && str_contains(mb_strtolower($product->name), 'bag')))
            ->values();
    }

    protected function headline(array $reply, array $orderDraft, Conversation $conversation): string
    {
        return match (true) {
            $orderDraft['ready_to_create'] => 'AI detected a purchase-ready conversation and prepared an order draft.',
            $orderDraft['order_signal_detected'] => 'AI detected order intent, but some details still need confirmation.',
            ($reply['detected_intent'] ?? null) === 'wholesale_inquiry' => 'This conversation looks like a wholesale opportunity that may need a quote.',
            $conversation->unread_count > 0 => 'This conversation needs a prompt reply to keep the lead moving.',
            default => 'AI reviewed the latest customer context and prepared guidance for the next step.',
        };
    }
}
