<?php

declare(strict_types=1);

namespace App\Modules\Engagement;

use App\Core\BaseController;
use App\Core\Request;
use App\Core\Session;
use App\Core\Database;
use App\Modules\Guest\GuestModel;
use App\Modules\Invitation\InvitationModel;
use App\Modules\Messaging\MessageModel;
use App\Modules\Messaging\MessageTemplateService;
use App\Modules\Messaging\MessageDeliveryService;
use App\Modules\PublicInvitation\PublicInvitationService;

/**
 * EngagementController — Handles Guest RSVP tracking, Wishes, and WhatsApp Queues.
 *
 * Scopes data security to the authenticated Couple's active workspace.
 *
 * @package Inveetaire
 * @ref     RC-014
 */
class EngagementController extends BaseController
{
    protected string $layout = 'couple';
    private GuestModel $guestModel;
    private InvitationModel $invitationModel;
    private MessageModel $messageModel;
    private MessageTemplateService $templateService;
    private MessageDeliveryService $deliveryService;
    private PublicInvitationService $publicInvitationService;

    public function __construct()
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $this->layout = $role;

        parent::__construct();
        $this->guestModel = new GuestModel();
        $this->invitationModel = new InvitationModel();
        $this->messageModel = new MessageModel();
        $this->templateService = new MessageTemplateService();
        $this->deliveryService = new MessageDeliveryService();
        $this->publicInvitationService = new PublicInvitationService();
    }

    /**
     * Show the RSVP monitoring center dashboard.
     * Route: GET /app/couple/engagement/rsvp
     *
     * @param Request $request
     * @return void
     */
    public function showRsvpCenter(Request $request): void
    {
        if ($request->get('ajax') === '1') {
            $this->layout = 'ajax';
        }
        $workspaceId = (int) Session::get('active_workspace_id');

        // Extract search/filter params
        $search = trim((string) $request->get('search'));
        $rsvp = trim((string) $request->get('rsvp')); // attending | declined | pending
        $group = trim((string) $request->get('group'));

        $filters = [];
        if ($search !== '') $filters['search'] = $search;
        if ($rsvp !== '') $filters['rsvp'] = $rsvp;
        if ($group !== '') $filters['group'] = $group;

        // Pagination setup
        $page = max(1, (int) $request->get('page', 1));
        $limit = 10;
        $offset = ($page - 1) * $limit;

        // Fetch counts for KPI widgets (reuse GuestModel statistics)
        $totalGuests = $this->guestModel->getGuestsCount($workspaceId);
        $confirmedCount = $this->guestModel->getGuestsCount($workspaceId, ['rsvp' => 'attending']);
        $declinedCount = $this->guestModel->getGuestsCount($workspaceId, ['rsvp' => 'declined']);
        $pendingCount = $this->guestModel->getGuestsCount($workspaceId, ['rsvp' => 'pending']);

        // Fetch data
        $guests = $this->guestModel->getGuests($workspaceId, $filters, $limit, $offset);
        $totalFiltered = $this->guestModel->getGuestsCount($workspaceId, $filters);
        $totalPages = (int) ceil($totalFiltered / $limit);

        // Fetch distinct groups for filter dropdown
        $groups = $this->guestModel->getDistinctGroups($workspaceId);

        $this->render('engagement/rsvp_center', [
            'title'          => 'RSVP Center',
            'guests'         => $guests,
            'groups'         => $groups,
            'search'         => $search,
            'rsvp'           => $rsvp,
            'group'          => $group,
            'page'           => $page,
            'totalPages'     => $totalPages,
            'totalFiltered'  => $totalFiltered,
            'stats'          => [
                'expected'  => $totalGuests,
                'confirmed' => $confirmedCount,
                'declined'  => $declinedCount,
                'pending'   => $pendingCount
            ],
            'success'        => Session::get('success') ?? null,
            'errors'         => Session::get('errors') ?? []
        ]);

        Session::set('success', null);
        Session::set('errors', null);
    }

    /**
     * Show the Guest Wishes moderation page.
     * Route: GET /app/couple/engagement/wishes
     *
     * @param Request $request
     * @return void
     */
    /**
     * Show the Guest Wishes moderation page.
     * Route: GET /app/couple/engagement/wishes
     *
     * @param Request $request
     * @return void
     */
    public function showWishes(Request $request): void
    {
        if ($request->get('ajax') === '1') {
            $this->layout = 'ajax';
        }
        $workspaceId = (int) Session::get('active_workspace_id');

        $search = trim((string) $request->get('search'));
        $sort = trim((string) $request->get('sort', 'newest')); // newest | oldest
        $status = trim((string) $request->get('status', 'all')); // all | pending | approved | rejected

        $filters = [
            'sort'   => $sort,
            'status' => $status
        ];
        if ($search !== '') $filters['search'] = $search;

        $page = max(1, (int) $request->get('page', 1));
        $limit = 10;
        $offset = ($page - 1) * $limit;

        $wishes = $this->invitationModel->getWishesFiltered($workspaceId, $filters, $limit, $offset);
        $totalFiltered = $this->invitationModel->getWishesCountFiltered($workspaceId, $filters);
        $totalPages = (int) ceil($totalFiltered / $limit);

        // Fetch counts for moderation status tabs
        $allCount = $this->invitationModel->getWishesCountFiltered($workspaceId, ['status' => 'all']);
        $pendingCount = $this->invitationModel->getWishesCountFiltered($workspaceId, ['status' => 'pending']);
        $approvedCount = $this->invitationModel->getWishesCountFiltered($workspaceId, ['status' => 'approved']);
        $rejectedCount = $this->invitationModel->getWishesCountFiltered($workspaceId, ['status' => 'rejected']);

        $this->render('engagement/wishes', [
            'title'          => 'Guest Book & Wishes Moderation',
            'wishes'         => $wishes,
            'search'         => $search,
            'sort'           => $sort,
            'status'         => $status,
            'page'           => $page,
            'totalPages'     => $totalPages,
            'totalFiltered'  => $totalFiltered,
            'stats'          => [
                'all'      => $allCount,
                'pending'  => $pendingCount,
                'approved' => $approvedCount,
                'rejected' => $rejectedCount
            ],
            'success'        => Session::get('success') ?? null,
            'errors'         => Session::get('errors') ?? []
        ]);

        Session::set('success', null);
        Session::set('errors', null);
    }

    /**
     * Approve a guest wish.
     * Route: POST /app/couple/engagement/wishes/approve/{id}
     *
     * @param Request $request
     * @return void
     */
    public function approveWish(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');
        $userId = (int) Session::get('user_id');
        $wishId = (int) $request->param('id');

        $this->invitationModel->updateWishStatus($workspaceId, $wishId, 'approved', $userId);
        Session::set('success', 'Wish approved and published successfully.');
        $this->redirect("/app/{$role}/engagement/wishes");
    }

    /**
     * Reject a guest wish.
     * Route: POST /app/couple/engagement/wishes/reject/{id}
     *
     * @param Request $request
     * @return void
     */
    public function rejectWish(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');
        $userId = (int) Session::get('user_id');
        $wishId = (int) $request->param('id');

        $this->invitationModel->updateWishStatus($workspaceId, $wishId, 'rejected', $userId);
        Session::set('success', 'Wish rejected.');
        $this->redirect("/app/{$role}/engagement/wishes");
    }

    /**
     * Delete a guest wish.
     * Route: POST /app/couple/engagement/wishes/delete/{id}
     *
     * @param Request $request
     * @return void
     */
    public function deleteWish(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');
        $wishId = (int) $request->param('id');

        $this->invitationModel->deleteWish($workspaceId, $wishId);
        Session::set('success', 'Wish removed.');
        $this->redirect("/app/{$role}/engagement/wishes");
    }

    /**
     * Show the manual WhatsApp sending queue.
     * Route: GET /app/couple/engagement/whatsapp-queue
     *
     * @param Request $request
     * @return void
     */
    public function showWhatsAppQueue(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');

        $search = trim((string) $request->get('search'));
        $status = trim((string) $request->get('status', 'not_sent')); // not_sent | sent | all

        $workspace = $this->messageModel->getWorkspace($workspaceId);
        if ($workspace === null) {
            $this->flash('error', 'Active workspace not found.');
            $this->redirect("/app/{$role}/dashboard");
            return;
        }

        $invitation = $this->messageModel->getInvitation($workspaceId);

        // Fetch template or default
        $template = $this->messageModel->getTemplate($workspaceId, 'invitation');
        $defaultText = "Dear {{guest_name}},\n\nWe joyfully invite you to celebrate our wedding.\n\nPlease find your personal digital invitation pass below:\n{{invitation_url}}\n\n{{holy_information}}\n\n{{reception_information}}\n\nThank you,\n{{couple_name}}";
        $templateText = $template ? $template['body_text'] : $defaultText;

        // Fetch events context
        $allEvents = $this->messageModel->getWeddingEvents($workspaceId);

        // Custom query to support invitation_status filtering and search
        $db = Database::getConnection();
        $sql = '
            SELECT id, guest_code, full_name, phone_number, guest_group, invited_pax, invitation_status 
            FROM guests 
            WHERE workspace_id = :workspace_id 
              AND is_deleted = 0
        ';
        $params = ['workspace_id' => $workspaceId];

        if ($status !== 'all') {
            $sql .= ' AND invitation_status = :status';
            $params['status'] = $status;
        }

        if ($search !== '') {
            $sql .= ' AND (full_name LIKE :search1 OR phone_number LIKE :search2)';
            $params['search1'] = '%' . $search . '%';
            $params['search2'] = '%' . $search . '%';
        }

        $sql .= ' ORDER BY full_name ASC';
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $rawGuests = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $compiledQueue = [];
        foreach ($rawGuests as $g) {
            $assignedEventIds = $this->messageModel->getAssignedEventIds($workspaceId, (int) $g['id']);
            $personalUrl = $this->publicInvitationService->generatePersonalUrl($workspace['slug'], $g['guest_code']);

            $message = $this->templateService->compileMessage(
                $templateText,
                $g,
                $workspace,
                $invitation,
                $allEvents,
                $assignedEventIds,
                $personalUrl
            );

            $whatsappUrl = '';
            if (!empty($g['phone_number'])) {
                $whatsappUrl = $this->deliveryService->generateWhatsAppUrl($g['phone_number'], $message);
            }

            $compiledQueue[] = [
                'id'                => $g['id'],
                'full_name'         => $g['full_name'],
                'phone_number'      => $g['phone_number'],
                'guest_group'       => $g['guest_group'],
                'invited_pax'       => $g['invited_pax'],
                'invitation_status' => $g['invitation_status'],
                'message'           => $message,
                'whatsapp_url'      => $whatsappUrl,
                'personal_url'      => $personalUrl
            ];
        }

        // Fetch counts for sub-header queue tabs
        $stmtCounts = $db->prepare('
            SELECT 
                SUM(CASE WHEN invitation_status = \'not_sent\' THEN 1 ELSE 0 END) as pending_count,
                SUM(CASE WHEN invitation_status = \'sent\' THEN 1 ELSE 0 END) as sent_count
            FROM guests 
            WHERE workspace_id = :workspace_id AND is_deleted = 0
        ');
        $stmtCounts->execute(['workspace_id' => $workspaceId]);
        $counts = $stmtCounts->fetch(\PDO::FETCH_ASSOC);

        $this->render('engagement/whatsapp_queue', [
            'title'          => 'WhatsApp Distribution Queue',
            'queue'          => $compiledQueue,
            'search'         => $search,
            'status'         => $status,
            'pending_count'  => (int) ($counts['pending_count'] ?? 0),
            'sent_count'     => (int) ($counts['sent_count'] ?? 0),
            'success'        => Session::get('success') ?? null,
            'errors'         => Session::get('errors') ?? []
        ]);

        Session::set('success', null);
        Session::set('errors', null);
    }

    /**
     * Mark a guest's invitation as Sent.
     * Route: POST /app/couple/engagement/whatsapp-queue/mark-sent/{id}
     *
     * @param Request $request
     * @return void
     */
    public function markSent(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');
        $guestId = (int) $request->param('id');

        $db = Database::getConnection();
        $stmt = $db->prepare('
            UPDATE guests 
            SET invitation_status = \'sent\', 
                updated_at = CURRENT_TIMESTAMP 
            WHERE id = :id AND workspace_id = :workspace_id AND is_deleted = 0
        ');
        $stmt->execute([
            'id'           => $guestId,
            'workspace_id' => $workspaceId
        ]);

        Session::set('success', 'Invitation marked as sent.');
        $this->redirect("/app/{$role}/engagement/whatsapp-queue");
    }

    /**
     * Reset all guests' invitation status to 'not_sent' to regenerate the sending queue.
     * Route: POST /app/couple/engagement/whatsapp-queue/reset
     *
     * @param Request $request
     * @return void
     */
    public function resetQueue(Request $request): void
    {
        $role = Session::get('role_snapshot') === 'crew' ? 'crew' : 'couple';
        $workspaceId = (int) Session::get('active_workspace_id');

        $db = Database::getConnection();
        $stmt = $db->prepare('
            UPDATE guests 
            SET invitation_status = \'not_sent\', 
                updated_at = CURRENT_TIMESTAMP 
            WHERE workspace_id = :workspace_id AND is_deleted = 0
        ');
        $stmt->execute(['workspace_id' => $workspaceId]);

        Session::set('success', 'WhatsApp distribution queue regenerated successfully.');
        $this->redirect("/app/{$role}/engagement/whatsapp-queue");
    }
}
