proxybuy-flutter/lib/screens/mains/hunt/providers/hunt_provider.dart

248 lines
7.2 KiB
Dart

import 'package:flutter/foundation.dart';
import '../models/hunt_card.dart';
enum HuntGameState {
cardSelection,
cardFlipped,
huntingActive,
hintMode,
completed,
}
class HuntState extends ChangeNotifier {
List<HuntCard> _cards = [];
HuntCard? _selectedCard;
HuntGameState _gameState = HuntGameState.cardSelection;
List<LeaderboardEntry> _leaderboard = [];
int _userPoints = 0;
bool _isLocationEnabled = false;
bool _isCameraPermissionGranted = false;
DateTime? _huntStartTime;
// Getters
List<HuntCard> get cards => _cards;
HuntCard? get selectedCard => _selectedCard;
HuntGameState get gameState => _gameState;
List<LeaderboardEntry> get leaderboard => _leaderboard;
int get userPoints => _userPoints;
bool get isLocationEnabled => _isLocationEnabled;
bool get isCameraPermissionGranted => _isCameraPermissionGranted;
DateTime? get huntStartTime => _huntStartTime;
bool get hasTimeLeft {
if (_huntStartTime == null) return false;
final elapsed = DateTime.now().difference(_huntStartTime!);
return elapsed.inHours < 12;
}
Duration get timeRemaining {
if (_huntStartTime == null) return Duration.zero;
final elapsed = DateTime.now().difference(_huntStartTime!);
final remaining = const Duration(hours: 12) - elapsed;
return remaining.isNegative ? Duration.zero : remaining;
}
int get currentUserRank {
if (_leaderboard.isEmpty) return 0;
try {
return _leaderboard.firstWhere((e) => e.isCurrentUser).rank;
} catch (e) {
return 0;
}
}
void initializeGame() {
_cards = _generateMockCards();
_leaderboard = _generateMockLeaderboard();
_gameState = HuntGameState.cardSelection;
notifyListeners();
}
void selectCard(HuntCard card) {
_selectedCard = card;
// Don't change game state, keep it as cardSelection so cards just flip
notifyListeners();
}
void startHunt() {
if (_selectedCard != null) {
_gameState = HuntGameState.huntingActive;
notifyListeners();
}
}
void activateHintMode() {
if (_gameState == HuntGameState.huntingActive) {
_gameState = HuntGameState.hintMode;
notifyListeners();
}
}
void setLocationEnabled(bool enabled) {
_isLocationEnabled = enabled;
notifyListeners();
}
void setCameraPermissionGranted(bool granted) {
_isCameraPermissionGranted = granted;
notifyListeners();
}
void completeHunt() {
if (_selectedCard != null) {
_userPoints += _selectedCard!.points;
_gameState = HuntGameState.completed;
_updateLeaderboard();
notifyListeners();
}
}
void resetGame() {
_selectedCard = null;
_gameState = HuntGameState.cardSelection;
_huntStartTime = null;
notifyListeners();
}
void _updateLeaderboard() {
// Update user's position in leaderboard
for (int i = 0; i < _leaderboard.length; i++) {
if (_leaderboard[i].isCurrentUser) {
_leaderboard[i] = _leaderboard[i].copyWith(totalPoints: _userPoints);
break;
}
}
// Sort leaderboard by points
_leaderboard.sort((a, b) => b.totalPoints.compareTo(a.totalPoints));
// Update ranks
for (int i = 0; i < _leaderboard.length; i++) {
_leaderboard[i] = _leaderboard[i].copyWith(rank: i + 1);
}
}
List<HuntCard> _generateMockCards() {
return [
HuntCard(
id: '1',
category: 'Coffee Shop',
categoryIcon: '',
points: 150,
question: 'In the heart of a grand shopping center, where fountains dance and skiers gather in warmth. Look for a café where the scent of coffee and the aroma of books intertwine.',
answer: 'Kino Café',
description: 'A cozy book café in Isfahan City Center',
targetLatitude: 32.62501010252744,
targetLongitude: 51.72622026956878,
hintLatitude: 32.62501010252744,
hintLongitude: 51.72622026956878,
hintDescription: 'Look for the AR marker near the fountain area',
),
HuntCard(
id: '2',
category: 'Restaurant',
categoryIcon: '🍽️',
points: 200,
question: 'Where spices tell stories of ancient Persia, and every dish carries the warmth of tradition. Seek the place where saffron meets hospitality.',
answer: 'Shahrzad Restaurant',
description: 'Traditional Persian cuisine restaurant',
targetLatitude: 32.625,
targetLongitude: 51.726,
hintLatitude: 32.625,
hintLongitude: 51.726,
hintDescription: 'Find the AR clue near the traditional architecture',
),
HuntCard(
id: '3',
category: 'Fashion Store',
categoryIcon: '👕',
points: 120,
question: 'Where fashion meets elegance, and every thread tells a story of style. Find the boutique that dresses dreams.',
answer: 'Zara Store',
description: 'International fashion retailer',
targetLatitude: 32.624,
targetLongitude: 51.725,
hintLatitude: 32.624,
hintLongitude: 51.725,
hintDescription: 'Check the AR marker at the fashion district entrance',
),
HuntCard(
id: '4',
category: 'Electronics',
categoryIcon: '📱',
points: 180,
question: 'In the digital realm where innovation never sleeps, discover the place where technology meets tomorrow.',
answer: 'TechnoCity',
description: 'Electronics and gadgets store',
targetLatitude: 32.623,
targetLongitude: 51.724,
hintLatitude: 32.623,
hintLongitude: 51.724,
hintDescription: 'Look for the AR guide near the tech display',
),
HuntCard(
id: '5',
category: 'Bookstore',
categoryIcon: '📚',
points: 100,
question: 'Where words dance on pages and knowledge finds its home. Seek the sanctuary of stories and wisdom.',
answer: 'Ketabsara Bookstore',
description: 'Literary paradise with rare collections',
targetLatitude: 32.622,
targetLongitude: 51.723,
hintLatitude: 32.622,
hintLongitude: 51.723,
hintDescription: 'Find the AR clue in the literature section',
),
]..sort((a, b) => b.points.compareTo(a.points));
}
List<LeaderboardEntry> _generateMockLeaderboard() {
return [
const LeaderboardEntry(
id: '1',
name: 'Alex Thompson',
avatar: '🏆',
totalPoints: 850,
rank: 1,
),
const LeaderboardEntry(
id: '2',
name: 'Sarah Johnson',
avatar: '🥈',
totalPoints: 720,
rank: 2,
),
const LeaderboardEntry(
id: '3',
name: 'Mike Chen',
avatar: '🥉',
totalPoints: 680,
rank: 3,
),
LeaderboardEntry(
id: 'current_user',
name: 'You',
avatar: '👤',
totalPoints: _userPoints,
rank: 4,
isCurrentUser: true,
),
const LeaderboardEntry(
id: '4',
name: 'Emma Davis',
avatar: '🌟',
totalPoints: 420,
rank: 5,
),
const LeaderboardEntry(
id: '5',
name: 'David Wilson',
avatar: '',
totalPoints: 380,
rank: 6,
),
];
}
}