import 'package:drift/drift.dart'; import 'package:mnemo_cards_backend/cron/task.dart' as cron_task; import 'package:mnemo_cards_backend/database/database.dart'; import 'package:mnemo_cards_common_backend/mnemo_cards_common_backend.dart'; class TasksSeederTask with cron_task.Task { final AppDatabase _db; TasksSeederTask(this._db); @override String get name => 'tasks_seeder'; @override Future task() async { print('Seeding initial user tasks...'); try { final now = DateTime.now(); final weekFromNow = now.add(const Duration(days: 7)); final tasks = [ // App Internal Tasks UserTaskModel( title: 'Пройди 3 теста сегодня', description: 'Заверши три тестовые сессии в приложении для улучшения навыков испанского.', type: 'app_internal', difficulty: 'easy', rewards: [ TaskRewardModel(type: 'xp', amount: 50), TaskRewardModel(type: 'coins', amount: 10), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['tests', 'practice', 'daily'], ), UserTaskModel( title: 'Достигни 80% правильных ответов в тесте', description: 'Пройди тест с результатом не менее 80% правильных ответов.', type: 'app_internal', difficulty: 'medium', rewards: [ TaskRewardModel(type: 'xp', amount: 100), TaskRewardModel(type: 'coins', amount: 25), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['tests', 'accuracy', 'challenge'], ), // External Tasks UserTaskModel( title: 'Подпишись на Telegram канал', description: 'Подпишись на наш Telegram канал @mnemo_cards для получения обновлений и советов по изучению испанского.', type: 'external', difficulty: 'easy', rewards: [ TaskRewardModel(type: 'xp', amount: 30), TaskRewardModel(type: 'coins', amount: 5), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['telegram', 'social', 'subscription'], ), UserTaskModel( title: 'Закажи еду на испанском', description: 'Сделай заказ в ресторане или кафе, используя испанский язык. Запиши процесс на видео для подтверждения.', type: 'external', difficulty: 'hard', rewards: [ TaskRewardModel(type: 'xp', amount: 200), TaskRewardModel(type: 'coins', amount: 50), TaskRewardModel( type: 'achievement', amount: 0, achievementId: 'real_world_practice'), ], status: 'available', createdAt: now, expiresAt: weekFromNow.add(const Duration(days: 14)), // 3 weeks instructions: 'Запиши видео, где ты делаешь заказ на испанском. Убедись, что официант понимает тебя.', tags: ['speaking', 'restaurant', 'video', 'real_world'], ), UserTaskModel( title: 'Посмотри испанский фильм с субтитрами', description: 'Посмотри испанский фильм или сериал с испанскими субтитрами в течение 30 минут.', type: 'external', difficulty: 'medium', rewards: [ TaskRewardModel(type: 'xp', amount: 75), TaskRewardModel(type: 'coins', amount: 15), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['listening', 'media', 'subtitles'], ), // Social Tasks UserTaskModel( title: 'Поделись прогрессом в соцсетях', description: 'Поделись своим прогрессом в изучении испанского в социальных сетях с хэштегом #MnemoCards.', type: 'social', difficulty: 'easy', rewards: [ TaskRewardModel(type: 'xp', amount: 40), TaskRewardModel(type: 'coins', amount: 10), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['social', 'sharing', 'progress'], ), UserTaskModel( title: 'Найди партнёра для практики', description: 'Найди собеседника для практики испанского языка (друга, коллегу или через языковые приложения).', type: 'social', difficulty: 'medium', rewards: [ TaskRewardModel(type: 'xp', amount: 90), TaskRewardModel(type: 'coins', amount: 20), ], status: 'available', createdAt: now, expiresAt: weekFromNow.add(const Duration(days: 7)), // 2 weeks tags: ['conversation', 'partner', 'practice'], ), // Additional App Tasks UserTaskModel( title: 'Изучай слова ежедневно 7 дней подряд', description: 'Учи новые слова в приложении каждый день в течение недели.', type: 'app_internal', difficulty: 'hard', rewards: [ TaskRewardModel(type: 'xp', amount: 150), TaskRewardModel(type: 'coins', amount: 35), TaskRewardModel( type: 'achievement', amount: 0, achievementId: 'consistency_master'), ], status: 'available', createdAt: now, expiresAt: weekFromNow.add(const Duration(days: 21)), // 4 weeks tags: ['vocabulary', 'daily', 'streak', 'consistency'], ), UserTaskModel( title: 'Пройди тест по грамматике', description: 'Заверши специализированный тест по грамматике испанского языка.', type: 'app_internal', difficulty: 'medium', rewards: [ TaskRewardModel(type: 'xp', amount: 80), TaskRewardModel(type: 'coins', amount: 20), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['grammar', 'tests', 'knowledge'], ), UserTaskModel( title: 'Практикуй произношение', description: 'Заверши урок по произношению или запиши себя, читая текст на испанском.', type: 'app_internal', difficulty: 'easy', rewards: [ TaskRewardModel(type: 'xp', amount: 60), TaskRewardModel(type: 'coins', amount: 12), ], status: 'available', createdAt: now, expiresAt: weekFromNow, tags: ['pronunciation', 'speaking', 'practice'], ), ]; // Convert UserTaskModel to UserTasksCompanion and insert // Используем InsertMode.insertOrIgnore для автоматического игнорирования дубликатов через ON CONFLICT for (final taskModel in tasks) { final rewardsJson = taskModel.rewards.map((r) => r.toJson()).toList(); await _db.into(_db.userTasks).insert( UserTasksCompanion.insert( title: taskModel.title, description: taskModel.description, type: taskModel.type, difficulty: taskModel.difficulty, status: taskModel.status, rewards: Value(rewardsJson), createdAt: Value(taskModel.createdAt), expiresAt: taskModel.expiresAt, completedAt: Value(taskModel.completedAt), proofUrl: Value(taskModel.proofUrl), instructions: Value(taskModel.instructions), tags: Value(taskModel.tags), imageUrl: Value(taskModel.imageUrl), ), mode: InsertMode.insertOrIgnore, // ON CONFLICT DO NOTHING ); } print('Successfully seeded ${tasks.length} user tasks (duplicates ignored)'); } catch (e) { print('Error seeding tasks: $e'); rethrow; } } @override int get intervalSeconds => 60 * 60 * 24; // Run once per day }