import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:hub/features/auth/index.dart';
import 'package:hub/features/menu/index.dart';
import 'package:hub/features/module/index.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/extensions/dialog_extensions.dart';
import 'package:hub/shared/utils/path_util.dart';

abstract class MenuLocalDataSource {
  Future<MenuItem?> addMenuEntry(Key key, EnumMenuItem item,
      List<MenuItem?> entries, IconData icon, String text, Function() action);

  Future<bool> processDisplayDefault(
      EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);

  Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
      List<MenuItem?> entries);

  Future<bool> processStartDate(String startDate, MenuEntry entry);

  Future<bool> processExpirationDate(String expirationDate, MenuEntry entry);
}

class MenuLocalDataSourceImpl implements MenuLocalDataSource {
  static final MenuLocalDataSourceImpl _instance =
      MenuLocalDataSourceImpl._internal();

  factory MenuLocalDataSourceImpl() => _instance;

  MenuLocalDataSourceImpl._internal();

  @override
  Future<MenuItem?> addMenuEntry(
    Key key,
    EnumMenuItem item,
    List<MenuItem?> entries,
    IconData icon,
    String text,
    Function() action,
  ) async {
    final menuItem = item == EnumMenuItem.button
        ? ButtonMenuItem(key: key, icon: icon, action: action, title: text)
        : item == EnumMenuItem.card || item == EnumMenuItem.tile
            ? CardMenuItem(key: key, icon: icon, action: action, title: text)
            : null;
    if (menuItem != null) {
      entries.add(menuItem);
    }
    return null;
  }

  @override
  Future<bool> processDisplayDefault(
      EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
    if (opt.key == 'FRE-HUB-LOGOUT') {
      await addMenuEntry(
          ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
          () async {
        await AuthenticationService.signOut(navigatorKey.currentContext!);
      });
      return true;
    } else
      return false;
  }

  @override
  Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
      List<MenuItem?> entries) async {
    try {
      switch (display.value) {
        case 'VISIVEL':
          await addMenuEntry(
              ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
              () async {
            await PathUtil.nav(opt.route);
          });
          break;
        case 'DESABILITADO':
          await addMenuEntry(
              ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
              () async {
            await DialogUnavailable.unavailableFeature(
                navigatorKey.currentContext!);
          });
          break;
        case 'INVISIVEL':
          break;
      }
    } catch (e) {
      log('Error processing display for module ${opt.key}: $e');
    }
  }

  @override
  Future<bool> processStartDate(String startDate, MenuEntry opt) async {
    try {
      if (startDate.isEmpty) return true;
      final start = DateTime.tryParse(startDate);
      if (start == null) return false;
      return DateTime.now().isAfter(start);
    } catch (e) {
      log('Error processing start date for module ${opt.key}: $e');
    }
    return false;
  }

  @override
  Future<bool> processExpirationDate(
      String expirationDate, MenuEntry opt) async {
    try {
      if (expirationDate.isEmpty) return false;
      final expiration = DateTime.tryParse(expirationDate);
      return expiration != null && DateTime.now().isAfter(expiration);
    } catch (e) {
      log('Error processing expiration date for module ${opt.key}: $e');
    }
    return false;
  }
}
