watch_theme_models.dart 7.39 KB
import 'dart:ui';

import '../widgets/watch_theme_colors.dart';

class WatchThemeItem {
  const WatchThemeItem({
    this.id,
    this.userId,
    this.status,
    required this.themeName,
    required this.energeticDescription,
    this.energeticImage,
    required this.normalDescription,
    this.normalImage,
    required this.slightStressfulDescription,
    this.slightStressfulImage,
    required this.stressfulDescription,
    this.stressfulImage,
    this.isOfficial = 0,
    this.isDefaultTheme = 0,
    this.officialThemeId,
    this.createTime,
    this.updateTime,
  });

  final int? id;
  final int? userId;
  final int? status;
  final String themeName;
  final String energeticDescription;
  final String? energeticImage;
  final String normalDescription;
  final String? normalImage;
  final String slightStressfulDescription;
  final String? slightStressfulImage;
  final String stressfulDescription;
  final String? stressfulImage;
  final int isOfficial;
  final int isDefaultTheme;
  final int? officialThemeId;
  final int? createTime;
  final int? updateTime;

  factory WatchThemeItem.fromJson(Map<String, dynamic> json) {
    return WatchThemeItem(
      id: _intFromJson(json['id']),
      userId: _intFromJson(json['user_id']),
      status: _intFromJson(json['status']),
      themeName: _stringFromJson(json['theme_name'], '自定义主题'),
      energeticDescription:
          _stringFromJson(json['energetic_description'], '状态优秀'),
      energeticImage: _nullableStringFromJson(json['energetic_image']),
      normalDescription: _stringFromJson(json['normal_description'], '状态正常'),
      normalImage: _nullableStringFromJson(json['normal_image']),
      slightStressfulDescription:
          _stringFromJson(json['slight_stressful_description'], '注意压力'),
      slightStressfulImage:
          _nullableStringFromJson(json['slight_stressful_image']),
      stressfulDescription:
          _stringFromJson(json['stressful_description'], '压力过载'),
      stressfulImage: _nullableStringFromJson(json['stressful_image']),
      isOfficial: _intFromJson(json['is_official']) ?? 0,
      isDefaultTheme: _intFromJson(json['is_default_theme']) ?? 0,
      officialThemeId: _intFromJson(json['official_theme_id']),
      createTime: _intFromJson(json['create_time']),
      updateTime: _intFromJson(json['update_time']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      if (id != null) 'id': id,
      if (userId != null) 'user_id': userId,
      if (status != null) 'status': status,
      'theme_name': themeName,
      'energetic_description': energeticDescription,
      'energetic_image': energeticImage,
      'normal_description': normalDescription,
      'normal_image': normalImage,
      'slight_stressful_description': slightStressfulDescription,
      'slight_stressful_image': slightStressfulImage,
      'stressful_description': stressfulDescription,
      'stressful_image': stressfulImage,
      'is_official': isOfficial,
      'is_default_theme': isDefaultTheme,
      if (officialThemeId != null) 'official_theme_id': officialThemeId,
      if (createTime != null) 'create_time': createTime,
      if (updateTime != null) 'update_time': updateTime,
    };
  }

  String get title => themeName;

  bool get isCustomTheme => isOfficial != 1;

  bool get isOfficialTheme => isOfficial == 1;

  bool get isDefault => isDefaultTheme == 1;

  List<WatchThemeItemInfo> get infoList => [
        WatchThemeItemInfo(
          title: energeticDescription,
          image: energeticImage,
        ),
        WatchThemeItemInfo(
          title: normalDescription,
          image: normalImage,
        ),
        WatchThemeItemInfo(
          title: slightStressfulDescription,
          image: slightStressfulImage,
        ),
        WatchThemeItemInfo(
          title: stressfulDescription,
          image: stressfulImage,
        ),
      ];

  static WatchThemeItem empty() {
    return const WatchThemeItem(
      themeName: '自定义主题',
      energeticDescription: '状态优秀',
      normalDescription: '状态正常',
      slightStressfulDescription: '注意压力',
      stressfulDescription: '压力过载',
    );
  }

  static int? _intFromJson(Object? value) {
    if (value is int) return value;
    if (value is num) return value.toInt();
    if (value is String) return int.tryParse(value);
    if (value is bool) return value ? 1 : 0;
    return null;
  }

  static String _stringFromJson(Object? value, String fallback) {
    final result = _nullableStringFromJson(value);
    return result ?? fallback;
  }

  static String? _nullableStringFromJson(Object? value) {
    if (value == null) return null;
    final result = value.toString().trim();
    return result.isEmpty ? null : result;
  }
}

class WatchThemeItemInfo {
  const WatchThemeItemInfo({
    required this.title,
    this.image,
  });

  final String title;
  final String? image;

  String? get imgUrl => _isNetworkImage ? image : null;

  String? get assetPath => _isNetworkImage ? null : image;

  bool get _isNetworkImage {
    final value = image?.toLowerCase();
    return value?.startsWith('http://') == true ||
        value?.startsWith('https://') == true;
  }
}

class WatchThemeResponse {
  const WatchThemeResponse({this.themes = const []});

  final List<WatchThemeItem> themes;

  factory WatchThemeResponse.fromJson(Map<String, dynamic> json) {
    final rawThemes = json['themes'];
    if (rawThemes is! List) return const WatchThemeResponse();
    return WatchThemeResponse(
      themes: rawThemes
          .whereType<Map>()
          .map((theme) => WatchThemeItem.fromJson(
                Map<String, dynamic>.from(theme),
              ))
          .toList(),
    );
  }
}

class WatchThemeUpsertRequest {
  const WatchThemeUpsertRequest({
    this.themeId,
    required this.themeName,
    required this.energeticDescription,
    required this.energeticImage,
    required this.normalDescription,
    required this.normalImage,
    required this.slightStressfulDescription,
    required this.slightStressfulImage,
    required this.stressfulDescription,
    required this.stressfulImage,
  });

  final int? themeId;
  final String themeName;
  final String energeticDescription;
  final String energeticImage;
  final String normalDescription;
  final String normalImage;
  final String slightStressfulDescription;
  final String slightStressfulImage;
  final String stressfulDescription;
  final String stressfulImage;

  Map<String, dynamic> toJson() {
    return {
      if (themeId != null) 'theme_id': themeId,
      'theme_name': themeName,
      'energetic_description': energeticDescription,
      'energetic_image': energeticImage,
      'normal_description': normalDescription,
      'normal_image': normalImage,
      'slight_stressful_description': slightStressfulDescription,
      'slight_stressful_image': slightStressfulImage,
      'stressful_description': stressfulDescription,
      'stressful_image': stressfulImage,
    };
  }
}

final defaultThemeTemplates = [
  WatchThemeTemplateItem(title: '状态优秀', color: WatchThemeColors.excellent),
  WatchThemeTemplateItem(title: '状态正常', color: WatchThemeColors.normal),
  WatchThemeTemplateItem(title: '注意压力', color: WatchThemeColors.stress),
  WatchThemeTemplateItem(title: '压力过载', color: WatchThemeColors.overload),
];

class WatchThemeTemplateItem {
  WatchThemeTemplateItem({required this.title, required this.color});

  final String title;
  final Color color;
}