part of '../analytic_dtos.dart';

@freezed
class PurchasingAnalyticDto with _$PurchasingAnalyticDto {
  const PurchasingAnalyticDto._();

  const factory PurchasingAnalyticDto({
    @JsonKey(name: 'organization_id') String? organizationId,
    @JsonKey(name: 'outlet_id') String? outletId,
    @JsonKey(name: 'outlet_name') String? outletName,
    @JsonKey(name: 'date_from') DateTime? dateFrom,
    @JsonKey(name: 'date_to') DateTime? dateTo,
    @JsonKey(name: 'group_by') String? groupBy,
    @JsonKey(name: 'summary') PurchasingAnalyticSummaryDto? summary,
    @JsonKey(name: 'data') List<PurchasingAnalyticDataDto>? data,
    @JsonKey(name: 'ingredient_data')
    List<PurchasingIngredientDataDto>? ingredientData,
    @JsonKey(name: 'vendor_data') List<PurchasingVendorDataDto>? vendorData,
  }) = _PurchasingAnalyticDto;

  factory PurchasingAnalyticDto.fromJson(Map<String, dynamic> json) =>
      _$PurchasingAnalyticDtoFromJson(json);

  PurchasingAnalytic toDomain() => PurchasingAnalytic(
    organizationId: organizationId ?? '',
    outletId: outletId ?? '',
    outletName: outletName ?? '',
    dateFrom: dateFrom ?? DateTime.fromMillisecondsSinceEpoch(0),
    dateTo: dateTo ?? DateTime.fromMillisecondsSinceEpoch(0),
    groupBy: groupBy ?? '',
    summary: summary?.toDomain() ?? PurchasingAnalyticSummary.empty(),
    data: data?.map((e) => e.toDomain()).toList() ?? [],
    ingredientData:
        ingredientData?.map((e) => e.toDomain()).toList() ?? [],
    vendorData: vendorData?.map((e) => e.toDomain()).toList() ?? [],
  );
}

@freezed
class PurchasingAnalyticSummaryDto with _$PurchasingAnalyticSummaryDto {
  const PurchasingAnalyticSummaryDto._();

  const factory PurchasingAnalyticSummaryDto({
    @JsonKey(name: 'total_purchases') num? totalPurchases,
    @JsonKey(name: 'raw_material_purchases') num? rawMaterialPurchases,
    @JsonKey(name: 'expense_purchases') num? expensePurchases,
    @JsonKey(name: 'total_purchase_orders') num? totalPurchaseOrders,
    @JsonKey(name: 'raw_material_purchase_orders') num? rawMaterialPurchaseOrders,
    @JsonKey(name: 'expense_count') num? expenseCount,
    @JsonKey(name: 'total_quantity') num? totalQuantity,
    @JsonKey(name: 'average_purchase_order_value')
    num? averagePurchaseOrderValue,
    @JsonKey(name: 'total_ingredients') num? totalIngredients,
    @JsonKey(name: 'total_vendors') num? totalVendors,
  }) = _PurchasingAnalyticSummaryDto;

  factory PurchasingAnalyticSummaryDto.fromJson(Map<String, dynamic> json) =>
      _$PurchasingAnalyticSummaryDtoFromJson(json);

  PurchasingAnalyticSummary toDomain() => PurchasingAnalyticSummary(
    totalPurchases: totalPurchases?.toInt() ?? 0,
    rawMaterialPurchases: rawMaterialPurchases?.toInt() ?? 0,
    expensePurchases: expensePurchases?.toInt() ?? 0,
    totalPurchaseOrders: totalPurchaseOrders?.toInt() ?? 0,
    rawMaterialPurchaseOrders: rawMaterialPurchaseOrders?.toInt() ?? 0,
    expenseCount: expenseCount?.toInt() ?? 0,
    totalQuantity: totalQuantity?.toInt() ?? 0,
    averagePurchaseOrderValue:
        averagePurchaseOrderValue?.toDouble() ?? 0,
    totalIngredients: totalIngredients?.toInt() ?? 0,
    totalVendors: totalVendors?.toInt() ?? 0,
  );
}

@freezed
class PurchasingAnalyticDataDto with _$PurchasingAnalyticDataDto {
  const PurchasingAnalyticDataDto._();

  const factory PurchasingAnalyticDataDto({
    @JsonKey(name: 'date') DateTime? date,
    @JsonKey(name: 'purchases') num? purchases,
    @JsonKey(name: 'raw_material_purchases') num? rawMaterialPurchases,
    @JsonKey(name: 'expense_purchases') num? expensePurchases,
    @JsonKey(name: 'purchase_orders') num? purchaseOrders,
    @JsonKey(name: 'raw_material_purchase_orders') num? rawMaterialPurchaseOrders,
    @JsonKey(name: 'expense_count') num? expenseCount,
    @JsonKey(name: 'quantity') num? quantity,
    @JsonKey(name: 'ingredients') num? ingredients,
    @JsonKey(name: 'vendors') num? vendors,
  }) = _PurchasingAnalyticDataDto;

  factory PurchasingAnalyticDataDto.fromJson(Map<String, dynamic> json) =>
      _$PurchasingAnalyticDataDtoFromJson(json);

  PurchasingAnalyticData toDomain() => PurchasingAnalyticData(
    date: date ?? DateTime.fromMillisecondsSinceEpoch(0),
    purchases: purchases?.toInt() ?? 0,
    rawMaterialPurchases: rawMaterialPurchases?.toInt() ?? 0,
    expensePurchases: expensePurchases?.toInt() ?? 0,
    purchaseOrders: purchaseOrders?.toInt() ?? 0,
    rawMaterialPurchaseOrders: rawMaterialPurchaseOrders?.toInt() ?? 0,
    expenseCount: expenseCount?.toInt() ?? 0,
    quantity: quantity?.toInt() ?? 0,
    ingredients: ingredients?.toInt() ?? 0,
    vendors: vendors?.toInt() ?? 0,
  );
}

@freezed
class PurchasingIngredientDataDto with _$PurchasingIngredientDataDto {
  const PurchasingIngredientDataDto._();

  const factory PurchasingIngredientDataDto({
    @JsonKey(name: 'ingredient_id') String? ingredientId,
    @JsonKey(name: 'ingredient_name') String? ingredientName,
    @JsonKey(name: 'quantity') num? quantity,
    @JsonKey(name: 'total_cost') num? totalCost,
    @JsonKey(name: 'average_unit_cost') num? averageUnitCost,
    @JsonKey(name: 'purchase_order_count') num? purchaseOrderCount,
  }) = _PurchasingIngredientDataDto;

  factory PurchasingIngredientDataDto.fromJson(Map<String, dynamic> json) =>
      _$PurchasingIngredientDataDtoFromJson(json);

  PurchasingIngredientData toDomain() => PurchasingIngredientData(
    ingredientId: ingredientId ?? '',
    ingredientName: ingredientName ?? '',
    quantity: quantity?.toInt() ?? 0,
    totalCost: totalCost?.toInt() ?? 0,
    averageUnitCost: averageUnitCost?.toDouble() ?? 0,
    purchaseOrderCount: purchaseOrderCount?.toInt() ?? 0,
  );
}

@freezed
class PurchasingVendorDataDto with _$PurchasingVendorDataDto {
  const PurchasingVendorDataDto._();

  const factory PurchasingVendorDataDto({
    @JsonKey(name: 'vendor_id') String? vendorId,
    @JsonKey(name: 'vendor_name') String? vendorName,
    @JsonKey(name: 'total_cost') num? totalCost,
    @JsonKey(name: 'purchase_order_count') num? purchaseOrderCount,
    @JsonKey(name: 'ingredient_count') num? ingredientCount,
    @JsonKey(name: 'quantity') num? quantity,
  }) = _PurchasingVendorDataDto;

  factory PurchasingVendorDataDto.fromJson(Map<String, dynamic> json) =>
      _$PurchasingVendorDataDtoFromJson(json);

  PurchasingVendorData toDomain() => PurchasingVendorData(
    vendorId: vendorId ?? '',
    vendorName: vendorName ?? '',
    totalCost: totalCost?.toInt() ?? 0,
    purchaseOrderCount: purchaseOrderCount?.toInt() ?? 0,
    ingredientCount: ingredientCount?.toInt() ?? 0,
    quantity: quantity?.toInt() ?? 0,
  );
}
