/// Address Model
///
/// Hive model for caching address data from ERPNext API.
library;

import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/features/account/domain/entities/address.dart';

part 'address_model.g.dart';

/// Address Model
///
/// Hive model for storing address data with ERPNext API compatibility.
@HiveType(typeId: HiveTypeIds.addressModel)
class AddressModel extends HiveObject {
  /// Address name (ID in ERPNext)
  @HiveField(0)
  String name;

  /// Display title for the address
  @HiveField(1)
  String addressTitle;

  /// Address line 1 (street, number, etc.)
  @HiveField(2)
  String addressLine1;

  /// Phone number
  @HiveField(3)
  String phone;

  /// Email address
  @HiveField(4)
  String? email;

  /// Fax number (optional)
  @HiveField(5)
  String? fax;

  /// Tax code/ID
  @HiveField(6)
  String? taxCode;

  /// City code (from ERPNext location master)
  @HiveField(7)
  String cityCode;

  /// Ward code (from ERPNext location master)
  @HiveField(8)
  String wardCode;

  /// Whether this is the default address
  @HiveField(9)
  bool isDefault;

  /// City name (for display)
  @HiveField(10)
  String? cityName;

  /// Ward name (for display)
  @HiveField(11)
  String? wardName;

  /// Whether editing this address is allowed
  @HiveField(12)
  bool isAllowEdit;

  AddressModel({
    required this.name,
    required this.addressTitle,
    required this.addressLine1,
    required this.phone,
    this.email,
    this.fax,
    this.taxCode,
    required this.cityCode,
    required this.wardCode,
    this.isDefault = false,
    this.cityName,
    this.wardName,
    this.isAllowEdit = true,
  });

  /// Create from JSON (API response)
  factory AddressModel.fromJson(Map<String, dynamic> json) {
    return AddressModel(
      name: json['name'] as String? ?? '',
      addressTitle: json['address_title'] as String? ?? '',
      addressLine1: json['address_line1'] as String? ?? '',
      phone: json['phone'] as String? ?? '',
      email: json['email'] as String?,
      fax: json['fax'] as String?,
      taxCode: json['tax_code'] as String?,
      cityCode: json['city_code'] as String? ?? '',
      wardCode: json['ward_code'] as String? ?? '',
      isDefault: json['is_default'] == 1 || json['is_default'] == true,
      cityName: json['city_name'] as String?,
      wardName: json['ward_name'] as String?,
      isAllowEdit: json['is_allow_edit'] == 1 || json['is_allow_edit'] == true,
    );
  }

  /// Convert to JSON (API request)
  Map<String, dynamic> toJson() {
    return {
      // If name is empty, send null to indicate new address creation
      'name': name.isEmpty ? null : name,
      'address_title': addressTitle,
      'address_line1': addressLine1,
      'phone': phone,
      if (email != null && email!.isNotEmpty) 'email': email,
      if (fax != null && fax!.isNotEmpty) 'fax': fax,
      if (taxCode != null && taxCode!.isNotEmpty) 'tax_code': taxCode,
      'city_code': cityCode,
      'ward_code': wardCode,
      'is_default': isDefault,
      if (cityName != null && cityName!.isNotEmpty) 'city_name': cityName,
      if (wardName != null && wardName!.isNotEmpty) 'ward_name': wardName,
      'is_allow_edit': isAllowEdit,
    };
  }

  /// Convert to domain entity
  Address toEntity() {
    return Address(
      name: name,
      addressTitle: addressTitle,
      addressLine1: addressLine1,
      phone: phone,
      email: email,
      fax: fax,
      taxCode: taxCode,
      cityCode: cityCode,
      wardCode: wardCode,
      isDefault: isDefault,
      cityName: cityName,
      wardName: wardName,
      isAllowEdit: isAllowEdit,
    );
  }

  /// Create from domain entity
  factory AddressModel.fromEntity(Address entity) {
    return AddressModel(
      name: entity.name,
      addressTitle: entity.addressTitle,
      addressLine1: entity.addressLine1,
      phone: entity.phone,
      email: entity.email,
      fax: entity.fax,
      taxCode: entity.taxCode,
      cityCode: entity.cityCode,
      wardCode: entity.wardCode,
      isDefault: entity.isDefault,
      cityName: entity.cityName,
      wardName: entity.wardName,
      isAllowEdit: entity.isAllowEdit,
    );
  }

  @override
  String toString() {
    return 'AddressModel(name: $name, addressTitle: $addressTitle, '
        'addressLine1: $addressLine1, phone: $phone, isDefault: $isDefault, '
        'isAllowEdit: $isAllowEdit)';
  }
}
