<?php
declare(strict_types=1);

/**
 * EnglishSpeak
 * File: teacher/flashcards/ajax/remove-word.php
 *
 * Remove one Word from one Flashcard Set.
 * Rebuilds order_no so selected words remain 1..N.
 * Keeps the JSON contract used by flashcards.js.
 */

require __DIR__ . '/../../partials/auth.php';
require_once __DIR__ . '/../../../config/database.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

function removeWordResponse(
    bool $success,
    array $payload = [],
    string $message = '',
    int $statusCode = 200
): never {
    http_response_code($statusCode);

    echo json_encode(
        array_merge(
            [
                'success' => $success,
                'message' => $message,
            ],
            $payload
        ),
        JSON_UNESCAPED_UNICODE
        | JSON_UNESCAPED_SLASHES
        | JSON_INVALID_UTF8_SUBSTITUTE
    );

    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    removeWordResponse(
        false,
        [],
        'Method not allowed.',
        405
    );
}

$setId = filter_input(INPUT_POST, 'set_id', FILTER_VALIDATE_INT);
$wordId = filter_input(INPUT_POST, 'word_id', FILTER_VALIDATE_INT);

if (!$setId || !$wordId) {
    removeWordResponse(
        false,
        [],
        'Invalid Flashcard Set or Word.',
        422
    );
}

$pdo = getDbConnection();

$currentUserId = (int)($_SESSION['user_id'] ?? 0);
$currentUserRole = strtolower(trim((string)($_SESSION['user_role'] ?? $_SESSION['role'] ?? 'teacher')));
$isAdmin = $currentUserRole === 'admin';

try {
    $pdo->beginTransaction();

    $setStmt = $pdo->prepare(
        'SELECT id, created_by_teacher_id
         FROM flashcard_sets
         WHERE id = ?
         LIMIT 1
         FOR UPDATE'
    );
    $setStmt->execute([$setId]);
    $setRow = $setStmt->fetch(PDO::FETCH_ASSOC);

    if (!$setRow) {
        throw new DomainException('Flashcard Set not found.');
    }
    if (!$isAdmin && ($setRow['created_by_teacher_id'] === null || (int)$setRow['created_by_teacher_id'] !== $currentUserId)) {
        throw new DomainException('Bạn không có quyền thay đổi Flashcard Set này.');
    }

    $relationStmt = $pdo->prepare(
        'SELECT id, order_no
         FROM flashcard_set_words
         WHERE set_id = ?
           AND word_id = ?
         LIMIT 1
         FOR UPDATE'
    );
    $relationStmt->execute([$setId, $wordId]);
    $relation = $relationStmt->fetch(PDO::FETCH_ASSOC);

    if (!$relation) {
        throw new DomainException(
            'This word is not in the Flashcard Set.'
        );
    }

    $deleteStmt = $pdo->prepare(
        'DELETE FROM flashcard_set_words
         WHERE id = ?
         LIMIT 1'
    );
    $deleteStmt->execute([(int)$relation['id']]);

    // Rebuild order_no as 1..N.
    $remainingStmt = $pdo->prepare(
        'SELECT id
         FROM flashcard_set_words
         WHERE set_id = ?
         ORDER BY order_no ASC, id ASC
         FOR UPDATE'
    );
    $remainingStmt->execute([$setId]);
    $remainingIds = $remainingStmt->fetchAll(PDO::FETCH_COLUMN);

    $orderStmt = $pdo->prepare(
        'UPDATE flashcard_set_words
         SET order_no = ?
         WHERE id = ?'
    );

    $position = 1;

    foreach ($remainingIds as $relationId) {
        $orderStmt->execute([
            $position,
            (int)$relationId,
        ]);

        $position++;
    }

    $wordCount = count($remainingIds);

    $setColumns = $pdo->query(
        'SHOW COLUMNS FROM flashcard_sets'
    )->fetchAll(PDO::FETCH_COLUMN);

    if (in_array('updated_at', $setColumns, true)) {
        $touchStmt = $pdo->prepare(
            'UPDATE flashcard_sets
             SET updated_at = NOW()
             WHERE id = ?'
        );
        $touchStmt->execute([$setId]);
    }

    $pdo->commit();

    removeWordResponse(
        true,
        [
            'word_id' => (int)$wordId,
            'word_count' => $wordCount,
            'order' => array_map(
                static fn(mixed $relationId, int $index): array => [
                    'relation_id' => (int)$relationId,
                    'order_no' => $index + 1,
                ],
                $remainingIds,
                array_keys($remainingIds)
            ),
        ],
        'Word removed successfully.'
    );
} catch (DomainException $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    removeWordResponse(
        false,
        [],
        $e->getMessage(),
        404
    );
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    error_log(
        'EnglishSpeak flashcards/ajax/remove-word.php: '
        . $e->getMessage()
    );

    removeWordResponse(
        false,
        [],
        'Unable to remove the word.',
        500
    );
}
