<?php
require_once '../config/cors.php';
header('Content-Type: application/json');

require_once '../config/db.php';
require_once '../includes/EmailSender.php';

$raw = file_get_contents('php://input');
$data = json_decode($raw, true);

if (!$data || empty($data['from_user_id']) || empty($data['subject'])) {
    echo json_encode(['status' => 'error', 'message' => 'Missing required fields: from_user_id, subject']);
    exit;
}

$parentId = isset($data['parent_id']) ? (int) $data['parent_id'] : null;
if (!$parentId && empty($data['recipient_type'])) {
    echo json_encode(['status' => 'error', 'message' => 'recipient_type is required for new messages']);
    exit;
}

$fromUserId = (int) $data['from_user_id'];
$rawRecipientType = trim($data['recipient_type'] ?? '');
$subject = trim($data['subject']);
$body = isset($data['body']) ? trim($data['body']) : '';
$recipientIds = isset($data['recipient_user_ids']) && is_array($data['recipient_user_ids'])
    ? array_map('intval', $data['recipient_user_ids']) : [];
$canReply = isset($data['can_reply']) ? (int) $data['can_reply'] : 1;

// Map frontend types to backend logic
$recipientType = $rawRecipientType;
if ($recipientType === 'specific_members') {
    $recipientType = 'specific';
} elseif ($recipientType === 'area_members') {
    $recipientType = 'area_members_or_specific';
}
// parentId already extracted above

try {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS notification_messages (
            id INT AUTO_INCREMENT PRIMARY KEY,
            parent_id INT NULL DEFAULT NULL,
            from_user_id INT NOT NULL,
            subject VARCHAR(255) NOT NULL,
            body TEXT NOT NULL,
            can_reply TINYINT(1) DEFAULT 1,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (from_user_id) REFERENCES users(id) ON DELETE CASCADE,
            FOREIGN KEY (parent_id) REFERENCES notification_messages(id) ON DELETE CASCADE
        )
    ");
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS notification_recipients (
            id INT AUTO_INCREMENT PRIMARY KEY,
            notification_id INT NOT NULL,
            user_id INT NOT NULL,
            read_at TIMESTAMP NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY unique_notif_recipient (notification_id, user_id),
            FOREIGN KEY (notification_id) REFERENCES notification_messages(id) ON DELETE CASCADE,
            FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
        )
    ");

    $stmt = $pdo->prepare("SELECT id, role, area FROM users WHERE id = ? AND status = 'approved'");
    $stmt->execute([$fromUserId]);
    $sender = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$sender) {
        echo json_encode(['status' => 'error', 'message' => 'Sender not found or not approved']);
        exit;
    }

    $role = strtoupper(trim($sender['role'] ?? ''));
    $area = $sender['area'] ?? '';

    $recipientUserIds = [];

    if ($parentId > 0) {
        // If it's a reply, find the root of the thread and collect ALL participants.
        // We cannot just use the direct parent's sender because when replying from the Sent
        // tab, the parent was sent BY the current user — so we'd get back themselves as the
        // only recipient, which gets filtered out.

        // 1. Walk up to the root of the thread
        $rootMsgId = $parentId;
        for ($i = 0; $i < 20; $i++) {
            $s = $pdo->prepare("SELECT id, parent_id FROM notification_messages WHERE id = ?");
            $s->execute([$rootMsgId]);
            $row = $s->fetch(PDO::FETCH_ASSOC);
            if ($row && $row['parent_id']) {
                $rootMsgId = (int) $row['parent_id'];
            } else {
                break;
            }
        }

        // 2. Collect all senders in the thread (root + all descendants) using recursive CTE
        $s = $pdo->prepare("
            WITH RECURSIVE thread_tree AS (
                SELECT id, from_user_id FROM notification_messages WHERE id = ?
                UNION ALL
                SELECT nm.id, nm.from_user_id FROM notification_messages nm
                JOIN thread_tree tt ON nm.parent_id = tt.id
            )
            SELECT DISTINCT from_user_id FROM thread_tree
        ");
        $s->execute([$rootMsgId]);
        while ($row = $s->fetch(PDO::FETCH_ASSOC)) {
            $recipientUserIds[] = (int) $row['from_user_id'];
        }

        // 3. Also include original recipients of the root message (in case they never replied)
        $s = $pdo->prepare("SELECT DISTINCT user_id FROM notification_recipients WHERE notification_id = ?");
        $s->execute([$rootMsgId]);
        while ($row = $s->fetch(PDO::FETCH_ASSOC)) {
            $recipientUserIds[] = (int) $row['user_id'];
        }

        if (empty($recipientUserIds)) {
            echo json_encode(['status' => 'error', 'message' => 'Parent message not found or thread is empty']);
            exit;
        }
    } elseif ($role === 'R.O' || $role === 'C.R.O' || $role === '') {
        // Member: can only notify AC and AAC in same area
        if ($recipientType !== 'ac_aac_same_area') {
            echo json_encode(['status' => 'error', 'message' => 'Members can only send to AC/AAC in the same area']);
            exit;
        }
        if (empty($area)) {
            echo json_encode(['status' => 'error', 'message' => 'Your area is not set']);
            exit;
        }
        $stmt = $pdo->prepare("SELECT id FROM users WHERE status = 'approved' AND area = ? AND UPPER(TRIM(role)) IN ('AC', 'AAC')");
        $stmt->execute([$area]);
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $recipientUserIds[] = (int) $row['id'];
        }
    } elseif ($role === 'AC' || $role === 'AAC') {
        // AC/AAC: can notify members (same area), all members (all areas), or specific members (same area)
        if ($recipientType === 'all_members') {
            $stmt = $pdo->query("SELECT id FROM users WHERE status = 'approved' AND (UPPER(TRIM(role)) IN ('R.O', 'C.R.O') OR role = '' OR role IS NULL)");
            if ($stmt) {
                while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                    $recipientUserIds[] = (int) $row['id'];
                }
            }
        } elseif (($recipientType === 'area_members' || $recipientType === 'area_members_or_specific') && empty($recipientIds)) {
            if (empty($area)) {
                echo json_encode(['status' => 'error', 'message' => 'Your area is not set']);
                exit;
            }
            $stmt = $pdo->prepare("SELECT id FROM users WHERE status = 'approved' AND area = ? AND (UPPER(TRIM(role)) IN ('R.O', 'C.R.O') OR role = '' OR role IS NULL)");
            $stmt->execute([$area]);
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                $recipientUserIds[] = (int) $row['id'];
            }
        } elseif (($recipientType === 'specific' || $recipientType === 'area_members_or_specific') && !empty($recipientIds)) {
            if (empty($area)) {
                echo json_encode(['status' => 'error', 'message' => 'Your area is not set']);
                exit;
            }
            $placeholders = implode(',', array_fill(0, count($recipientIds), '?'));
            // Still restrict to same area for AC/AAC
            $stmt = $pdo->prepare("SELECT id FROM users WHERE status = 'approved' AND area = ? AND id IN ($placeholders)");
            $stmt->execute(array_merge([$area], $recipientIds));
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                $recipientUserIds[] = (int) $row['id'];
            }
        } else {
            echo json_encode(['status' => 'error', 'message' => 'Invalid recipient_type for AC/AAC. Use area_members, all_members, or specific with recipient_user_ids.']);
            exit;
        }
    } else {
        echo json_encode(['status' => 'error', 'message' => 'Your role cannot send notifications']);
        exit;
    }

    $recipientUserIds = array_unique(array_filter($recipientUserIds, function ($id) use ($fromUserId) {
        return $id !== $fromUserId;
    }));
    if (empty($recipientUserIds)) {
        echo json_encode(['status' => 'error', 'message' => 'No valid recipients found']);
        exit;
    }

    $pdo->beginTransaction();
    $stmt = $pdo->prepare("INSERT INTO notification_messages (parent_id, from_user_id, subject, body, can_reply) VALUES (?, ?, ?, ?, ?)");
    $stmt->execute([$parentId, $fromUserId, $subject, $body, $canReply]);
    $notificationId = (int) $pdo->lastInsertId();

    $stmtRec = $pdo->prepare("INSERT INTO notification_recipients (notification_id, user_id) VALUES (?, ?)");
    foreach ($recipientUserIds as $uid) {
        $stmtRec->execute([$notificationId, $uid]);
    }
    $pdo->commit();

    // --- Send success response immediately before doing email work ---
    $responsePayload = json_encode([
        'status' => 'success',
        'message' => 'Notification sent',
        'notification_id' => $notificationId,
        'recipient_count' => count($recipientUserIds),
    ]);
    echo $responsePayload;

    // Flush so the client gets the response without waiting for emails
    if (function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request();
    } else {
        ob_flush();
        flush();
    }

    // --- Send email notifications to each recipient ---
    $isReply = ($parentId > 0);

    // Get sender display name
    $stmtSender = $pdo->prepare("SELECT first_name, last_name, role FROM users WHERE id = ?");
    $stmtSender->execute([$fromUserId]);
    $senderRow = $stmtSender->fetch(PDO::FETCH_ASSOC);
    $senderFullName = $senderRow
        ? trim(($senderRow['first_name'] ?? '') . ' ' . ($senderRow['last_name'] ?? ''))
        : 'NROI Member';
    $senderRoleUC = strtoupper(trim($senderRow['role'] ?? ''));
    $senderIsOfficer = in_array($senderRoleUC, ['AC', 'AAC']);

    // Fetch each recipient's email + name
    if (!empty($recipientUserIds)) {
        $placeholders = implode(',', array_fill(0, count($recipientUserIds), '?'));
        $stmtEmails = $pdo->prepare(
            "SELECT id, email, first_name, last_name, role FROM users WHERE id IN ($placeholders) AND email IS NOT NULL AND email != ''"
        );
        $stmtEmails->execute(array_values($recipientUserIds));
        $emailRows = $stmtEmails->fetchAll(PDO::FETCH_ASSOC);

        foreach ($emailRows as $recipient) {
            if (empty($recipient['email']))
                continue;

            $recipientName = trim(($recipient['first_name'] ?? '') . ' ' . ($recipient['last_name'] ?? ''));
            if (empty($recipientName))
                $recipientName = 'NROI Member';

            $recipientRoleUC = strtoupper(trim($recipient['role'] ?? ''));
            $recipientIsMember = ($recipientRoleUC === 'R.O' || $recipientRoleUC === 'C.R.O' || $recipientRoleUC === '');

            // Apply same anonymisation as inbox display:
            // Members see officer senders as 'AC/AAC'
            $displaySenderName = ($recipientIsMember && $senderIsOfficer) ? 'AC/AAC' : $senderFullName;

            sendInboxMessageNotification(
                $recipient['email'],
                $recipientName,
                $displaySenderName,
                $subject,
                $body,
                $isReply
            );
        }
    }

} catch (Exception $e) {
    if ($pdo->inTransaction())
        $pdo->rollBack();
    echo json_encode(['status' => 'error', 'message' => 'Server error: ' . $e->getMessage()]);
}
