import 'package:hive/hive.dart';
import 'schema/display_data.dart';
import 'schema/hidden_specs.dart';
import 'schema/user_data.dart';
import 'schema/gamification.dart';
import 'schema/metadata.dart';
import 'schema/item_type.dart';

export 'schema/display_data.dart';
export 'schema/hidden_specs.dart';
export 'schema/user_data.dart';
export 'schema/gamification.dart';
export 'schema/metadata.dart';
export 'schema/item_type.dart';

part 'sake_item.g.dart';

@HiveType(typeId: 0)
class SakeItem extends HiveObject {
  // --- Root Identity ---
  @HiveField(0)
  final String id;

  // --- New Hierarchical Data (Fields 20+) ---
  @HiveField(20)
  DisplayData? _displayData;

  @HiveField(21)
  HiddenSpecs? _hiddenSpecs;

  @HiveField(22)
  UserData? _userData;

  @HiveField(23)
  Gamification? _gamification;

  @HiveField(24)
  Metadata? _metadata;

  @HiveField(25)
  ItemType? _itemType;

  // --- Draft Mode Fields (Fields 26-27) ---
  @HiveField(26)
  bool? _isPendingAnalysis;  // true = AI解析待ち, false/null = 通常登録済み

  @HiveField(27)
  String? _draftPhotoPath;  // 解析待ち写真の一時パス（Draft時のみ）

  // --- Legacy Fields (Deprecated: Kept for Migration) ---
  @HiveField(1)
  final String? legacyName;

  @HiveField(2)
  final String? legacyBrand;

  @HiveField(3)
  final String? legacyPrefecture;

  @HiveField(4)
  final String? legacyDescription;

  @HiveField(5)
  final String? legacyCatchCopy;

  @HiveField(6)
  final List<String>? legacyImagePaths;

  @HiveField(7)
  final double? legacySweetnessScore;

  @HiveField(8)
  final double? legacyBodyScore;

  @HiveField(9)
  final DateTime? legacyCreatedAt;

  @HiveField(10)
  final int? legacyConfidenceScore;

  @HiveField(11)
  final List<String>? legacyFlavorTags;

  @HiveField(12)
  final bool? legacyIsFavorite;

  @HiveField(13)
  final Map<String, int>? legacyTasteStats;

  @HiveField(14)
  final bool? legacyIsUserEdited;

  @HiveField(15)
  final int? legacyCostPrice;

  @HiveField(16)
  final int? legacyManualPrice;

  @HiveField(17)
  final double? legacyMarkup;

  @HiveField(18)
  final Map<String, int>? legacyPriceVariants;

  SakeItem({
    required this.id,
    DisplayData? displayData,
    HiddenSpecs? hiddenSpecs,
    UserData? userData,
    Gamification? gamification,
    Metadata? metadata,
    ItemType? itemType,
    // Draft Mode params
    bool? isPendingAnalysis,
    String? draftPhotoPath,
    // Legacy params for migration compatibility (optional)
    this.legacyName,
    this.legacyBrand,
    this.legacyPrefecture,
    this.legacyDescription,
    this.legacyCatchCopy,
    this.legacyImagePaths,
    this.legacySweetnessScore,
    this.legacyBodyScore,
    this.legacyCreatedAt,
    this.legacyConfidenceScore,
    this.legacyFlavorTags,
    this.legacyIsFavorite,
    this.legacyTasteStats,
    this.legacyIsUserEdited,
    this.legacyCostPrice,
    this.legacyManualPrice,
    this.legacyMarkup,
    this.legacyPriceVariants,
  }) {
    _displayData = displayData;
    _hiddenSpecs = hiddenSpecs;
    _userData = userData;
    _gamification = gamification;
    _metadata = metadata;
    _itemType = itemType;
    _isPendingAnalysis = isPendingAnalysis;
    _draftPhotoPath = draftPhotoPath;
  }

  // --- Smart Getters (Auto-Migration / Fallback) ---
  DisplayData get displayData {
    if (_displayData != null) return _displayData!;
    // Fallback: Construct from Legacy
    return DisplayData(
      name: legacyName ?? 'Unknown',
      brewery: legacyBrand ?? 'Unknown',
      prefecture: legacyPrefecture ?? 'Unknown',
      catchCopy: legacyCatchCopy,
      imagePaths: legacyImagePaths ?? [],
      rating: null, // Legacy didn't have rating explicit in display
    );
  }
  
  // Allow setting for UI updates
  set displayData(DisplayData val) {
    _displayData = val;
    save(); // Auto-save on set? Or just update memory. HiveObject usually requires save().
    // Better to just update memory here.
  }

  HiddenSpecs get hiddenSpecs {
    if (_hiddenSpecs != null) return _hiddenSpecs!;
    return HiddenSpecs(
      description: legacyDescription,
      tasteStats: legacyTasteStats ?? {},
      flavorTags: legacyFlavorTags ?? [],
      sweetnessScore: legacySweetnessScore,
      bodyScore: legacyBodyScore,
    );
  }

  // Allow setting for さけのわ auto-matching
  set hiddenSpecs(HiddenSpecs val) {
    _hiddenSpecs = val;
  }

  UserData get userData {
    if (_userData != null) return _userData!;
    return UserData(
      isFavorite: legacyIsFavorite ?? false,
      isUserEdited: legacyIsUserEdited ?? false,
      price: legacyManualPrice,
      costPrice: legacyCostPrice,
      markup: legacyMarkup ?? 3.0,
      priceVariants: legacyPriceVariants,
    );
  }

  Gamification get gamification {
    if (_gamification != null) return _gamification!;
    return Gamification(
      ponPoints: 0, // Legacy didn't track
    );
  }

  Metadata get metadata {
    if (_metadata != null) return _metadata!;
    return Metadata(
      createdAt: legacyCreatedAt ?? DateTime.now(),
      aiConfidence: legacyConfidenceScore,
    );
  }

  ItemType get itemType {
    // Default to 'sake' for existing data
    return _itemType ?? ItemType.sake;
  }

  set itemType(ItemType val) {
    _itemType = val;
  }

  // Draft Mode Getters/Setters
  bool get isPendingAnalysis => _isPendingAnalysis ?? false;

  set isPendingAnalysis(bool val) {
    _isPendingAnalysis = val;
  }

  // ignore: unnecessary_getters_setters
  String? get draftPhotoPath => _draftPhotoPath;

  set draftPhotoPath(String? val) {
    _draftPhotoPath = val;
  }

  // --- Migration Method ---
  // Returns true if migration was performed (i.e., was legacy)
  bool ensureMigrated() {
    if (_displayData != null) return false; // Already new structure

    // Create New Objects from Legacy Fields
    _displayData = displayData; // Uses getter logic
    _hiddenSpecs = hiddenSpecs;
    _userData = userData;
    _gamification = gamification;
    _metadata = metadata;

    return true;
  }

  // --- CopyWith for Immutable Updates (Backend Compatible) ---
  SakeItem copyWith({
    String? name,
    String? brand, // Maps to Brewery
    String? prefecture,
    String? description,
    String? catchCopy,
    List<String>? imagePaths,
    double? sweetnessScore,
    double? bodyScore,
    int? confidenceScore, // Maps to aiConfidence
    List<String>? flavorTags,
    bool? isFavorite,
    Map<String, int>? tasteStats,
    bool? isUserEdited,
    String? memo,
    int? costPrice,
    int? manualPrice, // Maps to price
    double? markup,
    Map<String, int>? priceVariants,
    ItemType? itemType,
    // New Specs
    String? specificDesignation, // Maps to hiddenSpecs.type
    double? alcoholContent,
    int? polishingRatio,
    double? sakeMeterValue,
    String? riceVariety,
    String? yeast,
    String? manufacturingYearMonth,
    // Draft Mode
    bool? isPendingAnalysis,
    String? draftPhotoPath,
  }) {
    // Ensure we have current data structures
    final currentDisplay = displayData;
    final currentHidden = hiddenSpecs;
    final currentUser = userData;
    final currentMeta = metadata;
    final currentGame = gamification;

    return SakeItem(
      id: id,
      displayData: currentDisplay.copyWith(
        name: name,
        brewery: brand,
        prefecture: prefecture,
        catchCopy: catchCopy,
        imagePaths: imagePaths,
      ),
      hiddenSpecs: currentHidden.copyWith(
        description: description,
        tasteStats: tasteStats,
        flavorTags: flavorTags,
        sweetnessScore: sweetnessScore,
        bodyScore: bodyScore,
        type: specificDesignation,
        alcoholContent: alcoholContent,
        polishingRatio: polishingRatio,
        sakeMeterValue: sakeMeterValue,
        riceVariety: riceVariety,
        yeast: yeast,
        manufacturingYearMonth: manufacturingYearMonth,
      ),
      userData: currentUser.copyWith(
        isFavorite: isFavorite,
        isUserEdited: isUserEdited,
        memo: memo,
        price: manualPrice,
        costPrice: costPrice,
        markup: markup,
        priceVariants: priceVariants,
      ),
      gamification: currentGame,
      metadata: currentMeta.copyWith(
        aiConfidence: confidenceScore,
      ),
      itemType: itemType ?? this.itemType,
      // Draft Mode
      isPendingAnalysis: isPendingAnalysis ?? this.isPendingAnalysis,
      draftPhotoPath: draftPhotoPath ?? this.draftPhotoPath,
    );
  }
  // Compact JSON for QR ecosystem
  String toQrJson() {
    return '{"id":"$id","n":"${displayData.displayName}","b":"${displayData.displayBrewery}","p":"${displayData.displayPrefecture}","s":${hiddenSpecs.sweetnessScore ?? 0},"y":${hiddenSpecs.bodyScore ?? 0},"a":${hiddenSpecs.alcoholContent ?? 0}}';
  }
}
