<?php
namespace App\Controllers;

use App\Core\Controller;
use App\Core\Auth;
use App\Core\Request;
use App\Core\Response;
use App\Models\Contact;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\Deal;
use App\Models\PipelineStage;
use App\Models\Tag;
use App\Models\QuickReply;
use App\Models\WhatsAppTemplate;
use App\Models\User;
use App\Services\WhatsAppService;

class ChatController extends Controller {
    public function index(): void {
        $stages = PipelineStage::getOrdered();
        $tags = Tag::all('name ASC');
        $agents = User::getActiveAgents();
        $templates = WhatsAppTemplate::getApproved();
        $quickReplies = QuickReply::all('shortcut ASC');

        $this->render('chat/index', [
            'stages'       => $stages,
            'tags'         => $tags,
            'agents'       => $agents,
            'templates'    => $templates,
            'quickReplies' => $quickReplies
        ]);
    }

    public function getInbox(): void {
        $status = Request::get('status', 'all');
        $search = Request::get('search');
        $filterAgent = Request::get('agent_id');

        $userId = !empty($filterAgent) ? (int)$filterAgent : null;
        if (!Auth::isAdmin() && empty($filterAgent)) {
            // For non-admin agents, optionally allow viewing all or filtering
        }

        $conversations = Conversation::getInboxList($userId, $status, $search);
        Response::success($conversations);
    }

    public function getConversationData(int $id): void {
        $conversation = Conversation::find($id);
        if (!$conversation) {
            Response::error('Conversation not found', 404);
        }

        $contact = Contact::getWithDetails((int)$conversation['contact_id']);
        $messages = Message::getByConversation($id, 100);
        $deals = Deal::getByContact((int)$conversation['contact_id']);

        // Auto mark as read
        Conversation::markAsRead($id);

        Response::success([
            'conversation' => $conversation,
            'contact'      => $contact,
            'messages'     => $messages,
            'deals'        => $deals
        ]);
    }

    public function sendMessage(): void {
        $conversationId = (int)Request::post('conversation_id');
        $text = trim(Request::post('message', ''));
        $messageType = Request::post('message_type', 'text');
        $mediaUrl = Request::post('media_url');

        if (empty($conversationId) || (empty($text) && empty($mediaUrl))) {
            Response::error('Message content or media is required.');
        }

        $conversation = Conversation::find($conversationId);
        if (!$conversation) {
            Response::error('Conversation not found.', 404);
        }

        $contact = Contact::find((int)$conversation['contact_id']);
        if (!$contact) {
            Response::error('Contact not found.', 404);
        }

        $userId = Auth::id();
        $metaMsgId = null;
        $status = 'sent';

        if ($messageType === 'text') {
            $apiRes = WhatsAppService::sendText($contact['phone_number'], $text);
            $metaMsgId = $apiRes['meta_message_id'] ?? null;
            if (!$apiRes['success']) {
                $status = 'failed';
            }
        } elseif (in_array($messageType, ['image', 'document', 'audio', 'video'])) {
            $apiRes = WhatsAppService::sendMedia($contact['phone_number'], $messageType, $mediaUrl, $text);
            $metaMsgId = $apiRes['meta_message_id'] ?? null;
            if (!$apiRes['success']) {
                $status = 'failed';
            }
        }

        // Store message
        $msgId = Message::create([
            'conversation_id' => $conversationId,
            'contact_id'      => (int)$contact['id'],
            'user_id'         => $userId,
            'direction'       => 'outbound',
            'message_type'    => $messageType,
            'content'         => $text ?: ($mediaUrl ? ucfirst($messageType) . ' attachment' : ''),
            'media_url'       => $mediaUrl,
            'meta_message_id' => $metaMsgId ?: ('out_' . uniqid()),
            'status'          => $status,
            'created_at'      => date('Y-m-d H:i:s')
        ]);

        Conversation::updateLastMessage($conversationId, $text ?: '[' . ucfirst($messageType) . ']', 'outbound');

        $createdMessage = Message::find($msgId);
        Response::success($createdMessage, 'Message sent successfully');
    }

    public function sendTemplate(): void {
        $conversationId = (int)Request::post('conversation_id');
        $templateName = Request::post('template_name');
        $language = Request::post('language', 'en_US');

        if (empty($conversationId) || empty($templateName)) {
            Response::error('Conversation and template name are required.');
        }

        $conversation = Conversation::find($conversationId);
        $contact = Contact::find((int)$conversation['contact_id']);

        $apiRes = WhatsAppService::sendTemplate($contact['phone_number'], $templateName, $language);

        $msgId = Message::create([
            'conversation_id' => $conversationId,
            'contact_id'      => (int)$contact['id'],
            'user_id'         => Auth::id(),
            'direction'       => 'outbound',
            'message_type'    => 'template',
            'content'         => "📋 Template: {$templateName}",
            'meta_message_id' => $apiRes['meta_message_id'] ?? ('tmpl_' . uniqid()),
            'status'          => $apiRes['success'] ? 'sent' : 'failed',
            'created_at'      => date('Y-m-d H:i:s')
        ]);

        Conversation::updateLastMessage($conversationId, "📋 Template: {$templateName}", 'outbound');

        Response::success(Message::find($msgId), 'Template message sent');
    }

    public function markRead(int $id): void {
        Conversation::markAsRead($id);
        Response::success(null, 'Conversation marked as read');
    }

    public function assignAgent(): void {
        $conversationId = (int)Request::post('conversation_id');
        $agentId = Request::post('agent_id') ? (int)Request::post('agent_id') : null;

        $conversation = Conversation::find($conversationId);
        if (!$conversation) {
            Response::error('Conversation not found');
        }

        Conversation::update($conversationId, ['assigned_user_id' => $agentId]);
        Contact::update((int)$conversation['contact_id'], ['assigned_to' => $agentId]);

        Response::success(null, 'Agent assigned successfully');
    }

    public function changeStatus(): void {
        $conversationId = (int)Request::post('conversation_id');
        $status = Request::post('status', 'open');

        Conversation::update($conversationId, ['status' => $status]);
        Response::success(null, 'Status updated');
    }

    public function uploadMedia(): void {
        if (empty($_FILES['file'])) {
            Response::error('No file uploaded');
        }

        $file = $_FILES['file'];
        if ($file['error'] !== UPLOAD_ERR_OK) {
            Response::error('File upload failed');
        }

        $uploadDir = dirname(__DIR__, 2) . '/public/uploads/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0777, true);
        }

        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $filename = 'media_' . date('Ymd_His') . '_' . uniqid() . '.' . $ext;
        $targetPath = $uploadDir . $filename;

        if (move_uploaded_file($file['tmp_name'], $targetPath)) {
            $url = '/uploads/' . $filename;
            Response::success([
                'url'      => $url,
                'filename' => $file['name'],
                'size'     => $file['size']
            ], 'File uploaded successfully');
        } else {
            Response::error('Failed to move uploaded file');
        }
    }
}
