import 'package:flutter/foundation.dart';
import 'package:qpay/http/http.dart';
import 'package:qpay/browser.dart';

const appBuildNumber = 4;

/// Describes the result of the build-number check performed during splash.
enum SplashCheckStatus { checking, noUpdate, updateAvailable }

class SplashProvider extends ChangeNotifier {
  final Http _http = Http();

  SplashCheckStatus _status = SplashCheckStatus.checking;
  Map<String, dynamic>? _updatePayload;
  bool _isRefreshing = false;

  SplashCheckStatus get status => _status;
  Map<String, dynamic>? get updatePayload => _updatePayload;
  bool get isRefreshing => _isRefreshing;

  /// The store / download URL from the server payload, or `null` if
  /// the server didn't include one.
  String? get downloadUrl => _updatePayload?['downloadUrl']?.toString();

  /// Calls the server endpoint to see whether a newer app build exists.
  ///
  /// * 204 → no new build — proceed with normal app loading.
  /// * 200 → a new build is available — the splash screen will show a
  ///   non-dismissible bottom sheet offering the user a hard refresh.
  Future<void> checkVersion() async {
    _status = SplashCheckStatus.checking;
    notifyListeners();

    try {
      final buildNumber = appBuildNumber;
      final response = await _http.getRaw(
        '/public/app-version/check/app?currentBuildNumber=$buildNumber',
      );

      if (response.statusCode == 204) {
        _status = SplashCheckStatus.noUpdate;
      } else if (response.statusCode == 200) {
        _status = SplashCheckStatus.updateAvailable;
        _updatePayload = response.data is Map
            ? response.data as Map<String, dynamic>
            : null;
      } else {
        // Unexpected status code – don't block the user.
        _status = SplashCheckStatus.noUpdate;
      }
    } catch (_) {
      // Network / server errors should not prevent the app from loading.
      _status = SplashCheckStatus.noUpdate;
    }

    notifyListeners();
  }

  /// 1. Sends a POST request to clear the Cloudflare cache.
  /// 2. Waits 5 seconds to give the CDN time to propagate.
  /// 3. Performs a hard refresh by reloading the current URL, which
  ///    forces the browser to re-fetch all cached assets.
  Future<void> clearCacheAndRefresh() async {
    _isRefreshing = true;
    notifyListeners();

    try {
      await _http.postRaw('/public/cache/cloudflare/clear');
    } catch (_) {
      // Proceed with refresh even if the cache-clear request fails.
    }

    // Allow Cloudflare a few seconds to flush its edge cache.
    await Future<void>.delayed(const Duration(seconds: 5));

    // Hard-refresh: navigate to the current location which triggers a
    // full page reload on web (and restarts the app on other platforms).
    Browser.location.href = Browser.location.href;
  }
}
