import 'package:drift/drift.dart';
import 'package:niogu_app/core/database/app_database.dart';
import 'package:niogu_app/core/entities/custom_activity.dart';
import 'package:niogu_app/core/enums/approval_process.dart';
import 'package:niogu_app/core/enums/canceled_by.dart';
import 'package:niogu_app/core/enums/order_status.dart';
import 'package:niogu_app/core/enums/sync_status.dart';
import 'package:niogu_app/features/online_store/domain/entities/online_store.dart';
import 'package:niogu_app/features/online_store/domain/repositories/i_online_store_repository.dart';

class OnlineStoreRepositoryImpl implements IOnlineStoreRepository {
  final AppDatabase _appDatabase;

  OnlineStoreRepositoryImpl(this._appDatabase);

  @override
  Future<ConfigureOnlineStore> getConfigureOnlineStore() async {
    return await _appDatabase.tenantDao.getConfigureOnlineStore();
  }

  @override
  Future<void> configureOnlineStore(ConfigureOnlineStore configure) async {
    await _appDatabase.tenantDao.configureOnlineStore(configure);
  }

  @override
  Stream<List<OnlineStoreProduct>> watchOnlineStoreProducts() {
    return _appDatabase.tenantDao.watchAllOnlineStoreProducts();
  }

  @override
  Future<int> updateAlreadyOrderOnline(String orderId) async {
    return await _appDatabase.orderDao.updateAlreadyReadOrderOnline(orderId);
  }

  @override
  Stream<MessageActivity?> watchOrderOnlineHasNotReview() {
    return _appDatabase.orderDao.watchOrderOnlineHasNotReview();
  }

  @override
  Stream<int> watchNumberOfNeedToBeProcessed() {
    return _appDatabase.orderDao.watchNumberOfNeedToBeProcessed();
  }

  @override
  Stream<List<OnlineOrder>> watchOnlineOrders({
    String? outletId,
    DateTime? startDate,
    DateTime? endDate,
  }) {
    return _appDatabase.orderDao.watchAllOnlineOrders(
      outletId: outletId,
      startDate: startDate,
      endDate: endDate,
    );
  }

  @override
  Future<OnlineOrderDetail> fetchOnlineOrderDetailById(String orderId) async {
    return await _appDatabase.orderDao.getOnlineOrderDetailById(orderId);
  }

  @override
  Stream<ViewOrderStatus> watchOrderStatusById(String orderId) {
    return _appDatabase.orderDao.watchOrderStatusById(orderId);
  }

  @override
  Future<int> updateOrder({
    required String orderId,
    required OrderStatus orderStatus,
    required bool cancellationAccepted,
    ApprovalProcess? process,
    CanceledBy? canceledBy,
  }) async {
    return await _appDatabase.orderDao.updateOrder(
      orderId: orderId,
      orderStatus: orderStatus,
      cancellationAccepted: cancellationAccepted,
      process: process,
      canceledBy: canceledBy,
    );
  }

  @override
  Future<ShippingConfiguration> fetchShippingConfiguration() async {
    return await _appDatabase.tenantDao.getShippingConfiuration();
  }

  @override
  Future<int> shippingConfiguration(ShippingConfiguration configure) async {
    return await _appDatabase.tenantDao.shippingConfiguration(configure);
  }

  @override
  Future<List<ConfigurePaymentMethod>> fetchConfigurePaymentMethod() async {
    return await _appDatabase.tenantDao.getConfigurePaymentMethod();
  }

  @override
  Future<void> paymentMethodConfiguration(
    List<ConfigurePaymentMethod> configures,
  ) async {
    final List<TenantPaymentMethodsCompanion> companions = [];

    for (final configure in configures) {
      String? sourceName;

      String? accountNumber;

      String? receipentName;

      if (configure.sourceName.isNotEmpty) {
        sourceName = configure.sourceName;
      }

      if (configure.accountNumber.isNotEmpty) {
        accountNumber = configure.accountNumber;
      }

      if (configure.receipentName.isNotEmpty) {
        receipentName = configure.receipentName;
      }

      companions.add(
        TenantPaymentMethodsCompanion(
          localId: Value(configure.localId),
          sourceName: Value(sourceName),
          accountNumber: Value(accountNumber),
          receipentName: Value(receipentName),
          syncStatus: Value(SyncStatus.dirty.status),
        ),
      );
    }

    await _appDatabase.tenantDao.paymentMethodConfiguration(companions);
  }

  @override
  Stream<List<DisplayProductReview>> watchProductReviews() {
    return _appDatabase.productReviewDao.watchAllProductReviews();
  }

  @override
  Stream<DetailProductReview> watchDetailProductReview(String productId) {
    return _appDatabase.productReviewDao.watchDetailProductReview(productId);
  }

  @override
  Stream<List<ProductComment>> watchProductComments(String productId) {
    return _appDatabase.productReviewDao.watchAllProductComments(productId);
  }

  @override
  Future<RatingConfiguration> fetchRatingConfiguration() async {
    return await _appDatabase.tenantDao.getRatingConfiguration();
  }

  @override
  Future<int> ratingConfiguration(RatingConfiguration configuration) async {
    return await _appDatabase.tenantDao.ratingConfiguration(configuration);
  }

  @override
  Stream<List<ProductCampaign>> watchProductCampaigns() {
    return _appDatabase.tenantDao.watchAllProductCampaigns();
  }

  @override
  Stream<List<CategoryCampaign>> watchCategoryCampaigns() {
    return _appDatabase.tenantDao.watchAllCategoryCampaigns();
  }

  @override
  Stream<List<DisplayCampaign>> watchCampaigns() {
    return _appDatabase.campaignDao.watchAllCampaigns();
  }

  @override
  Stream<List<TargetOutlet>> watchTargetOutlets() {
    return _appDatabase.tenantDao.watchAllTargetOutlets();
  }

  @override
  Future<CampaignDetail> fetchCampaignById(String id) async {
    return await _appDatabase.campaignDao.getCampaignById(id);
  }

  @override
  Future<void> saveCampaign({
    required UpsertCampaign campaign,
    List<String>? deleteTargetOutlets,
  }) async {
    return _appDatabase.campaignDao.saveCampaign(campaign, deleteTargetOutlets);
  }

  @override
  Future<void> deleteCampaign(String campaignId) async {
    return _appDatabase.campaignDao.deleteCampaign(campaignId);
  }
}
