import 'package:garage/car/model/service_comment.dart';
import 'package:garage/car/model/tyre_type.dart';
import 'package:garage/utils/jsonable.dart';
import 'package:json_annotation/json_annotation.dart';

import '../../insurance/model/insurance.dart';

part 'car.g.dart';

// dart run build_runner build

@JsonSerializable(explicitToJson: true)
class Car implements Jsonable, Comparable<Car> {
  @override
  final String? id;
  final String spz;
  final String brand;
  final String name;
  final String model;
  final TyreType tyreType;
  final DateTime? tollExpiration;
  final List<DateTime> stkExpirations;
  final List<Insurance> insurances;
  final List<ServiceComment> serviceBook;

  Car({
    required this.id,
    required this.spz,
    required this.brand,
    required this.name,
    required this.model,
    required this.tyreType,
    required this.tollExpiration,
    required this.stkExpirations,
    required this.insurances,
    required this.serviceBook,
  });

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

  @override
  Map<String, dynamic> toJson() => _$CarToJson(this);

  Car copyWithNewSTK(DateTime expSTK) {
    stkExpirations.add(expSTK);
    return Car(
      id: id,
      spz: spz,
      brand: brand,
      name: name,
      model: model,
      tyreType: tyreType,
      tollExpiration: tollExpiration,
      stkExpirations: stkExpirations,
      insurances: insurances,
      serviceBook: serviceBook,
    );
  }

  Car copyAndAddInsurance(Insurance insurance) {
    insurances.add(insurance);
    return Car(
      id: id,
      spz: spz,
      brand: brand,
      name: name,
      model: model,
      tyreType: tyreType,
      tollExpiration: tollExpiration,
      stkExpirations: stkExpirations,
      insurances: insurances,
      serviceBook: serviceBook,
    );
  }

  @override
  set id(String? id) {}

  @override
  int compareTo(Car other) {
    return getCurrentSTK()!.compareTo(other.getCurrentSTK()!);
  }

  @override
  String toString() {
    return "Car: $spz and ${getCurrentInsurance().toString()}";
  }

  Insurance? getCurrentInsurance() {
    return insurances.lastOrNull;
  }

  DateTime? getCurrentSTK() {
    return stkExpirations.lastOrNull;
  }
}
