import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/app_navigator.dart';
import 'package:mypoint_flutter_app/main.dart' show routeObserver;
import '../resources/base_color.dart';
import '../widgets/alert/custom_alert_dialog.dart';
import '../widgets/alert/data_alert_model.dart';
import '../widgets/alert/popup_data_model.dart';

abstract class BaseScreen extends StatefulWidget {
  const BaseScreen({super.key});
}

abstract class BaseState<Screen extends BaseScreen> extends State<Screen>
    with WidgetsBindingObserver, RouteAware {
  bool _isVisible = false;
  ModalRoute<dynamic>? _route;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((_) => onInit());
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    if (_route != null) {
      routeObserver.unsubscribe(this);
    }
    onDispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.resumed:
        onAppResumed();
        break;
      case AppLifecycleState.paused:
        onAppPaused();
        break;
      default:
        break;
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _setupRouteObserver();
  }

  void _setupRouteObserver() {
    final modalRoute = ModalRoute.of(context);
    if (modalRoute != null && modalRoute is PageRoute && modalRoute != _route) {
      _route = modalRoute;
      routeObserver.subscribe(this, modalRoute);
    }
  }

  // MARK: - Core Lifecycle Methods
  
  /// Called when the widget is first inserted into the tree.
  /// Use this to initialize data, setup listeners, etc.
  void onInit() {
    if (kDebugMode) print("onInit: $runtimeType");
  }

  /// Called when the widget is removed from the tree.
  /// Use this to cleanup resources, cancel timers, etc.
  void onDispose() {
    if (kDebugMode) print("onDispose: $runtimeType");
  }

  // MARK: - Route Visibility Methods
  
  /// Called when the route is about to become visible (push or uncovered).
  /// Use this to prepare data, start animations, etc.
  void onRouteWillAppear() {
    if (kDebugMode) print("onRouteWillAppear: $runtimeType");
  }

  /// Called when the route has become visible.
  /// Use this to start timers, refresh data, etc.
  void onRouteDidAppear() {
    if (kDebugMode) print("onRouteDidAppear: $runtimeType");
  }

  /// Called when the route is about to be covered or popped.
  /// Use this to pause operations, save state, etc.
  void onRouteWillDisappear() {
    if (kDebugMode) print("onRouteWillDisappear: $runtimeType");
  }

  /// Called when the route has been covered or popped.
  /// Use this to stop timers, cleanup temporary resources, etc.
  void onRouteDidDisappear() {
    if (kDebugMode) print("onRouteDidDisappear: $runtimeType");
  }

  // MARK: - App Lifecycle Methods
  
  /// Called when the app becomes active (foreground).
  /// Use this to resume operations, refresh data, etc.
  void onAppResumed() {
    if (kDebugMode) print("onAppResumed: $runtimeType");
  }

  /// Called when the app becomes inactive (background).
  /// Use this to pause operations, save state, etc.
  void onAppPaused() {
    if (kDebugMode) print("onAppPaused: $runtimeType");
  }

  // MARK: - UI Helper Methods
  /// Shows a popup dialog with custom data
  void showPopup({
    required PopupDataModel data,
    bool? barrierDismissible,
    bool showCloseButton = false,
    ButtonsDirection direction = ButtonsDirection.column,
  }) {
    Get.dialog(
      CustomAlertDialog(
        alertData: data.dataAlertModel,
        showCloseButton: showCloseButton,
        direction: direction,
      ),
      barrierDismissible: barrierDismissible ?? true,
    );
  }

  /// Shows an alert dialog with custom data
  void showAlert({
    required DataAlertModel data,
    bool? barrierDismissible,
    bool showCloseButton = true,
    ButtonsDirection direction = ButtonsDirection.column,
  }) {
    Get.dialog(
      CustomAlertDialog(
        alertData: data,
        showCloseButton: showCloseButton,
        direction: direction,
      ),
      barrierDismissible: barrierDismissible ?? false,
    );
  }

  /// Shows an error alert with default styling
  void showAlertError({
    required String content,
    bool? barrierDismissible,
    String headerImage = "assets/images/ic_pipi_03.png",
    bool showCloseButton = true,
    VoidCallback? onConfirmed,
  }) {
    if (AppNavigator.isShowingDialog) return;
    Get.dialog(
      CustomAlertDialog(
        showCloseButton: showCloseButton,
        alertData: DataAlertModel(
          localHeaderImage: headerImage,
          title: "",
          description: content,
          buttons: [
            AlertButton(
              text: "Đã Hiểu",
              onPressed: () {
                Get.back();
                onConfirmed?.call();
              },
              bgColor: BaseColor.primary500,
              textColor: Colors.white,
            ),
          ],
        ),
      ),
      barrierDismissible: barrierDismissible ?? false,
    );
  }

  /// Hides the keyboard
  void hideKeyboard() {
    FocusScope.of(context).unfocus();
  }

  // MARK: - RouteAware Implementation
  @override
  void didPush() {
    _isVisible = true;
    _handleRouteAppear();
  }

  @override
  void didPopNext() => _handleRouteAppear();

  @override
  void didPushNext() => _handleRouteDisappear();

  @override
  void didPop() => _handleRouteDisappear();

  void _handleRouteAppear() {
    onRouteWillAppear();
    WidgetsBinding.instance.addPostFrameCallback((_) => onRouteDidAppear());
  }

  void _handleRouteDisappear() {
    onRouteWillDisappear();
    WidgetsBinding.instance.addPostFrameCallback((_) => onRouteDidDisappear());
  }
}
