part of '../analytic_dtos.dart';

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

  const factory ProfitSharingDto({
    @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: 'data') List<ProfitSharingCategoryDto>? data,
    @JsonKey(name: 'budget') ProfitSharingBudgetDto? budget,
  }) = _ProfitSharingDto;

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

  ProfitSharing toDomain() => ProfitSharing(
    organizationId: organizationId ?? '',
    outletId: outletId ?? '',
    outletName: outletName ?? '',
    dateFrom: dateFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    dateTo: dateTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    categories: data?.map((e) => e.toDomain()).toList() ?? [],
    budget: budget?.toDomain() ?? ProfitSharingBudget.empty(),
  );
}

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

  const factory ProfitSharingCategoryDto({
    @JsonKey(name: 'parent_category_id') String? parentCategoryId,
    @JsonKey(name: 'parent_category_name') String? parentCategoryName,
    @JsonKey(name: 'total_revenue') num? totalRevenue,
    @JsonKey(name: 'total_quantity') num? totalQuantity,
    @JsonKey(name: 'category_count') num? categoryCount,
    @JsonKey(name: 'product_count') num? productCount,
    @JsonKey(name: 'order_count') num? orderCount,
    @JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
    @JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
    @JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
  }) = _ProfitSharingCategoryDto;

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

  ProfitSharingCategory toDomain() => ProfitSharingCategory(
    parentCategoryId: parentCategoryId ?? '',
    parentCategoryName: parentCategoryName ?? '',
    totalRevenue: totalRevenue?.toInt() ?? 0,
    totalQuantity: totalQuantity?.toInt() ?? 0,
    categoryCount: categoryCount?.toInt() ?? 0,
    productCount: productCount?.toInt() ?? 0,
    orderCount: orderCount?.toInt() ?? 0,
    totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
    totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
    totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
  );
}

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

  const factory ProfitSharingBudgetDto({
    @JsonKey(name: 'percentages') ProfitSharingPercentageDto? percentages,
    @JsonKey(name: 'cut_off_from') DateTime? cutOffFrom,
    @JsonKey(name: 'cut_off_to') DateTime? cutOffTo,
    @JsonKey(name: 'total') ProfitSharingPeriodDto? total,
    @JsonKey(name: 'weekly') List<ProfitSharingPeriodDto>? weekly,
    @JsonKey(name: 'monthly') List<ProfitSharingPeriodDto>? monthly,
  }) = _ProfitSharingBudgetDto;

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

  ProfitSharingBudget toDomain() => ProfitSharingBudget(
    percentages: percentages?.toDomain() ?? ProfitSharingPercentage.empty(),
    cutOffFrom: cutOffFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    cutOffTo: cutOffTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    total: total?.toDomain() ?? ProfitSharingPeriod.empty(),
    weekly: weekly?.map((e) => e.toDomain()).toList() ?? [],
    monthly: monthly?.map((e) => e.toDomain()).toList() ?? [],
  );
}

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

  const factory ProfitSharingPercentageDto({
    @JsonKey(name: 'purchase') num? purchase,
    @JsonKey(name: 'owner') num? owner,
    @JsonKey(name: 'team') num? team,
  }) = _ProfitSharingPercentageDto;

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

  ProfitSharingPercentage toDomain() => ProfitSharingPercentage(
    purchase: purchase?.toDouble() ?? 0,
    owner: owner?.toDouble() ?? 0,
    team: team?.toDouble() ?? 0,
  );
}

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

  const factory ProfitSharingPeriodDto({
    @JsonKey(name: 'period_start') DateTime? periodStart,
    @JsonKey(name: 'period_end') DateTime? periodEnd,
    @JsonKey(name: 'revenue') num? revenue,
    @JsonKey(name: 'order_count') num? orderCount,
    @JsonKey(name: 'limit_purchase') num? limitPurchase,
    @JsonKey(name: 'limit_owner') num? limitOwner,
    @JsonKey(name: 'limit_team') num? limitTeam,
    @JsonKey(name: 'month') String? month,
    @JsonKey(name: 'week_count') num? weekCount,
  }) = _ProfitSharingPeriodDto;

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

  ProfitSharingPeriod toDomain() => ProfitSharingPeriod(
    periodStart:
        periodStart?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    periodEnd: periodEnd?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    revenue: revenue?.toInt() ?? 0,
    orderCount: orderCount?.toInt() ?? 0,
    limitPurchase: limitPurchase?.toInt() ?? 0,
    limitOwner: limitOwner?.toInt() ?? 0,
    limitTeam: limitTeam?.toInt() ?? 0,
    month: month ?? '',
    weekCount: weekCount?.toInt() ?? 0,
  );
}

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

  const factory ProfitSharingDetailDto({
    @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: 'parent_category_id') String? parentCategoryId,
    @JsonKey(name: 'parent_category_name') String? parentCategoryName,
    @JsonKey(name: 'summary') ProfitSharingSummaryDto? summary,
    @JsonKey(name: 'categories') List<ProfitSharingSubCategoryDto>? categories,
    @JsonKey(name: 'budget') ProfitSharingBudgetDto? budget,
  }) = _ProfitSharingDetailDto;

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

  ProfitSharingDetail toDomain() => ProfitSharingDetail(
    organizationId: organizationId ?? '',
    outletId: outletId ?? '',
    outletName: outletName ?? '',
    dateFrom: dateFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    dateTo: dateTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
    parentCategoryId: parentCategoryId ?? '',
    parentCategoryName: parentCategoryName ?? '',
    summary:
        summary?.toDomain(
          parentCategoryId: parentCategoryId ?? '',
          parentCategoryName: parentCategoryName ?? '',
        ) ??
        ProfitSharingCategory.empty(),
    categories: categories?.map((e) => e.toDomain()).toList() ?? [],
    budget: budget?.toDomain() ?? ProfitSharingBudget.empty(),
  );
}

/// Ringkasan kategori induk pada endpoint detail — bentuknya sama dengan item
/// pada endpoint daftar, hanya saja id & nama kategori ada di level atas.
@freezed
class ProfitSharingSummaryDto with _$ProfitSharingSummaryDto {
  const ProfitSharingSummaryDto._();

  const factory ProfitSharingSummaryDto({
    @JsonKey(name: 'total_revenue') num? totalRevenue,
    @JsonKey(name: 'total_quantity') num? totalQuantity,
    @JsonKey(name: 'category_count') num? categoryCount,
    @JsonKey(name: 'product_count') num? productCount,
    @JsonKey(name: 'order_count') num? orderCount,
    @JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
    @JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
    @JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
  }) = _ProfitSharingSummaryDto;

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

  ProfitSharingCategory toDomain({
    required String parentCategoryId,
    required String parentCategoryName,
  }) => ProfitSharingCategory(
    parentCategoryId: parentCategoryId,
    parentCategoryName: parentCategoryName,
    totalRevenue: totalRevenue?.toInt() ?? 0,
    totalQuantity: totalQuantity?.toInt() ?? 0,
    categoryCount: categoryCount?.toInt() ?? 0,
    productCount: productCount?.toInt() ?? 0,
    orderCount: orderCount?.toInt() ?? 0,
    totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
    totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
    totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
  );
}

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

  const factory ProfitSharingSubCategoryDto({
    @JsonKey(name: 'category_id') String? categoryId,
    @JsonKey(name: 'category_name') String? categoryName,
    @JsonKey(name: 'total_revenue') num? totalRevenue,
    @JsonKey(name: 'total_quantity') num? totalQuantity,
    @JsonKey(name: 'product_count') num? productCount,
    @JsonKey(name: 'order_count') num? orderCount,
    @JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
    @JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
    @JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
    @JsonKey(name: 'products') List<ProfitSharingProductDto>? products,
  }) = _ProfitSharingSubCategoryDto;

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

  ProfitSharingSubCategory toDomain() => ProfitSharingSubCategory(
    categoryId: categoryId ?? '',
    categoryName: categoryName ?? '',
    totalRevenue: totalRevenue?.toInt() ?? 0,
    totalQuantity: totalQuantity?.toInt() ?? 0,
    productCount: productCount?.toInt() ?? 0,
    orderCount: orderCount?.toInt() ?? 0,
    totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
    totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
    totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
    products: products?.map((e) => e.toDomain()).toList() ?? [],
  );
}

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

  const factory ProfitSharingProductDto({
    @JsonKey(name: 'product_id') String? productId,
    @JsonKey(name: 'product_name') String? productName,
    @JsonKey(name: 'product_sku') String? productSku,
    @JsonKey(name: 'product_price') num? productPrice,
    @JsonKey(name: 'quantity_sold') num? quantitySold,
    @JsonKey(name: 'revenue') num? revenue,
    @JsonKey(name: 'average_price') num? averagePrice,
    @JsonKey(name: 'order_count') num? orderCount,
    @JsonKey(name: 'standard_hpp_per_unit') num? standardHppPerUnit,
    @JsonKey(name: 'standard_hpp_total') num? standardHppTotal,
    @JsonKey(name: 'fifo_hpp_per_unit') num? fifoHppPerUnit,
    @JsonKey(name: 'fifo_hpp_total') num? fifoHppTotal,
    @JsonKey(name: 'moving_average_hpp_per_unit') num? movingAverageHppPerUnit,
    @JsonKey(name: 'moving_average_hpp_total') num? movingAverageHppTotal,
  }) = _ProfitSharingProductDto;

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

  ProfitSharingProduct toDomain() => ProfitSharingProduct(
    productId: productId ?? '',
    productName: productName ?? '',
    productSku: productSku ?? '',
    productPrice: productPrice?.toInt() ?? 0,
    quantitySold: quantitySold?.toInt() ?? 0,
    revenue: revenue?.toInt() ?? 0,
    averagePrice: averagePrice?.toDouble() ?? 0,
    orderCount: orderCount?.toInt() ?? 0,
    standardHppPerUnit: standardHppPerUnit?.toDouble() ?? 0,
    standardHppTotal: standardHppTotal?.toInt() ?? 0,
    fifoHppPerUnit: fifoHppPerUnit?.toDouble() ?? 0,
    fifoHppTotal: fifoHppTotal?.toInt() ?? 0,
    movingAverageHppPerUnit: movingAverageHppPerUnit?.toDouble() ?? 0,
    movingAverageHppTotal: movingAverageHppTotal?.toInt() ?? 0,
  );
}
