class ProductModel {
  late int id;
  late String type;
  late String name;
  String? urlKey;
  late String formattedPrice;
  String? shortDescription;
  String? description;
  String? optionValue;
  late List<ProductImage> images;
  late List<ProductAttribute> attributes;
  late bool inStock;
  bool? isSaved;
  late bool isWishlisted;
  bool? isItemInCart;
  bool? showQuantityChanger;
  late double price;
  String? formattedSpecialPrice;
  String? formattedRegularPrice;
  bool hasDiscount = false;
  String? discountRate;
  late Reviews reviews;
  List<ProductVariation>? variations;

  ProductModel({
    required this.id,
    required this.type,
    required this.name,
    required this.price,
    required this.formattedPrice,
    this.shortDescription,
    this.description,
    this.optionValue,
    required this.images,
    required this.inStock,
    this.isSaved,
    required this.isWishlisted,
    this.isItemInCart,
    this.showQuantityChanger,
    this.formattedRegularPrice,
    this.formattedSpecialPrice,
    this.hasDiscount = false,
    this.discountRate,
  });

  ProductModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    type = json['type'] ?? 'simple';
    name = json['name'] ?? '';
    price = json['price'] + .0 ?? 0.0;
    formattedPrice = json['formatted_price'] ?? '';
    shortDescription = json['short_description'];
    description = json['description'];
    optionValue = json['option_value'];
    reviews = Reviews.fromJson(json['reviews']);

    if (json['images'] != null) {
      images = [];
      json['images'].forEach((v) {
        images.add(new ProductImage.fromJson(v));
      });
    } else {
      images = [];
    }

    if (json['attributes'] != null) {
      attributes = [];
      json['attributes'].forEach((v) {
        attributes.add(new ProductAttribute.fromJson(v));
      });
    } else {
      attributes = [];
    }

    inStock = json['in_stock'];
    isSaved = json['is_saved'];
    isWishlisted = json['is_wishlisted'] ?? false;
    isItemInCart = json['is_item_in_cart'];
    showQuantityChanger = json['show_quantity_changer'];

    hasDiscount = false;
    if (json['formatted_special_price'] != null && json['formatted_regular_price'] != null) {
      this.hasDiscount = true;

      this.formattedSpecialPrice = json['formatted_special_price'];
      this.formattedRegularPrice = json['formatted_regular_price'];

      final double regularPrice = json['regular_price'].toDouble();
      final double specialPrice = json['special_price'].toDouble();

      double discountRt = (100 * (regularPrice - specialPrice)) / regularPrice;
      this.discountRate = discountRt.toStringAsFixed(2) + '%';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['url_key'] = this.urlKey;
    data['price'] = this.price;
    data['formatted_price'] = this.formattedPrice;
    data['short_description'] = this.shortDescription;
    data['description'] = this.description;
    data['option_value'] = this.optionValue;
    data['in_stock'] = this.inStock;
    data['is_item_in_cart'] = this.isItemInCart;
    data['images'] = this.images.map((v) => v.toJson()).toList();
    data['attributes'] = this.attributes.map((v) => v.toJson()).toList();
    return data;
  }

  static List<ProductModel> listFromJson(list) => List<ProductModel>.from(list.map((x) => ProductModel.fromJson(x)));
}

class ProductAttribute {
  late String code;
  late int value;
  late String name;
  late String label;

  ProductAttribute({
    required this.code,
    required this.value,
    required this.name,
    required this.label,
  });

  ProductAttribute.fromJson(Map<String, dynamic> json) {
    code = json['code'];
    value = json['value'];
    name = json['name'];
    label = json['label'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['code'] = this.code;
    data['value'] = this.value;
    data['name'] = this.name;
    data['label'] = this.label;
    return data;
  }
}

class ProductImage {
  late String originalImageUrl;

  ProductImage({
    required this.originalImageUrl,
  });

  ProductImage.fromJson(Map<String, dynamic> json) {
    originalImageUrl = json['original_image_url'] ?? json['url'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['original_image_url'] = this.originalImageUrl;
    return data;
  }
}

class ProductVariation {
  late int id;
  late String colorLabel;
  late String sizeLabel;
  late String formattedPrice;
  String? formattedSpecialPrice;
  String? formattedRegularPrice;
  late List<ProductImage> images;

  ProductVariation({
    required this.id,
    required this.colorLabel,
    required this.sizeLabel,
    required this.formattedPrice,
    required this.formattedSpecialPrice,
    required this.formattedRegularPrice,
    required this.images,
  });
}

class ProductAdditionalInfoModel {
  late int id;
  late String code;
  late String label;
  late String value;
  late String adminName;
  late String type;

  ProductAdditionalInfoModel({
    required this.id,
    required this.code,
    required this.label,
    required this.value,
    required this.adminName,
    required this.type,
  });

  ProductAdditionalInfoModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    code = json['code'].toString();
    label = json['label'].toString();
    value = json['value'].toString();
    adminName = json['admin_name'].toString();
    type = json['type'].toString();
  }
}

class Reviews {
  late int total;
  late String averageRating;

  Reviews({
    required this.total,
    required this.averageRating,
  });

  Reviews.fromJson(Map<String, dynamic> json) {
    total = json['total'];
    averageRating = json['average_rating'] ?? '0';
  }
}
