<?php

namespace Alexr\Http\Controllers;

use Alexr\Models\Booking;
use Alexr\Models\Customer;
use Alexr\Models\WhatsappConversation;
use Alexr\Models\WhatsappMessage;
use Evavel\Eva;
use Evavel\Http\Controllers\Controller;
use Evavel\Http\Request\Request;

/**
 * Controller for WhatsApp Inbox Interface
 * Handles conversations list, messages, and sending messages
 */
class WhatsappInboxController extends Controller
{
    /**
     * Get list of conversations with last message preview
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function conversations(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $tenantId = $request->tenantId();
        $perPage = $request->params['per_page'] ?? 25;
        $page = $request->params['page'] ?? 1;
        $filter = $request->params['filter'] ?? 'all'; // all, unread, today
        $search = $request->params['search'] ?? null;

        // Base query
        $query = WhatsappConversation::where('restaurant_id', $tenantId)
            ->orderBy('last_message_at', 'DESC');

        // Apply filters
        if ($filter === 'unread') {
            $query->where('unread_count', '>', 0);
        } elseif ($filter === 'today') {
            $query->where('last_message_at', '>=', date('Y-m-d 00:00:00'));
        }

        // Apply search
        if ($search) {
            $query->where(function($q) use ($search) {
                $q->where('phone', 'LIKE', "%{$search}%")
                  ->orWhere('profile_name', 'LIKE', "%{$search}%");
            });
        }

        // Get paginated results
        $conversations = $query->page($page, $perPage)->get();

        // Enrich conversations with additional data
        $enrichedConversations = [];
        foreach ($conversations as $conversation) {
            $data = $conversation->toArray();
            
            // Get last message
            $lastMessage = WhatsappMessage::where('conversation_id', $conversation->id)
                ->orderBy('date_created', 'DESC')
                ->first();
            
            if ($lastMessage) {
                $data['last_message'] = [
                    'body' => $this->truncateMessage($lastMessage->body, 50),
                    'direction' => $lastMessage->direction,
                    'date_created' => $lastMessage->date_created,
                ];
            }

            // Get customer info if linked
            if ($conversation->customer_id) {
                $customer = Customer::find($conversation->customer_id);
                if ($customer) {
                    $data['customer'] = [
                        'id' => $customer->id,
                        'name' => $customer->name,
                        'email' => $customer->email,
                        'is_vip' => $customer->isVip,
                    ];
                }
            }

            // Get next booking for this phone/customer
            $data['next_booking'] = $this->getNextBooking($tenantId, $conversation);

            $enrichedConversations[] = $data;
        }

        // Get total count for pagination
        $totalQuery = WhatsappConversation::where('restaurant_id', $tenantId);
        if ($filter === 'unread') {
            $totalQuery->where('unread_count', '>', 0);
        }
        $total = $totalQuery->count();

        // Get unread count for badge
        $totalUnread = WhatsappConversation::where('restaurant_id', $tenantId)
            ->where('unread_count', '>', 0)
            ->count();

        return $this->response([
            'success' => true,
            'conversations' => $enrichedConversations,
            'pagination' => [
                'total' => $total,
                'per_page' => $perPage,
                'page' => $page,
                'total_pages' => ceil($total / $perPage),
            ],
            'total_unread' => $totalUnread,
        ]);
    }

    /**
     * Get messages for a specific conversation
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function messages(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $conversationId = $request->params['conversation_id'] ?? null;
        if (!$conversationId) {
            return $this->response(['success' => false, 'error' => __eva("Conversation ID required.")]);
        }

        $conversation = WhatsappConversation::find($conversationId);
        if (!$conversation || $conversation->restaurant_id != $request->tenantId()) {
            return $this->response(['success' => false, 'error' => __eva("Conversation not found.")]);
        }

        // Mark as read
        $conversation->markAsRead();

        // Get messages
        $perPage = $request->params['per_page'] ?? 50;
        $page = $request->params['page'] ?? 1;

        $messages = WhatsappMessage::where('conversation_id', $conversationId)
            ->orderBy('date_created', 'DESC')
            ->page($page, $perPage)
            ->get();

        // Reverse to show oldest first in chat
        $messages = array_reverse($messages->toArray());

        // Get conversation details with customer and booking
        $conversationData = $conversation->toArray();
        
        if ($conversation->customer_id) {
            $customer = Customer::find($conversation->customer_id);
            if ($customer) {
                $conversationData['customer'] = [
                    'id' => $customer->id,
                    'name' => $customer->name,
                    'email' => $customer->email,
                    'phone' => $customer->phone,
                    'is_vip' => $customer->isVip,
                ];
            }
        }

        $conversationData['next_booking'] = $this->getNextBooking($request->tenantId(), $conversation);

        return $this->response([
            'success' => true,
            'conversation' => $conversationData,
            'messages' => $messages,
            'has_more' => count($messages) >= $perPage,
        ]);
    }

    /**
     * Send a message to a conversation
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function sendMessage(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $conversationId = $request->body_params['conversation_id'] ?? null;
        $body = $request->body_params['body'] ?? null;

        if (!$conversationId || !$body) {
            return $this->response(['success' => false, 'error' => __eva("Conversation ID and message body required.")]);
        }

        $conversation = WhatsappConversation::find($conversationId);
        if (!$conversation || $conversation->restaurant_id != $request->tenantId()) {
            return $this->response(['success' => false, 'error' => __eva("Conversation not found.")]);
        }

        // Check if window is open
        if (!$conversation->isWindowOpen) {
            return $this->response([
                'success' => false, 
                'error' => __eva("The 24-hour messaging window has expired. You can only send template messages."),
                'window_expired' => true,
            ]);
        }

        // Create message record
        $message = WhatsappMessage::create([
            'restaurant_id' => $request->tenantId(),
            'conversation_id' => $conversation->id,
            'customer_id' => $conversation->customer_id,
            'direction' => WhatsappMessage::DIRECTION_OUTBOUND,
            'type' => WhatsappMessage::TYPE_TEXT,
            'phone' => $conversation->phone,
            'phone_normalized' => $conversation->phone_normalized,
            'body' => $body,
            'status' => WhatsappMessage::STATUS_QUEUED,
        ]);

        // TODO: Actually send via Twilio
        // This would integrate with WhatsappTwilioManager
        
        // For now, just update conversation
        $conversation->markOutbound();

        return $this->response([
            'success' => true,
            'message' => $message->toArray(),
        ]);
    }

    /**
     * Mark conversation as read
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function markAsRead(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $conversationId = $request->body_params['conversation_id'] ?? null;
        if (!$conversationId) {
            return $this->response(['success' => false, 'error' => __eva("Conversation ID required.")]);
        }

        $conversation = WhatsappConversation::find($conversationId);
        if (!$conversation || $conversation->restaurant_id != $request->tenantId()) {
            return $this->response(['success' => false, 'error' => __eva("Conversation not found.")]);
        }

        $conversation->markAsRead();

        return $this->response(['success' => true]);
    }

    /**
     * Get total unread count (for header badge)
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function unreadCount(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $count = WhatsappConversation::where('restaurant_id', $request->tenantId())
            ->where('unread_count', '>', 0)
            ->sum('unread_count');

        return $this->response([
            'success' => true,
            'unread_count' => $count,
        ]);
    }

    /**
     * Link conversation to a customer
     * 
     * @param Request $request
     * @return \WP_REST_Response
     */
    public function linkCustomer(Request $request)
    {
        $user = Eva::make('user');
        if (!$user->canManage($request->tenant)) {
            return $this->response(['success' => false, 'error' => __eva("You cannot access.")]);
        }

        $conversationId = $request->body_params['conversation_id'] ?? null;
        $customerId = $request->body_params['customer_id'] ?? null;

        if (!$conversationId || !$customerId) {
            return $this->response(['success' => false, 'error' => __eva("Conversation ID and Customer ID required.")]);
        }

        $conversation = WhatsappConversation::find($conversationId);
        if (!$conversation || $conversation->restaurant_id != $request->tenantId()) {
            return $this->response(['success' => false, 'error' => __eva("Conversation not found.")]);
        }

        $customer = Customer::find($customerId);
        if (!$customer || $customer->restaurant_id != $request->tenantId()) {
            return $this->response(['success' => false, 'error' => __eva("Customer not found.")]);
        }

        $conversation->linkToCustomer($customerId);

        return $this->response([
            'success' => true,
            'conversation' => $conversation->toArray(),
        ]);
    }

    // -------------------------------------------------------------------------
    // Helper Methods
    // -------------------------------------------------------------------------

    /**
     * Get next booking for a conversation
     */
    protected function getNextBooking(int $restaurantId, WhatsappConversation $conversation): ?array
    {
        $query = Booking::where('restaurant_id', $restaurantId)
            ->where('date', '>=', date('Y-m-d'))
            ->whereIn('status', ['pending', 'booked', 'confirmed'])
            ->orderBy('date', 'ASC')
            ->orderBy('time', 'ASC');

        // Try by customer first
        if ($conversation->customer_id) {
            $booking = (clone $query)->where('customer_id', $conversation->customer_id)->first();
            if ($booking) {
                return $this->formatBookingPreview($booking);
            }
        }

        // Try by phone
        if ($conversation->phone_normalized) {
            $phoneSuffix = substr(preg_replace('/[^0-9]/', '', $conversation->phone_normalized), -9);
            $booking = $query->where('phone', 'LIKE', '%' . $phoneSuffix)->first();
            if ($booking) {
                return $this->formatBookingPreview($booking);
            }
        }

        return null;
    }

    /**
     * Format booking for preview
     */
    protected function formatBookingPreview(Booking $booking): array
    {
        return [
            'id' => $booking->id,
            'date' => $booking->date,
            'time' => $booking->time,
            'time_formatted' => evavel_seconds_to_Hm($booking->time),
            'party' => $booking->party,
            'status' => $booking->status,
            'name' => $booking->name,
            'is_today' => $booking->date === date('Y-m-d'),
        ];
    }

    /**
     * Truncate message for preview
     */
    protected function truncateMessage(?string $message, int $length = 50): string
    {
        if (!$message) {
            return '';
        }
        
        if (strlen($message) <= $length) {
            return $message;
        }

        return substr($message, 0, $length) . '...';
    }
}
