<?php
declare(strict_types=1);

/**
 * EnglishSpeak - Lesson Activities
 * File: teacher/lesson-activities/store.php
 *
 * Word Library -> Flashcard Set -> Lesson Activity -> Student Game
 */

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: ../lessons/index.php');
    exit;
}

$pdo = getDbConnection();

$lessonId = max(0, (int)($_POST['lesson_id'] ?? 0));
$title = trim((string)($_POST['title'] ?? ''));
$activityType = trim((string)($_POST['activity_type'] ?? ''));
$instructions = trim((string)($_POST['instructions'] ?? ''));
$flashcardSetId = max(0, (int)($_POST['flashcard_set_id'] ?? 0));
$learningGoal = trim((string)($_POST['learning_goal'] ?? ''));
$difficulty = trim((string)($_POST['difficulty'] ?? 'easy'));
$icon = trim((string)($_POST['icon'] ?? ''));
$requiredXp = max(0, (int)($_POST['required_xp'] ?? 0));
$xpReward = max(0, (int)($_POST['xp_reward'] ?? 10));
$passingScore = max(0, min(100, (int)($_POST['passing_score'] ?? 70)));
$sortOrder = max(0, (int)($_POST['sort_order'] ?? 1));
$status = (string)($_POST['status'] ?? 'active');

$allowedActivityTypes = [
    'flashcards',
    'listen_repeat',
    'speaking',
    'memory',
    'matching',
    'quiz',
    'typing',
    'word_search',
    'sentence_builder',
    'vocabulary',
];

$allowedLearningGoals = [
    'vocabulary',
    'listening',
    'speaking',
    'pronunciation',
    'reading',
    'writing',
    'review',
    'challenge',
];

$allowedDifficulties = ['easy', 'medium', 'hard'];
$allowedStatuses = ['active', 'inactive'];

if (!in_array($activityType, $allowedActivityTypes, true)) {
    $activityType = '';
}

if (!in_array($learningGoal, $allowedLearningGoals, true)) {
    $learningGoal = '';
}

if (!in_array($difficulty, $allowedDifficulties, true)) {
    $difficulty = 'easy';
}

if (!in_array($status, $allowedStatuses, true)) {
    $status = 'active';
}

$old = [
    'lesson_id' => $lessonId,
    'title' => $title,
    'activity_type' => $activityType,
    'instructions' => $instructions,
    'flashcard_set_id' => $flashcardSetId,
    'learning_goal' => $learningGoal,
    'difficulty' => $difficulty,
    'icon' => $icon,
    'required_xp' => $requiredXp,
    'xp_reward' => $xpReward,
    'passing_score' => $passingScore,
    'sort_order' => $sortOrder,
    'status' => $status,
];

$errors = [];

/**
 * @return array<string, array<string, mixed>>
 */
function lacStoreColumns(PDO $pdo, string $table): array
{
    $stmt = $pdo->prepare(
        "SELECT COUNT(*)
         FROM information_schema.TABLES
         WHERE TABLE_SCHEMA = DATABASE()
           AND TABLE_NAME = ?"
    );
    $stmt->execute([$table]);

    if ((int)$stmt->fetchColumn() === 0) {
        return [];
    }

    $rows = $pdo->query("SHOW COLUMNS FROM `{$table}`")->fetchAll(PDO::FETCH_ASSOC);
    return array_column($rows, null, 'Field');
}

$activityColumns = lacStoreColumns($pdo, 'activities');
$setColumns = lacStoreColumns($pdo, 'flashcard_sets');

if ($activityColumns === []) {
    $errors[] = 'The activities table does not exist.';
}

// Lesson validation.
$lessonExists = false;

if ($lessonId <= 0) {
    $errors[] = 'Please choose a Lesson.';
} else {
    $lessonStmt = $pdo->prepare(
        "SELECT l.id
         FROM lessons l
         INNER JOIN units u ON u.id = l.unit_id
         INNER JOIN books b ON b.id = u.book_id
         WHERE l.id = ?
         LIMIT 1"
    );
    $lessonStmt->execute([$lessonId]);
    $lessonExists = (bool)$lessonStmt->fetchColumn();

    if (!$lessonExists) {
        $errors[] = 'The selected Lesson does not exist.';
    }
}

// Required fields.
if ($title === '') {
    $errors[] = 'Activity Name is required.';
} elseif (mb_strlen($title) > 150) {
    $errors[] = 'Activity Name must not exceed 150 characters.';
}

if ($activityType === '') {
    $errors[] = 'Please choose a valid Game Template.';
}

if (mb_strlen($instructions) > 5000) {
    $errors[] = 'Instructions are too long.';
}

if (mb_strlen($icon) > 100) {
    $errors[] = 'Icon is too long.';
}

// Flashcard Set validation.
if (isset($activityColumns['flashcard_set_id'])) {
    if ($flashcardSetId > 0) {
        if ($setColumns === []) {
            $errors[] = 'The flashcard_sets table does not exist.';
        } else {
            $setStatusSql = isset($setColumns['status'])
                ? "AND status = 'active'"
                : '';

            $setStmt = $pdo->prepare(
                "SELECT id
                 FROM flashcard_sets
                 WHERE id = ?
                 {$setStatusSql}
                 LIMIT 1"
            );
            $setStmt->execute([$flashcardSetId]);

            if (!$setStmt->fetchColumn()) {
                $errors[] = 'The selected Flashcard Set does not exist or is inactive.';
            }
        }
    }
} elseif ($flashcardSetId > 0) {
    $errors[] = 'The activities table is missing flashcard_set_id.';
}

// Prevent an exact duplicate in one Lesson.
if ($lessonExists && $title !== '' && $activityType !== '') {
    $titleColumn = isset($activityColumns['title'])
        ? 'title'
        : (isset($activityColumns['name']) ? 'name' : null);

    $typeColumn = isset($activityColumns['activity_type'])
        ? 'activity_type'
        : (isset($activityColumns['type']) ? 'type' : null);

    if ($titleColumn !== null && $typeColumn !== null) {
        $duplicateStmt = $pdo->prepare(
            "SELECT id
             FROM activities
             WHERE lesson_id = ?
               AND LOWER(TRIM(`{$titleColumn}`)) = LOWER(TRIM(?))
               AND `{$typeColumn}` = ?
             LIMIT 1"
        );
        $duplicateStmt->execute([$lessonId, $title, $activityType]);

        if ($duplicateStmt->fetchColumn()) {
            $errors[] = 'An Activity with the same name and Game Template already exists in this Lesson.';
        }
    }
}

if ($errors !== []) {
    $_SESSION['activities_old'] = $old;
    $_SESSION['activities_errors'] = $errors;

    header('Location: create.php?lesson_id=' . $lessonId);
    exit;
}

// Build the INSERT from the real schema.
$insertColumns = [];
$placeholders = [];
$values = [];

$appendValue = static function (
    string $column,
    mixed $value
) use (&$insertColumns, &$placeholders, &$values): void {
    $insertColumns[] = "`{$column}`";
    $placeholders[] = '?';
    $values[] = $value;
};

$appendSql = static function (
    string $column,
    string $expression
) use (&$insertColumns, &$placeholders): void {
    $insertColumns[] = "`{$column}`";
    $placeholders[] = $expression;
};

if (!isset($activityColumns['lesson_id'])) {
    $_SESSION['activities_old'] = $old;
    $_SESSION['activities_errors'] = ['The activities table is missing lesson_id.'];
    header('Location: create.php?lesson_id=' . $lessonId);
    exit;
}

$appendValue('lesson_id', $lessonId);

if (isset($activityColumns['title'])) {
    $appendValue('title', $title);
} elseif (isset($activityColumns['name'])) {
    $appendValue('name', $title);
}

if (isset($activityColumns['activity_type'])) {
    $appendValue('activity_type', $activityType);
} elseif (isset($activityColumns['type'])) {
    $appendValue('type', $activityType);
}

if (isset($activityColumns['instructions'])) {
    $appendValue('instructions', $instructions !== '' ? $instructions : null);
} elseif (isset($activityColumns['description'])) {
    $appendValue('description', $instructions !== '' ? $instructions : null);
}

if (isset($activityColumns['flashcard_set_id'])) {
    $appendValue('flashcard_set_id', $flashcardSetId > 0 ? $flashcardSetId : null);
}

if (isset($activityColumns['learning_goal'])) {
    $appendValue('learning_goal', $learningGoal !== '' ? $learningGoal : null);
}

if (isset($activityColumns['difficulty'])) {
    $appendValue('difficulty', $difficulty);
}

if (isset($activityColumns['icon'])) {
    $appendValue('icon', $icon !== '' ? $icon : null);
}

if (isset($activityColumns['required_xp'])) {
    $appendValue('required_xp', $requiredXp);
}

if (isset($activityColumns['xp_reward'])) {
    $appendValue('xp_reward', $xpReward);
}

if (isset($activityColumns['passing_score'])) {
    $appendValue('passing_score', $passingScore);
}

if (isset($activityColumns['sort_order'])) {
    $appendValue('sort_order', $sortOrder);
}

if (isset($activityColumns['status'])) {
    $appendValue('status', $status);
}

// Initial reusable game configuration.
// Future game-specific settings can be added without changing the content model.
if (isset($activityColumns['config_json'])) {
    $config = [
        'version' => 1,
        'game_template' => $activityType,
        'shuffle' => true,
    ];

    if ($activityType === 'flashcards') {
        $config['show_image_first'] = true;
        $config['auto_play_audio'] = false;
    }

    $appendValue(
        'config_json',
        json_encode($config, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
    );
}

if (isset($activityColumns['created_at'])) {
    $appendSql('created_at', 'NOW()');
}

if (isset($activityColumns['updated_at'])) {
    $appendSql('updated_at', 'NOW()');
}

try {
    $pdo->beginTransaction();

    $sql = sprintf(
        "INSERT INTO activities (%s) VALUES (%s)",
        implode(', ', $insertColumns),
        implode(', ', $placeholders)
    );

    $stmt = $pdo->prepare($sql);
    $stmt->execute($values);

    $newActivityId = (int)$pdo->lastInsertId();

    $pdo->commit();

    $_SESSION['activities_message'] = 'Activity created successfully.';
    $_SESSION['activities_message_type'] = 'success';

    // Return to the new Activity Editor so the teacher can continue configuring it.
    header(
        'Location: ../lessons/activity.php?id='
        . $newActivityId
        . '&saved=1'
    );
    exit;
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    error_log('EnglishSpeak lesson-activities/store.php: ' . $e->getMessage());

    $_SESSION['activities_old'] = $old;

    if ($e instanceof PDOException && (string)$e->getCode() === '23000') {
        $_SESSION['activities_errors'] = [
            'This Activity conflicts with existing Lesson or Flashcard Set data.',
        ];
    } else {
        $_SESSION['activities_errors'] = [
            'Could not create the Activity. Please try again.',
        ];
    }

    header('Location: create.php?lesson_id=' . $lessonId);
    exit;
}
