/// Providers: Orders
///
/// Riverpod providers for managing orders state.
library;

import 'package:hive_ce/hive.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/features/orders/data/datasources/order_status_local_datasource.dart';
import 'package:worker/features/orders/data/models/order_status_model.dart';
import 'package:worker/features/orders/domain/entities/order.dart';
import 'package:worker/features/orders/domain/entities/order_detail.dart';
import 'package:worker/features/orders/domain/entities/order_status.dart';
import 'package:worker/features/orders/presentation/providers/order_repository_provider.dart';

part 'orders_provider.g.dart';

/// Orders Provider
///
/// Provides list of all orders from repository (Clean Architecture).
@riverpod
class Orders extends _$Orders {
  @override
  Future<List<Order>> build() async {
    // Fetch orders from repository
    try {
      final repository = await ref.read(orderRepositoryProvider.future);
      return await repository.getOrdersList(
        limitStart: 0,
        limitPageLength: 0, // 0 = get all
      );
    } catch (e) {
      // Return empty list on error
      return [];
    }
  }

  /// Refresh orders
  Future<void> refresh() async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async {
      final repository = await ref.read(orderRepositoryProvider.future);
      return await repository.getOrdersList(
        limitStart: 0,
        limitPageLength: 0,
      );
    });
  }
}

/// Selected Order Status Provider
///
/// Tracks the currently selected order status filter.
/// null means "All" orders.
@riverpod
class SelectedOrderStatus extends _$SelectedOrderStatus {
  @override
  String? build() {
    return null; // Default: show all orders
  }

  /// Select a status filter
  void selectStatus(String? status) {
    state = status;
  }

  /// Clear selection (show all)
  void clearSelection() {
    state = null;
  }
}

/// Order Search Query Provider
///
/// Tracks the current search query for order numbers.
@riverpod
class OrderSearchQuery extends _$OrderSearchQuery {
  @override
  String build() {
    return '';
  }

  /// Update search query
  void updateQuery(String query) {
    state = query;
  }

  /// Clear search query
  void clearQuery() {
    state = '';
  }
}

/// Orders Count by Status Provider
///
/// Returns count of orders for each status.
@riverpod
Future<Map<String, int>> ordersCountByStatus(Ref ref) async {
  final ordersAsync = ref.watch(ordersProvider);

  return ordersAsync.when(
    data: (orders) {
      final counts = <String, int>{};

      // Count orders by their status string
      for (final order in orders) {
        counts[order.status] = (counts[order.status] ?? 0) + 1;
      }

      return counts;
    },
    loading: () => {},
    error: (error, stack) => {},
  );
}

/// Total Orders Count Provider
@riverpod
Future<int> totalOrdersCount(Ref ref) async {
  final ordersAsync = ref.watch(ordersProvider);

  return ordersAsync.when(
    data: (orders) => orders.length,
    loading: () => 0,
    error: (error, stack) => 0,
  );
}

/// Order Status Hive Box Provider
///
/// Provides direct access to the Hive box for order statuses.
/// Use this to read data directly from Hive in the UI.
@riverpod
Box<dynamic> orderStatusHiveBox(Ref ref) {
  return Hive.box(HiveBoxNames.orderStatusBox);
}

/// Helper: Get Order Status by Label
///
/// Returns the OrderStatusModel for a given label (e.g., "Chờ phê duyệt").
/// Returns null if not found.
OrderStatusModel? getOrderStatusByLabel(Box<dynamic> box, String label) {
  final statuses = box.values.whereType<OrderStatusModel>();
  try {
    return statuses.firstWhere((status) => status.label == label);
  } catch (e) {
    return null;
  }
}

/// Helper: Get Order Status by Index
///
/// Returns the OrderStatusModel for a given index.
/// Returns null if not found.
OrderStatusModel? getOrderStatusByIndex(Box<dynamic> box, int index) {
  final status = box.get(index);
  return status is OrderStatusModel ? status : null;
}

/// Order Status List Provider
///
/// Provides cached order status list with automatic refresh.
/// Uses cache-first strategy with API fallback.
@riverpod
Future<List<OrderStatus>> orderStatusList(Ref ref) async {
  final repository = await ref.watch(orderRepositoryProvider.future);
  return await repository.getOrderStatusList();
}

/// Order Detail Provider
///
/// Provides detailed order information by order ID.
@riverpod
Future<OrderDetail> orderDetail(Ref ref, String orderId) async {
  final repository = await ref.watch(orderRepositoryProvider.future);
  return await repository.getOrderDetail(orderId);
}

/// Update Order Address Action
///
/// Updates the shipping and billing addresses for an order.
@Riverpod(keepAlive: true)
class UpdateOrderAddress extends _$UpdateOrderAddress {
  @override
  FutureOr<void> build() {
    // No initial state needed
  }

  /// Update order address
  Future<void> updateAddress({
    required String orderId,
    required String shippingAddressName,
    required String customerAddress,
  }) async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async {
      final repository = await ref.read(orderRepositoryProvider.future);
      await repository.updateOrderAddress(
        orderId: orderId,
        shippingAddressName: shippingAddressName,
        customerAddress: customerAddress,
      );
    });
  }
}

/// Cancel Order Action
///
/// Cancels an order (only allowed for "Chờ phê duyệt" status).
@Riverpod(keepAlive: true)
class CancelOrder extends _$CancelOrder {
  @override
  FutureOr<void> build() {
    // No initial state needed
  }

  /// Cancel order
  Future<void> cancel(String orderId) async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async {
      final repository = await ref.read(orderRepositoryProvider.future);
      await repository.cancelOrder(orderId);
    });
  }
}
