import 'package:json_annotation/json_annotation.dart';

import 'car.dart';

part 'tour.g.dart';

@JsonSerializable(fieldRename: FieldRename.snake)
class Article {
  final int id;
  final String title;
  final int quantity;
  final double pricePerQuantity;
  final double depositPricePerQuantity;
  final int quantityDelivered;
  final int quantityReturned;
  final int quantityToDeposit;
  final int? referenceTo;

  Article({
    required this.id,
    required this.title,
    required this.quantity,
    required this.pricePerQuantity,
    required this.depositPricePerQuantity,
    required this.quantityDelivered,
    required this.quantityReturned,
    required this.quantityToDeposit,
    this.referenceTo,
  });

  factory Article.fromJson(Map<String, dynamic> json) => _$ArticleFromJson(json);
  Map<String, dynamic> toJson() => _$ArticleToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Address {
  final String street;
  final String housingNumber;
  final String postalCode;
  final String city;
  final String? country;

  Address({
    required this.street,
    required this.housingNumber,
    required this.postalCode,
    required this.city,
    this.country,
  });

  factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
  Map<String, dynamic> toJson() => _$AddressToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Customer {
  final String name;
  final int id;
  final Address address;

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

  String get displayAddress => "${address.street} ${address.housingNumber}, ${address.postalCode} ${address.city}";

  factory Customer.fromJson(Map<String, dynamic> json) => _$CustomerFromJson(json);
  Map<String, dynamic> toJson() => _$CustomerToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Receipt {
  final List<Article> articles;
  final Customer customer;
  final double totalGrossPrice;
  final double totalNetPrice;

  Receipt({
    required this.articles,
    required this.customer,
    required this.totalGrossPrice,
    required this.totalNetPrice,
  });

  factory Receipt.fromJson(Map<String, dynamic> json) => _$ReceiptFromJson(json);
  Map<String, dynamic> toJson() => _$ReceiptToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Delivery {
  final Receipt receipt;
  final String informationForDriver;
  final DateTime desiredDeliveryTime;
  final DateTime? timeDelivered;

  Delivery({
    required this.receipt,
    required this.informationForDriver,
    required this.desiredDeliveryTime,
    required this.timeDelivered,
  });

  factory Delivery.fromJson(Map<String, dynamic> json) => _$DeliveryFromJson(json);
  Map<String, dynamic> toJson() => _$DeliveryToJson(this);
}

@JsonSerializable(fieldRename: FieldRename.snake)
class Tour {
  final Car car;
  final String date;
  final List<Delivery> deliveries;

  Tour({
    required this.car,
    required this.date,
    required this.deliveries,
  });

  int get amountDeliveries => deliveries.length;
  int get amountFinishedDeliveries => deliveries.where((delivery) => delivery.timeDelivered != null).length;
  int get amountDeliveriesLeft => amountDeliveries - amountFinishedDeliveries;
  double get progress => amountFinishedDeliveries / amountDeliveries;
  int get progressPercentage => (progress * 100).toInt();

  factory Tour.fromJson(Map<String, dynamic> json) => _$TourFromJson(json);
  Map<String, dynamic> toJson() => _$TourToJson(this);
}