import 'dart:convert';

/// Parse JSON to ProductResponse
ProductResponse productResponseFromJson(String str) =>
    ProductResponse.fromJson(json.decode(str));

String productResponseToJson(ProductResponse data) =>
    json.encode(data.toJson());

class ProductResponse {
  final int? code;
  final Data? data;
  final String? message;
  final bool? status;
  final List<Product>? details; // for variants API

  ProductResponse({
    this.code,
    this.data,
    this.message,
    this.status,
    this.details,
  });

  factory ProductResponse.fromJson(Map<String, dynamic> json) =>
      ProductResponse(
        code: json["code"],
        data: json["data"] == null ? null : Data.fromJson(json["data"]),
        details: json["details"] != null
            ? List<Product>.from(
            json["details"]!.map((x) => Product.fromVariantJson(x)))
            : null,
        message: json["message"],
        status: json["status"],
      );

  Map<String, dynamic> toJson() => {
    "code": code,
    "data": data?.toJson(),
    "details": details == null
        ? null
        : List<dynamic>.from(details!.map((x) => x.toJson())),
    "message": message,
    "status": status,
  };
}

/// Data class for main product API
class Data {
  final String? address;
  final String? city;
  final List<Detail>? details;
  final String? licenseno;
  final String? locationname;
  final String? pickuplat;
  final int? pickuplocationid;
  final String? pickuplong;
  final String? postcode;
  final String? primarycontact;
  final String? primaryemail;
  final String? suburb;
  final String? tenantname;

  Data({
    this.address,
    this.city,
    this.details,
    this.licenseno,
    this.locationname,
    this.pickuplat,
    this.pickuplocationid,
    this.pickuplong,
    this.postcode,
    this.primarycontact,
    this.primaryemail,
    this.suburb,
    this.tenantname,
  });

  factory Data.fromJson(Map<String, dynamic> json) => Data(
    address: json["address"],
    city: json["city"],
    details: json["details"] == null
        ? []
        : List<Detail>.from(
        json["details"]!.map((x) => Detail.fromJson(x))),
    licenseno: json["licenseno"],
    locationname: json["locationname"],
    pickuplat: json["pickuplat"],
    pickuplocationid: json["pickuplocationid"],
    pickuplong: json["pickuplong"],
    postcode: json["postcode"],
    primarycontact: json["primarycontact"],
    primaryemail: json["primaryemail"],
    suburb: json["suburb"],
    tenantname: json["tenantname"],
  );



  Map<String, dynamic> toJson() => {
    "address": address,
    "city": city,
    "details": details == null
        ? []
        : List<dynamic>.from(details!.map((x) => x.toJson())),
    "licenseno": licenseno,
    "locationname": locationname,
    "pickuplat": pickuplat,
    "pickuplocationid": pickuplocationid,
    "pickuplong": pickuplong,
    "postcode": postcode,
    "primarycontact": primarycontact,
    "primaryemail": primaryemail,
    "suburb": suburb,
    "tenantname": tenantname,
  };
}

/// Detail class for subcategories
class Detail {
  final int? subcategoryid;
  final String? subcategoryname;
  final String? image;
  final List<Product>? products;

  Detail({
    this.subcategoryid,
    this.subcategoryname,
    this.image,
    this.products,
  });

  factory Detail.fromJson(Map<String, dynamic> json) => Detail(
    subcategoryid: json["subcategoryid"],
    subcategoryname: json["subcategoryname"],
    image: json["image"],
    products: json["products"] == null
        ? []
        : List<Product>.from(
        json["products"]!.map((x) => Product.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "subcategoryid": subcategoryid,
    "subcategoryname": subcategoryname,
    "image": image,
    "products": products == null
        ? []
        : List<dynamic>.from(products!.map((x) => x.toJson())),
  };
}

/// Product class for both main products and variants
class Product {
  final int? productid;
  final int? applocationid;
  final int? productlocationid;
  final int? tenantid;
  final int? categoryid;
  final String? categoryname;
  final int? subcategoryid;
  final String? subcategoryname;
  final String? productname;
  final String? productimage;
  final String? productdesc;
  final Productunit? productunit;
  final String? unitvalue;
  final double? productcost;
  final double? discount;
  final double? taxamount;
  final int? taxpercent;
  final int? producttax;
  final int? productstock;
  final int? productcombo;
  final int? variants;
  final int? quantity;
  final int? approve;
  final Productstatus? productstatus;

  Product({
    this.productid,
    this.applocationid,
    this.productlocationid,
    this.tenantid,
    this.categoryid,
    this.categoryname,
    this.subcategoryid,
    this.subcategoryname,
    this.productname,
    this.productimage,
    this.productdesc,
    this.productunit,
    this.unitvalue,
    this.productcost,
    this.discount,
    this.taxamount,
    this.taxpercent,
    this.producttax,
    this.productstock,
    this.productcombo,
    this.variants,
    this.quantity,
    this.approve,
    this.productstatus,
  });

  /// Factory for main product API
  factory Product.fromJson(Map<String, dynamic> json) => Product(
    productid: json["productid"],
    applocationid: json["applocationid"],
    productlocationid: json["productlocationid"],
    tenantid: json["tenantid"],
    categoryid: json["categoryid"],
    categoryname: json["categoryname"],
    subcategoryid: json["subcategoryid"],
    subcategoryname: json["Subcategoryname"],
    productname: json["productname"],
    productimage: json["productimage"],
    productdesc: json["productdesc"],
    productunit: productunitValues.map[json["productunit"]] ?? Productunit.KG,
    unitvalue: json["unitvalue"],
    productcost: (json["productcost"] ?? 0).toDouble(),
    discount: (json["discountvalue"] ?? 0).toDouble(),
    taxamount: (json["taxamount"] ?? 0).toDouble(),
    taxpercent: json["taxpercent"],
    producttax: json["producttax"],
    productstock: json["productstock"],
    productcombo: json["productcombo"],
    variants: json["variants"],
    quantity: json["quantity"],
    approve: json["approve"],
    productstatus: productstatusValues.map[json["productstatus"]] ?? Productstatus.AVAILABLE,
  );

  /// Factory for variants API (flat structure)
  factory Product.fromVariantJson(Map<String, dynamic> json) => Product(
    productid: json["productid"],
    applocationid: json["applocationid"],
    productlocationid: json["productlocationid"],
    tenantid: json["tenantid"],
    categoryid: json["categoryid"],
    categoryname: json["categoryname"],
    subcategoryid: json["subcategoryid"] ?? 0,
    subcategoryname: json["Subcategoryname"] ?? "",
    productname: json["productname"],
    productimage: json["productimage"],
    productdesc: json["productdesc"].toString(),
    productunit: productunitValues.map[json["productunit"]] ?? Productunit.KG,
    unitvalue: json["unitvalue"] ?? "",
    productcost: (json["productcost"] ?? 0).toDouble(),
    discount: (json["discountvalue"] ?? 0).toDouble(),
    taxamount: (json["producttax"] ?? 0).toDouble(),
    taxpercent: json["taxpercent"] ?? 0,
    producttax: json["producttax"] ?? 0,
    productstock: json["productstock"] ?? 0,
    productcombo: json["productcombo"] ?? 0,
    variants: json["variants"] ?? 0,
    quantity: json["quantity"] ?? 0,
    approve: json["approve"] ?? 0,
    productstatus: productstatusValues.map[json["productstatus"]] ?? Productstatus.AVAILABLE,
  );

  Map<String, dynamic> toJson() => {
    "productid": productid,
    "applocationid": applocationid,
    "productlocationid": productlocationid,
    "tenantid": tenantid,
    "categoryid": categoryid,
    "categoryname": categoryname,
    "subcategoryid": subcategoryid,
    "Subcategoryname": subcategoryname,
    "productname": productname,
    "productimage": productimage,
    "productdesc": productdesc,
    "productunit": productunitValues.reverse[productunit],
    "unitvalue": unitvalue,
    "productcost": productcost,
    "discount": discount,
    "taxamount": taxamount,
    "taxpercent": taxpercent,
    "producttax": producttax,
    "productstock": productstock,
    "productcombo": productcombo,
    "variants": variants,
    "quantity": quantity,
    "approve": approve,
    "productstatus": productstatusValues.reverse[productstatus],
  };





  /// Convert a JSON list into List<Product>
  static List<Product> fromJsonList(List<dynamic> list) {
    return list.map((e) => Product.fromJson(e)).toList();
  }

  /// Convert a JSON list for variants into List<Product>
  static List<Product> fromVariantJsonList(List<dynamic> list) {
    return list.map((e) => Product.fromVariantJson(e)).toList();
  }
}




enum Productstatus { ACTIVE, AVAILABLE, OUTOFSTOCK }
final productstatusValues = EnumValues({
  "Active": Productstatus.ACTIVE,
  "available": Productstatus.AVAILABLE,
  "outofstock": Productstatus.OUTOFSTOCK
});

enum Productunit { BOX, KG, LTR, PCS }

final productunitValues = EnumValues({
  "box": Productunit.BOX,
  "kg": Productunit.KG,
  "ltr": Productunit.LTR,
  "pcs": Productunit.PCS,
});

/// Enum helper class
class EnumValues<T> {
  Map<String, T> map;
  late Map<T, String> reverseMap;

  EnumValues(this.map);

  Map<T, String> get reverse {
    reverseMap = map.map((k, v) => MapEntry(v, k));
    return reverseMap;
  }
}
