import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/base/app_loading.dart';
import 'package:mypoint_flutter_app/networking/app_navigator.dart';
import 'package:mypoint_flutter_app/main.dart' show routeObserver;
import '../networking/dio_http_service.dart';
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;
  bool _isPaused = false;
  ModalRoute<dynamic>? _route;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    if (kDebugMode) {
      print("_show: $runtimeType");
    }
    // Gọi onInit sau khi initState
    WidgetsBinding.instance.addPostFrameCallback((_) {
      onInit();
    });
  }

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.resumed:
        if (_isPaused) {
          _isPaused = false;
          onAppResumed();
          if (_isVisible) {
            // App back to foreground while this route is visible → appear again
            onWillAppear();
            WidgetsBinding.instance.addPostFrameCallback((_) {
              onDidAppear();
            });
          }
        }
        break;
      case AppLifecycleState.paused:
        if (!_isPaused) {
          _isPaused = true;
          onAppPaused();
          if (_isVisible) {
            // App goes to background while this route is visible → disappear
            onWillDisappear();
            WidgetsBinding.instance.addPostFrameCallback((_) {
              onDidDisappear();
            });
          }
        }
        break;
      case AppLifecycleState.inactive:
        onAppInactive();
        break;
      case AppLifecycleState.detached:
        onAppDetached();
        break;
      case AppLifecycleState.hidden:
        onAppHidden();
        break;
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Subscribe to RouteObserver when route is available
    final modalRoute = ModalRoute.of(context);
    if (modalRoute != null && modalRoute is PageRoute && modalRoute != _route) {
      _route = modalRoute;
      routeObserver.subscribe(this, modalRoute);
    }
    if (!_isVisible) {
      _isVisible = true;
      // First time becoming visible in the tree
      onWillAppear();
      // Call did-appear after the frame
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (_isVisible && !_isPaused) {
          onDidAppear();
        }
      });
    }
  }

  @override
  void didUpdateWidget(Screen oldWidget) {
    super.didUpdateWidget(oldWidget);
    // Gọi khi widget được update (có thể do navigation, state changes)
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_isVisible && !_isPaused) {
        onStart();
      }
    });
  }

  // MARK: - Flutter Lifecycle Hooks (Override these in your screens)
  
  /// Called when the widget is first inserted into the tree (similar to viewDidLoad in iOS)
  void onInit() {
    // Override in subclasses
  }

  /// Called when the widget is about to become visible (similar to viewWillAppear in iOS)
  void onResume() {
    // Override in subclasses
  }

  /// Called when the widget has become visible (similar to viewDidAppear in iOS)
  void onStart() {
    // Override in subclasses
  }

  /// Called when the widget is about to become invisible (similar to viewWillDisappear in iOS)
  void onPause() {
    // Override in subclasses
  }

  /// Called when the widget has become invisible (similar to viewDidDisappear in iOS)
  void onStop() {
    // Override in subclasses
  }

  /// Called when the widget is removed from the tree (similar to viewDidUnload in iOS)
  void onDestroy() {
    // Override in subclasses
  }

  // MARK: - Route visibility hooks (Navigator push/pop)

  /// Called right before the route appears (push or uncovered)
  void onWillAppear() {}

  /// Called right after the route appeared
  void onDidAppear() {}

  /// Called right before another route covers this one
  void onWillDisappear() {}

  /// Called right after this route is covered or popped
  void onDidDisappear() {}

  /// Called when app becomes active (similar to applicationDidBecomeActive in iOS)
  void onAppResumed() {
    // Override in subclasses
  }

  /// Called when app becomes inactive (similar to applicationWillResignActive in iOS)
  void onAppPaused() {
    // Override in subclasses
  }

  /// Called when app becomes inactive (similar to applicationWillResignActive in iOS)
  void onAppInactive() {
    // Override in subclasses
  }

  /// Called when app is detached (similar to applicationWillTerminate in iOS)
  void onAppDetached() {
    // Override in subclasses
  }

  /// Called when app is hidden (similar to applicationDidEnterBackground in iOS)
  void onAppHidden() {
    // Override in subclasses
  }

  void showPopup({
    required PopupDataModel data,
    bool? barrierDismissibl,
    bool showCloseButton = false,
    ButtonsDirection direction = ButtonsDirection.column,
  }) {
    Get.dialog(
      CustomAlertDialog(alertData: data.dataAlertModel, showCloseButton: showCloseButton, direction: direction),
      barrierDismissible: barrierDismissibl ?? true,
    );
  }

  void showAlert({
    required DataAlertModel data,
    bool? barrierDismissibl,
    bool showCloseButton = true,
    ButtonsDirection direction = ButtonsDirection.column,
  }) {
    Get.dialog(
      CustomAlertDialog(alertData: data, showCloseButton: showCloseButton, direction: direction),
      barrierDismissible: barrierDismissibl ?? false,
    );
  }

  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();
                if (onConfirmed != null) {
                  onConfirmed();
                }
              },
              bgColor: BaseColor.primary500,
              textColor: Colors.white,
            ),
          ],
        ),
      ),
      barrierDismissible: barrierDismissible ?? false,
    );
  }

  void hideKeyboard() {
    FocusScope.of(context).unfocus();
  }

  void printDebug(dynamic data) {
    if (kDebugMode) {
      print(data);
    }
  }

  Widget? createBottomBar() {
    return null;
  }

  // MARK: - RouteAware overrides mapping to hooks

  @override
  void didPush() {
    onWillAppear();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      onDidAppear();
    });
  }

  @override
  void didPopNext() {
    onWillAppear();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      onDidAppear();
    });
  }

  @override
  void didPushNext() {
    onWillDisappear();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      onDidDisappear();
    });
  }

  @override
  void didPop() {
    onWillDisappear();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      onDidDisappear();
    });
  }
}
