import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:share_plus/share_plus.dart';
import 'package:syncrow_app/features/app_layout/model/permission_model.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
import 'package:syncrow_app/features/auth/model/project_model.dart';
import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
import 'package:syncrow_app/features/menu/view/menu_view.dart';
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_event.dart';
import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart';
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
import 'package:syncrow_app/features/scene/view/routines_view.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/navigation/navigation_service.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/services/api/profile_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/constants/temp_const.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
part 'home_state.dart';

class HomeCubit extends Cubit<HomeState> {
  HomeCubit._() : super(HomeInitial()) {
    // checkIfNotificationPermissionGranted();
    fetchUserInfo().then(
      (value) {
        if (selectedSpace == null) {
          fetchUnitsByUserId();
          fetchPermissions();

          // .then((value) {
          //   if (selectedSpace != null) {
          //     fetchRoomsByUnitId(selectedSpace!);
          //   }
          // });
        }
      },
    );
  }
  static UserModel? user;

  List<PermissionModel>? permissionModel = [];

  static HomeCubit? _instance;
  static HomeCubit getInstance() {
    // If an instance already exists, return it
    _instance ??= HomeCubit._();
    return _instance!;
  }

  Future fetchUserInfo() async {
    try {
      emit(HomeLoading());
      var uuid =
          await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
      user = await ProfileApi().fetchUserInfo(uuid);
      project = user?.project;

      emit(HomeUserInfoLoaded(user!));
    } catch (e) {
      return;
    }
  }

  static bool manageSupSpace = false;
  static bool manageScene = false;
  static bool manageDeviceLocation = false;
  static bool visitorPasswordManagement = false;
  String errorMsg = '';

  Future<void> fetchPermissions() async {
    try {
      emit(HomeLoading());
      final response = await ProfileApi().fetchPermissions(user!.role!.uuid);
      permissionModel = PermissionModel.fromJsonList(response);
      hasViewPermission();
      emit(PermissionsRoleLoaded(permissionModel!));
    } catch (e) {
      emit(HomeError(e.toString()));
    }
  }

  void hasViewPermission() {
    emit(HomeLoading());

    manageSupSpace = hasPermission(
      permissionModel!,
      'SPACE_MANAGEMENT',
      'MANAGE_SPACE',
      'ASSIGN_USER_TO_SPACE',
    );
    manageScene = hasPermission(
      permissionModel!,
      'AUTOMATION_MANAGEMENT',
      'MANAGE_SCENES',
      'UPDATE',
    );
    manageDeviceLocation = hasPermission(
      permissionModel!,
      'DEVICE_MANAGEMENT',
      'MANAGE_DEVICE',
      'LOCATION_UPDATE',
    );
    visitorPasswordManagement = hasPermission(
      permissionModel!,
      'VISITOR_PASSWORD_MANAGEMENT',
      'MANAGE_VISITOR_PASSWORD',
      'VIEW',
    );
    emit(HomePermissionUpdated());
  }

  bool hasPermission(List<PermissionModel> permissions, String mainTitle,
      String subTitle, String finalTitle) {
    try {
      final mainOption = permissions.firstWhere(
        (perm) => perm.title == mainTitle,
      );

      final subOption = mainOption.subOptions.firstWhere(
        (sub) => sub.title == subTitle,
      );

      if (subOption.subOptions == null) {
        return false;
      }

      final finalOption = subOption.subOptions!.firstWhere(
        (finalSub) => finalSub.title == finalTitle,
      );
      return finalOption.isChecked == true;
    } catch (e) {
      return false;
    }
  }

  void emitSafe(HomeState newState) {
    final cubit = this;
    if (!cubit.isClosed) {
      cubit.emit(newState);
    }
  }

  @override
  Future<void> close() {
    _instance = null;
    selectedSpace = null;
    selectedRoom = null;
    pageIndex = 0;
    // OneSignal.User.pushSubscription
    //     .removeObserver((stateChanges) => oneSignalSubscriptionObserver);
    // OneSignal.Notifications.removePermissionObserver(
    //     (permission) => oneSignalPermissionObserver);
    // OneSignal.Notifications.removeClickListener(
    //     (event) => oneSignalClickListenerObserver);
    return super.close();
  }

  static HomeCubit get(context) => BlocProvider.of(context);

  List<SpaceModel> spaces = [];

  SpaceModel? selectedSpace;

  SubSpaceModel? selectedRoom;

  Project? project;

  PageController devicesPageController = PageController();

  PageController roomsPageController = PageController();

  var duration = const Duration(milliseconds: 300);

  // void oneSignalPermissionObserver;
  // void oneSignalSubscriptionObserver;
  // void oneSignalClickListenerObserver;

  // selectSpace(SpaceModel space) async {
  //   selectedSpace = space;
  //   emit(SpaceSelected(space));
  // }

  checkIfNotificationPermissionGranted() async {
    try {
      OneSignal.initialize('762350c9-1e5d-4d95-a648-16d4dc8a25e1');

      //Show native push notification dialog
      if (Platform.isIOS) {
        await OneSignal.Notifications.permissionNative();
      } else {
        await OneSignal.Notifications.requestPermission(true);
      }

      if (await Permission.notification.isGranted == false) {
        return;
      }

      var userUuid =
          await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
              '';
      if (userUuid.isNotEmpty) {
        await OneSignal.login(userUuid);
      }
      //Enable push notifications
      await OneSignal.User.pushSubscription.optIn();

      // //this function will be called once a user is subscribed
      // oneSignalSubscriptionObserver =
      //     OneSignal.User.pushSubscription.addObserver((state) async {
      //   if (state.current.optedIn) {
      //     await _sendSubscriptionId();
      //   }
      // });

      // // Send the player id when a user allows notifications
      // oneSignalPermissionObserver =
      //     OneSignal.Notifications.addPermissionObserver((state) async {
      //   await _sendSubscriptionId();
      // });

      // //check if the player id is sent, if not send it again
      // await _sendSubscriptionId();

      // oneSignalClickListenerObserver =
      //     OneSignal.Notifications.addClickListener((event) async {
      //   //Once the user clicks on the notification
      // });
    } catch (err) {
      debugPrint("******* Error");
      debugPrint(err.toString());
      rethrow;
    }
  }

  _sendSubscriptionId() async {
    // String? subscriptionId = OneSignal.User.pushSubscription.id ?? '';
    //TODO send the subscription id to BE
  }

  changeSelectedSpace(SpaceModel space) {
    selectedSpace = space;
    emitSafe(SpaceSelected(space));
    fetchRoomsByUnitId(space);
  }

  roomSliderPageChanged(int index) {
    devicesPageController.animateToPage(
      index,
      duration: duration,
      curve: Curves.linear,
    );

    if (index == 0) {
      unselectRoom();
    } else if (index == 1) {
      unselectRoom1();
    } else {
      selectedRoom = selectedSpace!.subspaces[index - 2];
      emitSafe(RoomSelected(selectedRoom!));
    }
  }

  devicesPageChanged(int index) {
    roomsPageController.animateToPage(
      index,
      duration: const Duration(milliseconds: 300),
      curve: Curves.linear,
    );

    if (index <= 0) {
      unselectRoom();
    } else if (index == 1) {
      unselectRoom1();
    } else {
      selectedRoom = selectedSpace!.subspaces[index - 2];
      emitSafe(RoomSelected(selectedRoom!));
    }
  }

  unselectRoom() {
    // selectedRoom = null;
    devicesPageController.animateToPage(
      0,
      duration: duration,
      curve: Curves.linear,
    );

    roomsPageController.animateToPage(
      0,
      duration: duration,
      curve: Curves.linear,
    );

    emitSafe(RoomUnSelected());
  }

  unselectRoom1() {
    // selectedRoom = null;
    devicesPageController.animateToPage(
      1,
      duration: duration,
      curve: Curves.linear,
    );

    roomsPageController.animateToPage(
      1,
      duration: duration,
      curve: Curves.linear,
    );

    emitSafe(RoomUnSelected());
  }

//////////////////////////////////////// API ////////////////////////////////////////
  generateInvitation(SpaceModel unit) async {
    try {
      final invitationCode = await SpacesAPI.generateInvitationCode(unit.id,
          unit.community.uuid, project?.uuid ?? TempConst.projectIdDev);
      if (invitationCode.isNotEmpty) {
        Share.share('The invitation code is $invitationCode');
        CustomSnackBar.displaySnackBar(
            'Invitation code generated successfully the code is: $invitationCode');
      } else {
        CustomSnackBar.displaySnackBar('Please try again!');
      }
    } catch (failure) {
      CustomSnackBar.displaySnackBar('Something went wrong');
      return;
    }
  }

  Future<bool> joinAUnit(String code) async {
    try {
      var userUuid =
          await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
              '';
      Map<String, String> body = {'inviteCode': code};

      final success = await SpacesAPI.joinUnit(userUuid, body);
      if (success) {
        await fetchUnitsByUserId();
        CustomSnackBar.displaySnackBar('Done successfully');
      }
      return true;
    } catch (failure) {
      CustomSnackBar.displaySnackBar('Something went wrong');
      return false;
    }
  }

  fetchUnitsByUserId() async {
    emitSafe(GetSpacesLoading());
    try {
      spaces = await SpacesAPI.getSpacesByUserId();
      emitSafe(GetSpacesSuccess(spaces));
    } catch (failure) {
      emitSafe(GetSpacesError("No units found"));
      return;
    }

    if (spaces.isNotEmpty) {
      selectedSpace = spaces.first;
      await fetchRoomsByUnitId(selectedSpace!);
      emitSafe(GetSpacesSuccess(spaces));
    } else {
      emitSafe(GetSpacesError("No spaces found"));
    }
  }

  fetchRoomsByUnitId(SpaceModel space) async {
    emitSafe(GetSpaceRoomsLoading());
    try {
      space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(
          space.community.uuid,
          space.id,
          project?.uuid ?? TempConst.projectIdDev);
    } catch (failure) {
      emitSafe(GetSpaceRoomsError(failure.toString()));
      return;
    }
    if (space.subspaces.isNotEmpty) {
      emitSafe(GetSpaceRoomsSuccess(space.subspaces));
    } else {
      emitSafe(GetSpaceRoomsError("No rooms found"));
    }
  }

  activationCode(activationCode) async {
    try {
      emitSafe(GetSpaceRoomsLoading());
      var uuid =
          await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
      var res = await SpacesAPI.activationCodeSpace(
          activationCode: activationCode, userUuid: uuid);

      if (res['success'] == true) {
        fetchUserInfo();
        fetchUnitsByUserId();
      }
      emitSafe(GetSpacesSuccess(spaces!));

      return res['success'];
    } on DioException catch (e) {
      final errorMessage = e.response?.data['error']['message'];
      errorMsg = e.response?.data['error']['message'];
      emitSafe(ActivationError(errMessage: errorMsg));
      return false;
    }
  }

  /////////////////////////////////////// Nav ///////////////////////////////////////

  static int pageIndex = 0;

  static Map<String, List<Widget>> appBarActions = {
    // 'Dashboard': [
    //   // IconButton(
    //   //   icon: const Icon(
    //   //     Icons.add,
    //   //     size: 25,
    //   //   ),
    //   //   style: ButtonStyle(
    //   //     foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
    //   //   ),
    //   //   onPressed: () {
    //   //     Navigator.push(
    //   //       NavigationService.navigatorKey.currentContext!,
    //   //       CustomPageRoute(
    //   //         builder: (context) => CurtainView(
    //   //           curtain: DeviceModel(
    //   //             name: "Curtain",
    //   //             status: [StatusModel(code: "awd", value: 1)],
    //   //             productType: DeviceType.Curtain,
    //   //           ),
    //   //         ),
    //   //       ),
    //   //     );
    //   //   },
    //   // ),
    // ],
    'Devices': [
      //TODO: to be checked
      // IconButton(
      //   icon: const Icon(
      //     Icons.add,
      //     size: 25,
      //   ),
      //   style: ButtonStyle(
      //     foregroundColor:
      //         MaterialStateProperty.all(ColorsManager.textPrimaryColor),
      //   ),
      //   onPressed: () {},
      // ),
      // IconButton(
      //   icon: const Icon(
      //     Icons.more_vert,
      //     size: 25,
      //   ),
      //   style: ButtonStyle(
      //     foregroundColor:
      //         MaterialStateProperty.all(ColorsManager.textPrimaryColor),
      //   ),
      //   onPressed: () {},
      // ),
    ],
    'Routine': [
      // IconButton(
      //   icon: Image.asset(
      //     Assets.assetsIconsFilter,
      //     height: 20,
      //     width: 20,
      //   ),
      //   onPressed: () {},
      // ),
      manageScene
          ? IconButton(
              icon: const Icon(
                Icons.add,
                size: 32,
              ),
              style: ButtonStyle(
                foregroundColor:
                    WidgetStateProperty.all(ColorsManager.textPrimaryColor),
              ),
              onPressed: () {
                Navigator.pushNamed(
                  NavigationService.navigatorKey.currentContext!,
                  Routes.sceneTasksRoute,
                  arguments: SceneSettingsRouteArguments(
                    sceneType: '',
                    sceneId: '',
                    sceneName: '',
                  ),
                );
                NavigationService.navigatorKey.currentContext!
                    .read<CreateSceneBloc>()
                    .add(const ClearTaskListEvent());
                NavigationService.navigatorKey.currentContext!
                    .read<CreateSceneBloc>()
                    .add(const SceneTypeEvent(CreateSceneEnum.none));
                NavigationService.navigatorKey.currentContext!
                    .read<SmartSceneSelectBloc>()
                    .add(const SmartSceneClearEvent());
                BlocProvider.of<EffectPeriodBloc>(
                        NavigationService.navigatorKey.currentState!.context)
                    .add(ResetEffectivePeriod());
                NavigationService.navigatorKey.currentContext!
                    .read<CreateSceneBloc>()
                    .add(const ClearTabToRunSetting());
              },
            )
          : const SizedBox(),
      // IconButton(
      //   icon: const Icon(
      //     Icons.more_vert,
      //     size: 28,
      //   ),
      //   style: ButtonStyle(
      //     foregroundColor:
      //         WidgetStateProperty.all(ColorsManager.textPrimaryColor),
      //   ),
      //   onPressed: () {},
      // ),
    ],
    'Menu': [
      // IconButton(
      //   icon: SvgPicture.asset(
      //     Assets.assetsIconsScan,
      //     height: 20,
      //     width: 20,
      //   ),
      //   onPressed: () {},
      // ),
    ],
  };

  static Map<String, Widget?> appBarLeading = {
    // 'Dashboard': const AppBarHomeDropdown(),
    'Devices': const AppBarHomeDropdown(),
    'Routine': const AppBarHomeDropdown(),
    'Menu': Padding(
      padding: const EdgeInsets.only(left: 15),
      child: Image.asset(
        Assets.assetsImagesLogoHorizontal,
        height: 15,
        width: 100,
        fit: BoxFit.scaleDown,
      ),
    ),
  };

  static var bottomNavItems = [
    // defaultBottomNavBarItem(icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
    // defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
    defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
    defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
    defaultBottomNavBarItem(icon: Assets.assetsIconsMenu, label: 'Menu'),
  ];

  final List<Widget> pages = [
    // const DashboardView(),
    // const LayoutPage(),
    BlocProvider(
      create: (context) => DevicesCubit.getInstance(),
      child: const DevicesViewBody(),
    ),
    const RoutinesView(),
    const MenuView(),
  ];

  void updatePageIndex(int index) {
    pageIndex = index;

    emitSafe(NavChangePage());
  }

  void updateDevice(String deviceId) async {
    try {
      final response = await DevicesAPI.firmwareDevice(
          deviceId: deviceId, firmwareVersion: '0');
      if (response['success'] ?? false) {
        CustomSnackBar.displaySnackBar('No updates available');
      }
    } catch (_) {}
  }
}

BottomNavigationBarItem defaultBottomNavBarItem(
    {required String icon, required String label}) {
  return BottomNavigationBarItem(
    icon: SvgPicture.asset(icon),
    activeIcon: SvgPicture.asset(
      icon.replaceAll('.svg', '-fill.svg'),
      colorFilter: const ColorFilter.mode(
        ColorsManager.primaryColor,
        BlendMode.srcIn,
      ),
    ),
    label: label,
  );
}


// class PermissionUtils {
//   // Check if the "VIEW" permission exists in "MANAGE_SUBSPACE"
//   static bool hasViewPermission(List<dynamic> permissions) {
//     return _hasPermission(permissions, 'MANAGE_SUBSPACE', 'VIEW');
//   }

//   // Generalized permission checker
//   static bool _hasPermission(
//       List<dynamic> permissions, String mainTitle, String subTitle) {
//     final mainOption = permissions.firstWhere(
//       (perm) => perm['title'] == mainTitle,
//       orElse: () => null,
//     );
//     if (mainOption != null) {
//       final subOption = mainOption['subOptions'].firstWhere(
//         (sub) => sub['title'] == subTitle,
//         orElse: () => null,
//       );
//       return subOption != null && subOption['isChecked'] == true;
//     }
//     return false;
//   }
// }
