/// Location Local Data Source /// /// Handles Hive caching for cities and wards. library; import 'package:hive_ce/hive.dart'; import 'package:worker/core/constants/storage_constants.dart'; import 'package:worker/core/database/hive_service.dart'; import 'package:worker/features/account/data/models/city_model.dart'; import 'package:worker/features/account/data/models/ward_model.dart'; /// Location Local Data Source /// /// Provides offline-first caching for cities and wards using Hive. class LocationLocalDataSource { final HiveService _hiveService; LocationLocalDataSource(this._hiveService); // ============================================================================ // CITIES // ============================================================================ /// Get city box Box get _cityBox => _hiveService.getBox(HiveBoxNames.cityBox); /// Get all cached cities List getCities() { try { final cities = _cityBox.values.whereType().toList(); return cities; } catch (e) { return []; } } /// Save cities to cache Future saveCities(List cities) async { try { // Only clear if there are existing cities if (_cityBox.isNotEmpty) { await _cityBox.clear(); } for (final city in cities) { await _cityBox.put(city.code, city); } } catch (e) { rethrow; } } /// Get city by code CityModel? getCityByCode(String code) { try { return _cityBox.get(code) as CityModel?; } catch (e) { return null; } } /// Check if cities are cached bool hasCities() { return _cityBox.isNotEmpty; } // ============================================================================ // WARDS // ============================================================================ /// Get ward box Box get _wardBox => _hiveService.getBox(HiveBoxNames.wardBox); /// Get cached wards for a city /// /// Wards are stored with key: "cityCode_wardCode" List getWards(String cityCode) { try { final wards = _wardBox.values .whereType() .where((ward) { // Check if this ward belongs to the city final key = '${cityCode}_${ward.code}'; return _wardBox.containsKey(key); }) .toList(); return wards; } catch (e) { return []; } } /// Save wards for a specific city to cache Future saveWards(String cityCode, List wards) async { try { // Remove old wards for this city (only if they exist) final keysToDelete = _wardBox.keys .where((key) => key.toString().startsWith('${cityCode}_')) .toList(); if (keysToDelete.isNotEmpty) { for (final key in keysToDelete) { await _wardBox.delete(key); } } // Save new wards for (final ward in wards) { final key = '${cityCode}_${ward.code}'; await _wardBox.put(key, ward); } } catch (e) { rethrow; } } /// Check if wards are cached for a city bool hasWards(String cityCode) { return _wardBox.keys.any((key) => key.toString().startsWith('${cityCode}_')); } /// Clear all cached data Future clearAll() async { try { // Only clear if boxes are not empty if (_cityBox.isNotEmpty) { await _cityBox.clear(); } if (_wardBox.isNotEmpty) { await _wardBox.clear(); } } catch (e) { rethrow; } } }