<?php

namespace App\Http\Controllers;

use App\Events\ReadyToShipIntent;
use App\Models\Order;
use App\Models\CustomOrder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class TrelloWebhookController extends Controller
{
    /**
     * Handle incoming Trello webhooks
     * 
     * POST /api/webhooks/trello
     */
    public function handle(Request $request)
    {
        // Trello validation ping or real event - both return 200
        Log::info('Trello webhook received', [
            'method' => $request->method(),
            'content_length' => strlen($request->getContent()),
        ]);

        // If empty body or validation ping, just return success
        if ($request->getContent() === '' || $request->method() === 'HEAD') {
            return response()->json(['ok' => true], 200);
        }

        try {
            $payload = $request->json()->all();

            Log::info('Trello action received', [
                'action' => $payload['action']['type'] ?? 'unknown',
                'card' => $payload['action']['data']['card']['name'] ?? 'unknown',
            ]);

            match ($payload['action']['type'] ?? null) {
                'updateCard'      => $this->handleCardUpdate($payload),
                'updateCheckItem' => $this->handleChecklistUpdate($payload),
                default           => Log::debug('Unhandled Trello action', [
                    'type' => $payload['action']['type'] ?? 'unknown',
                ]),
            };

            return response()->json(['success' => true], 200);
        } catch (\Throwable $e) {
            Log::error('Error processing Trello webhook', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            return response()->json(['success' => true], 200);
        }
    }



    /**
     * Handle card movement between lists
     */
    private function handleCardUpdate(array $payload): void
    {
        $action = $payload['action'] ?? [];
        $cardData = $action['data']['card'] ?? [];
        $cardId = $cardData['id'] ?? null;
        $cardName = $cardData['name'] ?? null;
        $listAfter = $action['data']['listAfter'] ?? [];
        $listName = $listAfter['name'] ?? null;

        if (! $cardId || ! $cardName || ! $listName) {
            Log::warning('Trello card update missing required data', [
                'card_id' => $cardId,
                'card_name' => $cardName,
                'list_name' => $listName,
            ]);
            return;
        }

        // Extract order number from card name (e.g., "Order #1043" or "Order #ORD-20260102-ABC123")
        if (! preg_match('/Order #([A-Za-z0-9\-]+)/', $cardName, $matches)) {
            Log::debug('Could not extract order number from card name', ['card_name' => $cardName]);
            return;
        }

        $orderNumber = $matches[1];

        // Try to find the order (could be standard or custom)
        $order = Order::where('order_number', $orderNumber)->first() 
            ?? CustomOrder::where('order_number', $orderNumber)->first();

        if (! $order) {
            Log::warning('Order not found for Trello card', [
                'order_number' => $orderNumber,
                'card_name' => $cardName,
            ]);
            return;
        }

        Log::info('Trello card moved', [
            'order_uuid' => $order->uuid,
            'order_number' => $orderNumber,
            'list' => $listName,
        ]);

        // Handle list-specific actions
        match ($listName) {
            'Prep' => $order->update(['status' => 'prep']),
            'Printing' => $order->update(['status' => 'printing']),
            'Inspection' => $order->update(['status' => 'inspection']),
            'Packing' => $order->update(['status' => 'packing']),
            'Ready to Ship' => $this->handleReadyToShipIntent($order, $cardId),
            'Awaiting Collection' => $this->handleAwaitingCollectionIntent($order, $cardId),
            'In Transit' => $order->update(['status' => 'in_transit']),
            'Done' => $order->update(['status' => 'completed']),
            default => Log::debug('Card moved to list', [
                'order_uuid' => $order->uuid,
                'list' => $listName,
            ]),
        };

        Log::info('Order status updated from Trello', [
            'order_uuid' => $order->uuid,
            'list' => $listName,
            'status' => $order->status,
        ]);
    }

    /**
     * Handle checklist item completion
     */
    private function handleChecklistUpdate(array $payload): void
    {
        $action = $payload['action'] ?? [];
        $cardData = $action['data']['card'] ?? [];
        $cardName = $cardData['name'] ?? null;
        $itemName = $action['data']['checkItem']['name'] ?? null;
        $itemState = $action['data']['checkItem']['state'] ?? null;

        if ($itemState !== 'complete' || ! $cardName || ! $itemName) {
            return;
        }

        Log::debug('Trello checklist item completed', [
            'card' => $cardName,
            'item' => $itemName,
        ]);

        // TODO: Map checklist completions to domain events if needed
        // For now, just log for visibility
    }

    /**
     * Handle "Ready to Ship" intent
     * 
     * Emit event to trigger shipment creation flow
     */
    private function handleReadyToShipIntent($order, string $cardId): void
    {
        Log::info('Ready to Ship intent from Trello', [
            'order_uuid' => $order->uuid,
            'card_id' => $cardId,
        ]);

        // Emit event so ShippingController can validate and create shipment
        ReadyToShipIntent::dispatch($order);
    }

    /**
     * Handle "Awaiting Collection" intent
     * 
     * Verify shipment exists before accepting transition
     */
    private function handleAwaitingCollectionIntent($order, string $cardId): void
    {
        Log::info('Awaiting Collection intent from Trello', [
            'order_uuid' => $order->uuid,
            'card_id' => $cardId,
        ]);

        // Check if order has a waybill (shipment was created)
        if (! $order->courier_waybill_id) {
            Log::warning('Cannot move to Awaiting Collection - no shipment created', [
                'order_uuid' => $order->uuid,
            ]);
            return;
        }

        Log::info('Order ready for collection', [
            'order_uuid' => $order->uuid,
            'waybill_id' => $order->courier_waybill_id,
        ]);
    }
}
