<?php
/**
 * api/chat.php — StudyTrack Chat API
 * All actions via POST ?action=...
 */
ob_start();
require_once '../includes/config.php';

if (!isset($_SESSION['user_id'])) {
    ob_clean();
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'msg' => 'Not logged in.']);
    exit;
}

$me = (int)$_SESSION['user_id'];

// ── Ensure tables exist ──────────────────────────────────────────
try {
    $pdo->exec("CREATE TABLE IF NOT EXISTS `chat_conversations` (
      `id`         INT AUTO_INCREMENT PRIMARY KEY,
      `type`       ENUM('direct','group') NOT NULL DEFAULT 'direct',
      `name`       VARCHAR(100) DEFAULT NULL,
      `avatar`     VARCHAR(255) DEFAULT NULL,
      `created_by` INT NOT NULL,
      `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE CASCADE
    ) ENGINE=InnoDB;");

    $pdo->exec("CREATE TABLE IF NOT EXISTS `chat_members` (
      `id`              INT AUTO_INCREMENT PRIMARY KEY,
      `conversation_id` INT NOT NULL,
      `user_id`         INT NOT NULL,
      `role`            ENUM('member','admin') DEFAULT 'member',
      `joined_at`       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      `last_read_at`    TIMESTAMP NULL DEFAULT NULL,
      UNIQUE KEY `unique_member` (`conversation_id`, `user_id`),
      FOREIGN KEY (`conversation_id`) REFERENCES `chat_conversations`(`id`) ON DELETE CASCADE,
      FOREIGN KEY (`user_id`)         REFERENCES `users`(`id`)              ON DELETE CASCADE
    ) ENGINE=InnoDB;");

    $pdo->exec("CREATE TABLE IF NOT EXISTS `chat_messages` (
      `id`              INT AUTO_INCREMENT PRIMARY KEY,
      `conversation_id` INT NOT NULL,
      `sender_id`       INT NOT NULL,
      `body`            TEXT NOT NULL,
      `is_deleted`      TINYINT(1) DEFAULT 0,
      `created_at`      TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      FOREIGN KEY (`conversation_id`) REFERENCES `chat_conversations`(`id`) ON DELETE CASCADE,
      FOREIGN KEY (`sender_id`)       REFERENCES `users`(`id`)              ON DELETE CASCADE,
      INDEX `idx_conv_created` (`conversation_id`, `created_at`)
    ) ENGINE=InnoDB;");
} catch (Exception $e) {}

ob_clean();
header('Content-Type: application/json; charset=utf-8');

$action = $_POST['action'] ?? $_GET['action'] ?? '';

// ── Helper ───────────────────────────────────────────────────────
function isMember($pdo, $convId, $userId) {
    $s = $pdo->prepare("SELECT 1 FROM chat_members WHERE conversation_id=? AND user_id=?");
    $s->execute([$convId, $userId]);
    return (bool)$s->fetchColumn();
}

// ════════════════════════════════════════════════════════════════
// ACTION: list_conversations
// Returns all conversations for current user with last message + unread count
// ════════════════════════════════════════════════════════════════
if ($action === 'list_conversations') {
  try {
    $rows = $pdo->prepare("
        SELECT
            c.id, c.type, c.name AS group_name, c.created_at,
            cm.last_read_at,
            -- last message
            (SELECT m.body        FROM chat_messages m WHERE m.conversation_id=c.id AND m.is_deleted=0 ORDER BY m.created_at DESC LIMIT 1) AS last_body,
            (SELECT m.created_at  FROM chat_messages m WHERE m.conversation_id=c.id AND m.is_deleted=0 ORDER BY m.created_at DESC LIMIT 1) AS last_at,
            (SELECT m.sender_id   FROM chat_messages m WHERE m.conversation_id=c.id AND m.is_deleted=0 ORDER BY m.created_at DESC LIMIT 1) AS last_sender_id,
            -- unread count
            (SELECT COUNT(*) FROM chat_messages m2
             WHERE m2.conversation_id=c.id AND m2.is_deleted=0
               AND m2.sender_id != ?
               AND (cm.last_read_at IS NULL OR m2.created_at > cm.last_read_at)
            ) AS unread
        FROM chat_conversations c
        JOIN chat_members cm ON cm.conversation_id=c.id AND cm.user_id=?
        ORDER BY last_at DESC, c.created_at DESC
    ");
    $rows->execute([$me, $me]);
    $convs = $rows->fetchAll(PDO::FETCH_ASSOC);

    // For direct chats: get the other user's info
    foreach ($convs as &$c) {
        if ($c['type'] === 'direct') {
            $other = $pdo->prepare("
                SELECT u.id, u.name, u.avatar, u.google_avatar
                FROM chat_members cm
                JOIN users u ON u.id=cm.user_id
                WHERE cm.conversation_id=? AND cm.user_id != ?
                LIMIT 1
            ");
            $other->execute([$c['id'], $me]);
            $c['other_user'] = $other->fetch(PDO::FETCH_ASSOC);
        } else {
            // Group: member count
            $cnt = $pdo->prepare("SELECT COUNT(*) FROM chat_members WHERE conversation_id=?");
            $cnt->execute([$c['id']]);
            $c['member_count'] = (int)$cnt->fetchColumn();
        }
        $c['unread'] = (int)$c['unread'];
    }
    echo json_encode(['success' => true, 'conversations' => $convs]);
  } catch (Exception $e) {
    echo json_encode(['success' => true, 'conversations' => [], 'error' => $e->getMessage()]);
  }
  exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: get_messages
// ════════════════════════════════════════════════════════════════
if ($action === 'get_messages') {
    $convId  = (int)($_GET['conv_id'] ?? 0);
    $since   = $_GET['since'] ?? null; // ISO timestamp for polling
    $limit   = 60;

    if (!$convId || !isMember($pdo, $convId, $me)) {
        echo json_encode(['success' => false, 'msg' => 'Access denied.']); exit;
    }

    // Mark as read
    $pdo->prepare("UPDATE chat_members SET last_read_at=NOW() WHERE conversation_id=? AND user_id=?")
        ->execute([$convId, $me]);

    if ($since) {
        $msgs = $pdo->prepare("
            SELECT m.id, m.sender_id, m.body, m.created_at, m.is_deleted,
                   u.name AS sender_name, u.avatar, u.google_avatar
            FROM chat_messages m JOIN users u ON u.id=m.sender_id
            WHERE m.conversation_id=? AND m.created_at > ?
            ORDER BY m.created_at ASC LIMIT ?
        ");
        $msgs->execute([$convId, $since, $limit]);
    } else {
        $msgs = $pdo->prepare("
            SELECT m.id, m.sender_id, m.body, m.created_at, m.is_deleted,
                   u.name AS sender_name, u.avatar, u.google_avatar
            FROM chat_messages m JOIN users u ON u.id=m.sender_id
            WHERE m.conversation_id=?
            ORDER BY m.created_at DESC LIMIT ?
        ");
        $msgs->execute([$convId, $limit]);
    }
    $list = $msgs->fetchAll(PDO::FETCH_ASSOC);
    if (!$since) $list = array_reverse($list);

    // Conversation info
    $info = $pdo->prepare("
        SELECT c.id, c.type, c.name AS group_name
        FROM chat_conversations c WHERE c.id=?
    ");
    $info->execute([$convId]);
    $conv = $info->fetch(PDO::FETCH_ASSOC);

    // Members list (for group header)
    $mems = $pdo->prepare("
        SELECT u.id, u.name, u.avatar, u.google_avatar, cm.role
        FROM chat_members cm JOIN users u ON u.id=cm.user_id
        WHERE cm.conversation_id=?
    ");
    $mems->execute([$convId]);
    $members = $mems->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode([
        'success'  => true,
        'messages' => $list,
        'conv'     => $conv,
        'members'  => $members,
        'me'       => $me
    ]);
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: send_message
// ════════════════════════════════════════════════════════════════
if ($action === 'send_message') {
    $convId = (int)($_POST['conv_id'] ?? 0);
    $body   = trim($_POST['body'] ?? '');

    if (!$convId || !$body) { echo json_encode(['success'=>false,'msg'=>'Empty message.']); exit; }
    if (strlen($body) > 2000) { echo json_encode(['success'=>false,'msg'=>'Too long.']); exit; }
    if (!isMember($pdo, $convId, $me)) { echo json_encode(['success'=>false,'msg'=>'Access denied.']); exit; }

    $ins = $pdo->prepare("INSERT INTO chat_messages (conversation_id, sender_id, body) VALUES (?,?,?)");
    $ins->execute([$convId, $me, htmlspecialchars($body, ENT_QUOTES)]);
    $msgId = $pdo->lastInsertId();

    // Return the inserted message with sender info
    $msg = $pdo->prepare("
        SELECT m.id, m.sender_id, m.body, m.created_at, m.is_deleted,
               u.name AS sender_name, u.avatar, u.google_avatar
        FROM chat_messages m JOIN users u ON u.id=m.sender_id
        WHERE m.id=?
    ");
    $msg->execute([$msgId]);
    echo json_encode(['success' => true, 'message' => $msg->fetch(PDO::FETCH_ASSOC)]);
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: open_direct  — get or create direct conversation
// ════════════════════════════════════════════════════════════════
if ($action === 'open_direct') {
    $otherId = (int)($_POST['user_id'] ?? 0);
    if (!$otherId || $otherId === $me) { echo json_encode(['success'=>false,'msg'=>'Invalid user.']); exit; }

    // Check if direct conv already exists between me & other
    $existing = $pdo->prepare("
        SELECT c.id FROM chat_conversations c
        JOIN chat_members cm1 ON cm1.conversation_id=c.id AND cm1.user_id=?
        JOIN chat_members cm2 ON cm2.conversation_id=c.id AND cm2.user_id=?
        WHERE c.type='direct'
        LIMIT 1
    ");
    $existing->execute([$me, $otherId]);
    $row = $existing->fetch();

    if ($row) {
        echo json_encode(['success' => true, 'conv_id' => $row['id']]);
    } else {
        $pdo->beginTransaction();
        $pdo->prepare("INSERT INTO chat_conversations (type, created_by) VALUES ('direct',?)")->execute([$me]);
        $convId = (int)$pdo->lastInsertId();
        $pdo->prepare("INSERT INTO chat_members (conversation_id, user_id) VALUES (?,?)")->execute([$convId, $me]);
        $pdo->prepare("INSERT INTO chat_members (conversation_id, user_id) VALUES (?,?)")->execute([$convId, $otherId]);
        $pdo->commit();
        echo json_encode(['success' => true, 'conv_id' => $convId]);
    }
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: create_group
// ════════════════════════════════════════════════════════════════
if ($action === 'create_group') {
    $name    = trim($_POST['name'] ?? '');
    $members = json_decode($_POST['members'] ?? '[]', true); // array of user IDs

    if (strlen($name) < 2) { echo json_encode(['success'=>false,'msg'=>'Group name too short.']); exit; }
    if (!is_array($members) || count($members) < 1) { echo json_encode(['success'=>false,'msg'=>'Add at least 1 member.']); exit; }

    $pdo->beginTransaction();
    $pdo->prepare("INSERT INTO chat_conversations (type, name, created_by) VALUES ('group',?,?)")
        ->execute([htmlspecialchars($name, ENT_QUOTES), $me]);
    $convId = (int)$pdo->lastInsertId();

    // Add creator as admin
    $pdo->prepare("INSERT INTO chat_members (conversation_id, user_id, role) VALUES (?,?,'admin')")->execute([$convId, $me]);

    // Add members (validate they're real users)
    $addStmt = $pdo->prepare("INSERT IGNORE INTO chat_members (conversation_id, user_id) VALUES (?,?)");
    foreach ($members as $uid) {
        $uid = (int)$uid;
        if ($uid && $uid !== $me) {
            // Verify user exists
            $chk = $pdo->prepare("SELECT id FROM users WHERE id=?");
            $chk->execute([$uid]);
            if ($chk->fetch()) $addStmt->execute([$convId, $uid]);
        }
    }
    $pdo->commit();
    echo json_encode(['success' => true, 'conv_id' => $convId]);
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: list_users  — search users to start chat
// ════════════════════════════════════════════════════════════════
if ($action === 'list_users') {
    $q = trim($_GET['q'] ?? '');
    if ($q) {
        $stmt = $pdo->prepare("
            SELECT id, name, avatar, google_avatar
            FROM users WHERE id != ? AND (name LIKE ? OR email LIKE ?)
            ORDER BY name LIMIT 20
        ");
        $stmt->execute([$me, "%$q%", "%$q%"]);
    } else {
        $stmt = $pdo->prepare("
            SELECT id, name, avatar, google_avatar
            FROM users WHERE id != ?
            ORDER BY name LIMIT 30
        ");
        $stmt->execute([$me]);
    }
    echo json_encode(['success' => true, 'users' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: delete_message (own messages only)
// ════════════════════════════════════════════════════════════════
if ($action === 'delete_message') {
    $msgId = (int)($_POST['msg_id'] ?? 0);
    $stmt  = $pdo->prepare("SELECT sender_id, conversation_id FROM chat_messages WHERE id=?");
    $stmt->execute([$msgId]);
    $msg = $stmt->fetch();
    if (!$msg || $msg['sender_id'] !== $me) { echo json_encode(['success'=>false,'msg'=>'Cannot delete.']); exit; }
    $pdo->prepare("UPDATE chat_messages SET is_deleted=1 WHERE id=?")->execute([$msgId]);
    echo json_encode(['success' => true]);
    exit;
}

// ════════════════════════════════════════════════════════════════
// ACTION: total_unread  — badge count for nav
// ════════════════════════════════════════════════════════════════
if ($action === 'total_unread') {
    $stmt = $pdo->prepare("
        SELECT COUNT(*) FROM chat_messages m
        JOIN chat_members cm ON cm.conversation_id=m.conversation_id AND cm.user_id=?
        WHERE m.sender_id != ?
          AND m.is_deleted=0
          AND (cm.last_read_at IS NULL OR m.created_at > cm.last_read_at)
    ");
    $stmt->execute([$me, $me]);
    echo json_encode(['success' => true, 'unread' => (int)$stmt->fetchColumn()]);
    exit;
}

echo json_encode(['success' => false, 'msg' => 'Unknown action.']);