part of '../analytic_dtos.dart';

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

  const factory ProfitLossAnalyticDto({
    @JsonKey(name: 'organization_id') String? organizationId,
    @JsonKey(name: 'outlet_id') String? outletId,
    @JsonKey(name: 'outlet_name') String? outletName,
    @JsonKey(name: 'date_from') String? dateFrom,
    @JsonKey(name: 'date_to') String? dateTo,
    @JsonKey(name: 'group_by') String? groupBy,
    @JsonKey(name: 'summary') ProfitLossSummaryDto? summary,
    @JsonKey(name: 'data') List<ProfitLossDailyDataDto>? data,
    @JsonKey(name: 'product_data') List<ProfitLossProductDataDto>? productData,
    @JsonKey(name: 'main_summary')
    List<ProfitLossMainSummaryItemDto>? mainSummary,
    @JsonKey(name: 'purchasing') ProfitLossPurchasingDto? purchasing,
    @JsonKey(name: 'operational_expenses')
    List<ProfitLossOperationalExpenseDto>? operationalExpenses,
    @JsonKey(name: 'operational_expenses_total') int? operationalExpensesTotal,
  }) = _ProfitLossAnalyticDto;

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

  ProfitLossAnalytic toDomain() => ProfitLossAnalytic(
    organizationId: organizationId ?? '',
    outletId: outletId ?? '',
    outletName: outletName ?? '',
    dateFrom: dateFrom ?? '',
    dateTo: dateTo ?? '',
    groupBy: groupBy ?? '',
    summary: summary?.toDomain() ?? ProfitLossSummary.empty(),
    data: (data ?? []).map((e) => e.toDomain()).toList(),
    productData: (productData ?? []).map((e) => e.toDomain()).toList(),
    mainSummary: (mainSummary ?? []).map((e) => e.toDomain()).toList(),
    purchasing: purchasing?.toDomain() ?? ProfitLossPurchasing.empty(),
    operationalExpenses: (operationalExpenses ?? [])
        .map((e) => e.toDomain())
        .toList(),
    operationalExpensesTotal: operationalExpensesTotal ?? 0,
  );
}

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

  const factory ProfitLossSummaryDto({
    @JsonKey(name: 'total_revenue') int? totalRevenue,
    @JsonKey(name: 'total_cost') int? totalCost,
    @JsonKey(name: 'gross_profit') int? grossProfit,
    @JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
    @JsonKey(name: 'total_tax') int? totalTax,
    @JsonKey(name: 'total_discount') int? totalDiscount,
    @JsonKey(name: 'net_profit') int? netProfit,
    @JsonKey(name: 'net_profit_margin') double? netProfitMargin,
    @JsonKey(name: 'total_orders') int? totalOrders,
    @JsonKey(name: 'average_profit') double? averageProfit,
    @JsonKey(name: 'profitability_ratio') double? profitabilityRatio,
  }) = _ProfitLossSummaryDto;

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

  ProfitLossSummary toDomain() => ProfitLossSummary(
    totalRevenue: totalRevenue ?? 0,
    totalCost: totalCost ?? 0,
    grossProfit: grossProfit ?? 0,
    grossProfitMargin: grossProfitMargin ?? 0.0,
    totalTax: totalTax ?? 0,
    totalDiscount: totalDiscount ?? 0,
    netProfit: netProfit ?? 0,
    netProfitMargin: netProfitMargin ?? 0.0,
    totalOrders: totalOrders ?? 0,
    averageProfit: averageProfit ?? 0.0,
    profitabilityRatio: profitabilityRatio ?? 0.0,
  );
}

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

  const factory ProfitLossDailyDataDto({
    @JsonKey(name: 'date') String? date,
    @JsonKey(name: 'revenue') int? revenue,
    @JsonKey(name: 'cost') int? cost,
    @JsonKey(name: 'gross_profit') int? grossProfit,
    @JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
    @JsonKey(name: 'tax') int? tax,
    @JsonKey(name: 'discount') int? discount,
    @JsonKey(name: 'net_profit') int? netProfit,
    @JsonKey(name: 'net_profit_margin') double? netProfitMargin,
    @JsonKey(name: 'orders') int? orders,
  }) = _ProfitLossDailyDataDto;

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

  ProfitLossDailyData toDomain() => ProfitLossDailyData(
    date: date ?? '',
    revenue: revenue ?? 0,
    cost: cost ?? 0,
    grossProfit: grossProfit ?? 0,
    grossProfitMargin: grossProfitMargin ?? 0.0,
    tax: tax ?? 0,
    discount: discount ?? 0,
    netProfit: netProfit ?? 0,
    netProfitMargin: netProfitMargin ?? 0.0,
    orders: orders ?? 0,
  );
}

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

  const factory ProfitLossProductDataDto({
    @JsonKey(name: 'product_id') String? productId,
    @JsonKey(name: 'product_name') String? productName,
    @JsonKey(name: 'category_id') String? categoryId,
    @JsonKey(name: 'category_name') String? categoryName,
    @JsonKey(name: 'quantity_sold') int? quantitySold,
    @JsonKey(name: 'revenue') int? revenue,
    @JsonKey(name: 'cost') int? cost,
    @JsonKey(name: 'gross_profit') int? grossProfit,
    @JsonKey(name: 'gross_profit_margin') double? grossProfitMargin,
    @JsonKey(name: 'average_price') int? averagePrice,
    @JsonKey(name: 'average_cost') int? averageCost,
    @JsonKey(name: 'profit_per_unit') int? profitPerUnit,
  }) = _ProfitLossProductDataDto;

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

  ProfitLossProductData toDomain() => ProfitLossProductData(
    productId: productId ?? '',
    productName: productName ?? '',
    categoryId: categoryId ?? '',
    categoryName: categoryName ?? '',
    quantitySold: quantitySold ?? 0,
    revenue: revenue ?? 0,
    cost: cost ?? 0,
    grossProfit: grossProfit ?? 0,
    grossProfitMargin: grossProfitMargin ?? 0.0,
    averagePrice: averagePrice ?? 0,
    averageCost: averageCost ?? 0,
    profitPerUnit: profitPerUnit ?? 0,
  );
}

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

  const factory ProfitLossMainSummaryItemDto({
    @JsonKey(name: 'id') String? id,
    @JsonKey(name: 'label') String? label,
    @JsonKey(name: 'is_bold') bool? isBold,
    @JsonKey(name: 'today_nominal') int? todayNominal,
    @JsonKey(name: 'today_pct') double? todayPct,
    @JsonKey(name: 'mtd_nominal') int? mtdNominal,
    @JsonKey(name: 'mtd_pct') double? mtdPct,
    @JsonKey(name: 'sub_items') List<ProfitLossMainSummaryItemDto>? subItems,
  }) = _ProfitLossMainSummaryItemDto;

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

  ProfitLossMainSummaryItem toDomain() => ProfitLossMainSummaryItem(
    id: id ?? '',
    label: label ?? '',
    isBold: isBold ?? false,
    todayNominal: todayNominal ?? 0,
    todayPct: todayPct ?? 0.0,
    mtdNominal: mtdNominal ?? 0,
    mtdPct: mtdPct ?? 0.0,
    subItems: (subItems ?? []).map((e) => e.toDomain()).toList(),
  );
}

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

  const factory ProfitLossPurchasingDto({
    @JsonKey(name: 'today_total') int? todayTotal,
    @JsonKey(name: 'mtd_total') int? mtdTotal,
    @JsonKey(name: 'today_raw_material') int? todayRawMaterial,
    @JsonKey(name: 'mtd_raw_material') int? mtdRawMaterial,
    @JsonKey(name: 'today_expense') int? todayExpense,
    @JsonKey(name: 'mtd_expense') int? mtdExpense,
    @JsonKey(name: 'items') List<ProfitLossPurchasingItemDto>? items,
  }) = _ProfitLossPurchasingDto;

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

  ProfitLossPurchasing toDomain() => ProfitLossPurchasing(
    todayTotal: todayTotal ?? 0,
    mtdTotal: mtdTotal ?? 0,
    todayRawMaterial: todayRawMaterial ?? 0,
    mtdRawMaterial: mtdRawMaterial ?? 0,
    todayExpense: todayExpense ?? 0,
    mtdExpense: mtdExpense ?? 0,
    items: (items ?? []).map((e) => e.toDomain()).toList(),
  );
}

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

  const factory ProfitLossPurchasingItemDto({
    @JsonKey(name: 'date') String? date,
    @JsonKey(name: 'item') String? item,
    @JsonKey(name: 'quantity') int? quantity,
    @JsonKey(name: 'nominal') int? nominal,
  }) = _ProfitLossPurchasingItemDto;

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

  ProfitLossPurchasingItem toDomain() => ProfitLossPurchasingItem(
    date: date ?? '',
    item: item ?? '',
    quantity: quantity ?? 0,
    nominal: nominal ?? 0,
  );
}

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

  const factory ProfitLossOperationalExpenseDto({
    @JsonKey(name: 'item') String? item,
    @JsonKey(name: 'nominal') int? nominal,
  }) = _ProfitLossOperationalExpenseDto;

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

  ProfitLossOperationalExpense toDomain() =>
      ProfitLossOperationalExpense(item: item ?? '', nominal: nominal ?? 0);
}
