import 'package:niogu_app/core/enums/approval_process.dart';
import 'package:niogu_app/core/enums/campaign_type.dart';
import 'package:niogu_app/core/enums/canceled_by.dart';
import 'package:niogu_app/core/enums/delivery_fee_type.dart';
import 'package:niogu_app/core/enums/delivery_type.dart';
import 'package:niogu_app/core/enums/order_status.dart';
import 'package:niogu_app/core/enums/review_display_policy.dart';
import 'package:niogu_app/core/enums/review_display_type.dart';
import 'package:niogu_app/core/enums/stock_type.dart';
import 'package:uuid/uuid.dart';

class ConfigureOnlineStore {
  final String onlineStoreName;
  final String onlineOpenTime;
  final String onlineCloseTime;
  final bool isCloseService;
  final int preparationTimeMinutes;
  final int orderIntervalMinutes;
  final List<String> productIds;

  const ConfigureOnlineStore({
    required this.onlineStoreName,
    required this.onlineOpenTime,
    required this.onlineCloseTime,
    required this.isCloseService,
    required this.preparationTimeMinutes,
    required this.orderIntervalMinutes,
    required this.productIds,
  });
}

enum OnlineStoreProductEmpty {
  loading,
  empty_database,
  empty_search_result,
  has_data,
}

class OnlineStoreProduct {
  final String id;
  final String name;
  final StockType stockType;
  final double remainingStock;
  final String unit;
  final double sellingPrice;
  final String? imagePath;
  final bool hasVariant;
  final List<VariantOnlineStoreProduct> variants;
  final bool hasBeenDelete;

  const OnlineStoreProduct({
    required this.id,
    required this.name,
    required this.stockType,
    required this.remainingStock,
    required this.unit,
    required this.sellingPrice,
    this.imagePath,
    required this.hasVariant,
    required this.variants,
    required this.hasBeenDelete,
  });
}

class VariantOnlineStoreProduct {
  final String id;
  final String name;
  final StockType stockType;
  final double remainingStock;
  final String unit;
  final double sellingPrice;
  final bool isProductVariant;
  final bool hasBeenDelete;

  const VariantOnlineStoreProduct({
    required this.id,
    required this.name,
    required this.stockType,
    required this.remainingStock,
    required this.unit,
    required this.sellingPrice,
    required this.isProductVariant,
    required this.hasBeenDelete,
  });
}

enum OnlineOrderEmpty { loading, empty_database, empty_search_result, has_data }

class OnlineOrder {
  final String id;
  final String? displayImage;
  final String orderNumber;
  final OrderStatus orderStatus;
  final bool isCancellation;
  final bool cancellationAccepted;
  final ApprovalProcess process;
  final int itemCount;
  final double orderTotal;
  final DateTime orderDate;

  const OnlineOrder({
    required this.id,
    this.displayImage,
    required this.orderNumber,
    required this.orderStatus,
    required this.isCancellation,
    required this.cancellationAccepted,
    required this.process,
    required this.itemCount,
    required this.orderTotal,
    required this.orderDate,
  });
}

class OnlineOrderDetail {
  final String id;
  final String outletName;
  final String orderNumber;
  final DateTime orderDate;
  final String? notes;
  final OrderStatus orderStatus;
  final bool isCancellation;
  final bool cancellationAccepted;
  final ApprovalProcess process;
  final DeliveryType deliveryType;
  final DeliveryInfo deliveryInfo;
  final String paymentMethod;
  final String paymentProof;
  final List<OnlineOrderItem> items;
  final double totalOrder;
  final double deliveryFee;
  final double totalAmount;

  const OnlineOrderDetail({
    required this.id,
    required this.outletName,
    required this.orderNumber,
    required this.orderDate,
    this.notes,
    required this.orderStatus,
    required this.isCancellation,
    required this.cancellationAccepted,
    required this.process,
    required this.deliveryType,
    required this.deliveryInfo,
    required this.paymentMethod,
    required this.paymentProof,
    required this.items,
    required this.totalOrder,
    required this.deliveryFee,
    required this.totalAmount,
  });
}

class DeliveryInfo {
  final String name;
  final String phoneNumber;
  final String fullAddress;
  final String preference;

  const DeliveryInfo({
    required this.name,
    required this.phoneNumber,
    required this.fullAddress,
    required this.preference,
  });
}

class OnlineOrderItem {
  final String? imagePath;
  final String name;
  final String? variantName;
  final double sellingPrice;
  final double quantity;
  final double subtotal;

  const OnlineOrderItem({
    this.imagePath,
    required this.name,
    this.variantName,
    required this.sellingPrice,
    required this.quantity,
    required this.subtotal,
  });
}

class ViewOrderStatus {
  final bool isCancellation;
  final bool cancellationAccepted;
  final ApprovalProcess process;
  final OrderStatus orderStatus;
  final CanceledBy? canceledBy;

  const ViewOrderStatus({
    required this.isCancellation,
    required this.cancellationAccepted,
    required this.process,
    required this.orderStatus,
    required this.canceledBy,
  });
}

class ShippingConfiguration {
  final bool allowCOD;
  final DeliveryFeeType deliveryFeeType;
  final double maxDeliveryRadiusKm;
  final double deliveryFlatFee;
  final double deliveryFeePerKm;
  final double deliveryBaseFee;

  const ShippingConfiguration({
    required this.allowCOD,
    required this.deliveryFeeType,
    required this.maxDeliveryRadiusKm,
    required this.deliveryFlatFee,
    required this.deliveryFeePerKm,
    required this.deliveryBaseFee,
  });
}

class ConfigurePaymentMethod {
  final String localId;
  final String sourceName;
  final String accountNumber;
  final String receipentName;

  ConfigurePaymentMethod({
    String? localId,
    required this.sourceName,
    required this.accountNumber,
    required this.receipentName,
  }) : localId = localId ?? Uuid().v7().toString();
}

class DisplayProductReview {
  final String id;
  final String? imagePath;
  final String name;
  final double averageRating;
  final double totalSoldInOnlineStore;
  final double totalSoldInPos;
  final String unit;

  const DisplayProductReview({
    required this.id,
    this.imagePath,
    required this.name,
    required this.averageRating,
    required this.totalSoldInOnlineStore,
    required this.totalSoldInPos,
    required this.unit,
  });

  DisplayProductReview copyWith({
    double? averageRating,
    double? totalSoldInOnlineStore,
    double? totalSoldInPos,
  }) {
    return DisplayProductReview(
      id: id,
      imagePath: imagePath,
      name: name,
      averageRating: averageRating ?? this.averageRating,
      totalSoldInOnlineStore:
          totalSoldInOnlineStore ?? this.totalSoldInOnlineStore,
      totalSoldInPos: totalSoldInPos ?? this.totalSoldInPos,
      unit: unit,
    );
  }
}

class DetailProductReview {
  final List<String> imagePaths;
  final String name;
  final double averageRating;
  final int totalRating;
  final RatingDistribution rating;
  final int totalLike;

  const DetailProductReview({
    required this.imagePaths,
    required this.name,
    required this.averageRating,
    required this.totalRating,
    required this.rating,
    required this.totalLike,
  });
}

class RatingDistribution {
  final List<double> values;

  const RatingDistribution(this.values);

  double get star1 => values[0];
  double get star2 => values[1];
  double get star3 => values[2];
  double get star4 => values[3];
  double get star5 => values[4];
}

class ProductComment {
  final String name;
  final int rating;
  final String? variantName;
  final String? comment;
  final DateTime date;

  const ProductComment({
    required this.name,
    required this.rating,
    this.variantName,
    this.comment,
    required this.date,
  });
}

class RatingConfiguration {
  final ReviewDisplayType type;
  final ReviewDisplayPolicy policy;

  const RatingConfiguration({required this.type, required this.policy});
}

enum ProductCampaignEmpty {
  loading,
  empty_database,
  empty_search_result,
  has_data,
}

class ProductCampaign {
  final String id;
  final String? imagePath;
  final String name;
  final StockType stockType;
  final double remainingStock;
  final String unit;

  const ProductCampaign({
    required this.id,
    this.imagePath,
    required this.name,
    required this.stockType,
    required this.remainingStock,
    required this.unit,
  });
}

enum CategoryCampaignEmpty {
  loading,
  empty_database,
  empty_search_result,
  has_data,
}

class CategoryCampaign {
  final String id;
  final String? imagePath;
  final String name;
  final int productUseAmount;

  const CategoryCampaign({
    required this.id,
    this.imagePath,
    required this.name,
    required this.productUseAmount,
  });
}

class SelectedItemCampaign {
  final String id;
  final String name;
  final CampaignType type;

  const SelectedItemCampaign({
    required this.id,
    required this.name,
    required this.type,
  });
}

class TargetOutlet {
  final String id;
  final String name;
  final String? address;

  const TargetOutlet({required this.id, required this.name, this.address});
}

class SelectedTargetOutlet {
  final String? id;
  final String outletId;
  final String name;

  const SelectedTargetOutlet({
    this.id,
    required this.outletId,
    required this.name,
  });

  SelectedTargetOutlet copyWith({String? id}) {
    return SelectedTargetOutlet(id: id, outletId: outletId, name: name);
  }
}

class DisplayCampaign {
  final String id;
  final String imagePath;
  final String name;
  final DateTime? startDate;
  final DateTime? endDate;
  final bool isActive;
  final int outletUseAmount;

  const DisplayCampaign({
    required this.id,
    required this.imagePath,
    required this.name,
    this.startDate,
    this.endDate,
    required this.isActive,
    required this.outletUseAmount,
  });
}

class CampaignDetail {
  final String id;
  final String imagePath;
  final String name;
  final DateTime? startDate;
  final DateTime? endDate;
  final CampaignType? campaignType;
  final String? linkId;
  final String? linkName;
  final List<SelectedTargetOutlet> targetOutlets;
  final bool isActive;

  const CampaignDetail({
    required this.id,
    required this.imagePath,
    required this.name,
    this.startDate,
    this.endDate,
    this.campaignType,
    this.linkId,
    this.linkName,
    required this.targetOutlets,
    required this.isActive,
  });
}

class UpsertCampaign {
  final String id;
  final String imagePath;
  final String name;
  final DateTime? startDate;
  final DateTime? endDate;
  final CampaignType? campaignType;
  final String? linkId;
  final List<UpsertTargetOutlet> targetOutlets;
  final bool isActive;

  UpsertCampaign({
    String? id,
    required this.imagePath,
    required this.name,
    this.startDate,
    this.endDate,
    this.campaignType,
    this.linkId,
    required this.targetOutlets,
    this.isActive = true,
  }) : id = id ?? const Uuid().v7().toString();
}

class UpsertTargetOutlet {
  final String id;
  final String outletId;

  UpsertTargetOutlet({String? id, required this.outletId})
    : id = id ?? const Uuid().v7().toString();
    
}
