/// 고객(Customer) 도메인 엔티티.
class Customer {
  Customer({
    this.id,
    required this.customerCode,
    required this.customerName,
    this.contactName,
    this.isPartner = false,
    this.isGeneral = true,
    this.email,
    this.mobileNo,
    this.zipcode,
    this.addressDetail,
    this.isActive = true,
    this.isDeleted = false,
    this.note,
    this.createdAt,
    this.updatedAt,
  });

  final int? id;
  final String customerCode;
  final String customerName;
  final String? contactName;
  final bool isPartner;
  final bool isGeneral;
  final String? email;
  final String? mobileNo;
  final CustomerZipcode? zipcode;
  final String? addressDetail;
  final bool isActive;
  final bool isDeleted;
  final String? note;
  final DateTime? createdAt;
  final DateTime? updatedAt;

  /// 선택한 속성만 변경한 새 인스턴스를 반환한다.
  Customer copyWith({
    int? id,
    String? customerCode,
    String? customerName,
    String? contactName,
    bool? isPartner,
    bool? isGeneral,
    String? email,
    String? mobileNo,
    CustomerZipcode? zipcode,
    String? addressDetail,
    bool? isActive,
    bool? isDeleted,
    String? note,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return Customer(
      id: id ?? this.id,
      customerCode: customerCode ?? this.customerCode,
      customerName: customerName ?? this.customerName,
      contactName: contactName ?? this.contactName,
      isPartner: isPartner ?? this.isPartner,
      isGeneral: isGeneral ?? this.isGeneral,
      email: email ?? this.email,
      mobileNo: mobileNo ?? this.mobileNo,
      zipcode: zipcode ?? this.zipcode,
      addressDetail: addressDetail ?? this.addressDetail,
      isActive: isActive ?? this.isActive,
      isDeleted: isDeleted ?? this.isDeleted,
      note: note ?? this.note,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }
}

/// 고객 주소의 우편번호/행정구역 정보를 표현한다.
class CustomerZipcode {
  CustomerZipcode({
    required this.zipcode,
    this.sido,
    this.sigungu,
    this.roadName,
  });

  final String zipcode;
  final String? sido;
  final String? sigungu;
  final String? roadName;
}

/// 고객 생성/수정 시 사용하는 입력 모델.
class CustomerInput {
  CustomerInput({
    required this.customerCode,
    required this.customerName,
    this.contactName,
    required this.isPartner,
    required this.isGeneral,
    this.email,
    this.mobileNo,
    this.zipcode,
    this.addressDetail,
    this.isActive = true,
    this.note,
  });

  final String customerCode;
  final String customerName;
  final String? contactName;
  final bool isPartner;
  final bool isGeneral;
  final String? email;
  final String? mobileNo;
  final String? zipcode;
  final String? addressDetail;
  final bool isActive;
  final String? note;

  /// API 요청 바디에 사용하기 위한 맵으로 직렬화한다.
  Map<String, dynamic> toPayload() {
    return {
      'customer_code': customerCode,
      'customer_name': customerName,
      'contact_name': contactName,
      'is_partner': isPartner,
      'is_general': isGeneral,
      'email': email,
      'mobile_no': mobileNo,
      'zipcode': zipcode,
      'address_detail': addressDetail,
      'is_active': isActive,
      'note': note,
    };
  }
}
