/// Data Model: Promotion
///
/// Data Transfer Object for promotion information.
/// This model handles serialization/deserialization for:
/// - JSON (API responses)
/// - Hive (local database)
///
/// Extends the domain entity and adds data layer functionality.
library;

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

part 'promotion_model.g.dart';

/// Promotion Model
///
/// Used for:
/// - API JSON serialization/deserialization
/// - Hive local database storage
/// - Converting to/from domain entity
///
/// Hive Type ID: 26 (from HiveTypeIds.promotionModel)
@HiveType(typeId: HiveTypeIds.promotionModel)
class PromotionModel extends HiveObject {
  /// Promotion ID
  @HiveField(0)
  final String id;

  /// Promotion title
  @HiveField(1)
  final String title;

  /// Description
  @HiveField(2)
  final String description;

  /// Image URL
  @HiveField(3)
  final String imageUrl;

  /// Start date (ISO8601 string)
  @HiveField(4)
  final String startDate;

  /// End date (ISO8601 string)
  @HiveField(5)
  final String endDate;

  /// Discount percentage (nullable)
  @HiveField(6)
  final int? discountPercentage;

  /// Discount amount (nullable)
  @HiveField(7)
  final double? discountAmount;

  /// Terms and conditions (nullable)
  @HiveField(8)
  final String? terms;

  /// Details URL (nullable)
  @HiveField(9)
  final String? detailsUrl;

  PromotionModel({
    required this.id,
    required this.title,
    required this.description,
    required this.imageUrl,
    required this.startDate,
    required this.endDate,
    this.discountPercentage,
    this.discountAmount,
    this.terms,
    this.detailsUrl,
  });

  /// From JSON constructor
  factory PromotionModel.fromJson(Map<String, dynamic> json) {
    return PromotionModel(
      id: json['id'] as String,
      title: json['title'] as String,
      description: json['description'] as String,
      imageUrl: json['imageUrl'] as String,
      startDate: json['startDate'] as String,
      endDate: json['endDate'] as String,
      discountPercentage: json['discountPercentage'] as int?,
      discountAmount: json['discountAmount'] as double?,
      terms: json['terms'] as String?,
      detailsUrl: json['detailsUrl'] as String?,
    );
  }

  /// To JSON method
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'description': description,
      'imageUrl': imageUrl,
      'startDate': startDate,
      'endDate': endDate,
      'discountPercentage': discountPercentage,
      'discountAmount': discountAmount,
      'terms': terms,
      'detailsUrl': detailsUrl,
    };
  }

  /// Convert to domain entity
  Promotion toEntity() {
    return Promotion(
      id: id,
      title: title,
      description: description,
      imageUrl: imageUrl,
      startDate: DateTime.parse(startDate),
      endDate: DateTime.parse(endDate),
      discountPercentage: discountPercentage,
      discountAmount: discountAmount,
      terms: terms,
      detailsUrl: detailsUrl,
    );
  }

  /// Create from domain entity
  factory PromotionModel.fromEntity(Promotion entity) {
    return PromotionModel(
      id: entity.id,
      title: entity.title,
      description: entity.description,
      imageUrl: entity.imageUrl,
      startDate: entity.startDate.toIso8601String(),
      endDate: entity.endDate.toIso8601String(),
      discountPercentage: entity.discountPercentage,
      discountAmount: entity.discountAmount,
      terms: entity.terms,
      detailsUrl: entity.detailsUrl,
    );
  }

  /// Copy with method for creating modified copies
  PromotionModel copyWith({
    String? id,
    String? title,
    String? description,
    String? imageUrl,
    String? startDate,
    String? endDate,
    int? discountPercentage,
    double? discountAmount,
    String? terms,
    String? detailsUrl,
  }) {
    return PromotionModel(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      imageUrl: imageUrl ?? this.imageUrl,
      startDate: startDate ?? this.startDate,
      endDate: endDate ?? this.endDate,
      discountPercentage: discountPercentage ?? this.discountPercentage,
      discountAmount: discountAmount ?? this.discountAmount,
      terms: terms ?? this.terms,
      detailsUrl: detailsUrl ?? this.detailsUrl,
    );
  }

  @override
  String toString() {
    return 'PromotionModel(id: $id, title: $title, startDate: $startDate, endDate: $endDate)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is PromotionModel &&
        other.id == id &&
        other.title == title &&
        other.description == description &&
        other.imageUrl == imageUrl &&
        other.startDate == startDate &&
        other.endDate == endDate &&
        other.discountPercentage == discountPercentage &&
        other.discountAmount == discountAmount &&
        other.terms == terms &&
        other.detailsUrl == detailsUrl;
  }

  @override
  int get hashCode {
    return Object.hash(
      id,
      title,
      description,
      imageUrl,
      startDate,
      endDate,
      discountPercentage,
      discountAmount,
      terms,
      detailsUrl,
    );
  }
}
