import 'dart:io';
import 'dart:convert';

/// 用于区分 copyWith 中"未传参数"和"传了 null"的标记
class _CopyWithNullSentinel {
  const _CopyWithNullSentinel();
}
const _copyWithNull = _CopyWithNullSentinel();

/// 影视条目模型
class Movie {
  final String id;
  final String title; // 影视名称
  final String? posterPath; // 本地海报路径
  final DateTime? releaseDate; // 上映时间
  final List<String> directors; // 导演列表
  final List<String> writers; // 编剧列表
  final List<String> actors; // 主演列表
  final List<String> genres; // 类型
  final List<String> alternateTitles; // 别名
  final String? summary; // 剧情简介
  final double? rating; // 评分 1-10
  final String status; // watched/want_to_watch/watching
  final DateTime? watchDate; // 观看日期
  final DateTime createdAt;
  final DateTime updatedAt;
  final bool isDeleted;

  Movie({
    required this.id,
    required this.title,
    this.posterPath,
    this.releaseDate,
    this.directors = const [],
    this.writers = const [],
    this.actors = const [],
    this.genres = const [],
    this.alternateTitles = const [],
    this.summary,
    this.rating,
    required this.status,
    this.watchDate,
    required this.createdAt,
    required this.updatedAt,
    this.isDeleted = false,
  });

  factory Movie.fromJson(Map<String, dynamic> json) {
    return Movie(
      id: json['id'] ?? '',
      title: json['title'] ?? '',
      posterPath: json['poster_path'],
      releaseDate: json['release_date'] != null 
          ? DateTime.parse(json['release_date']) 
          : null,
      directors: _parseStringList(json['directors']),
      writers: _parseStringList(json['writers']),
      actors: _parseStringList(json['actors']),
      genres: _parseStringList(json['genres']),
      alternateTitles: _parseStringList(json['alternate_titles']),
      summary: json['summary'],
      rating: json['rating']?.toDouble(),
      status: json['status'] ?? 'want_to_watch',
      watchDate: json['watch_date'] != null
          ? DateTime.parse(json['watch_date'])
          : null,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'poster_path': posterPath,
      'release_date': releaseDate?.toUtc().toUtc().toIso8601String(),
      'directors': jsonEncode(directors),
      'writers': jsonEncode(writers),
      'actors': jsonEncode(actors),
      'genres': jsonEncode(genres),
      'alternate_titles': jsonEncode(alternateTitles),
      'summary': summary,
      'rating': rating,
      'status': status,
      'watch_date': watchDate?.toUtc().toIso8601String(),
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
      'is_deleted': isDeleted ? 1 : 0,
    };
  }
  
  /// 获取封面文件
  File? get posterFile {
    if (posterPath == null || posterPath!.isEmpty) return null;
    return File(posterPath!);
  }

  /// 解析字符串列表（公共静态方法，供Book使用）
  static List<String> parseStringList(dynamic data) {
    if (data == null) return [];
    if (data is List) {
      return data.map((e) => e.toString()).toList();
    }
    if (data is String) {
      try {
        // 尝试解析JSON字符串
        final decoded = jsonDecode(data);
        if (decoded is List) {
          return decoded.map((e) => e.toString()).toList();
        }
      } catch (e) {
        // 如果解析失败，按逗号分割
        return data.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
      }
    }
    return [];
  }
  
  /// 解析字符串列表（私有别名，保持兼容性）
  static List<String> _parseStringList(dynamic data) => parseStringList(data);

  /// 复制并修改
  Movie copyWith({
    String? id,
    String? title,
    Object? posterPath = _copyWithNull,
    DateTime? releaseDate,
    List<String>? directors,
    List<String>? writers,
    List<String>? actors,
    List<String>? genres,
    List<String>? alternateTitles,
    Object? summary = _copyWithNull,
    double? rating,
    String? status,
    DateTime? watchDate,
    DateTime? createdAt,
    DateTime? updatedAt,
    bool? isDeleted,
  }) {
    return Movie(
      id: id ?? this.id,
      title: title ?? this.title,
      posterPath: posterPath is _CopyWithNullSentinel ? this.posterPath : (posterPath as String?),
      releaseDate: releaseDate ?? this.releaseDate,
      directors: directors ?? this.directors,
      writers: writers ?? this.writers,
      actors: actors ?? this.actors,
      genres: genres ?? this.genres,
      alternateTitles: alternateTitles ?? this.alternateTitles,
      summary: summary is _CopyWithNullSentinel ? this.summary : (summary as String?),
      rating: rating ?? this.rating,
      status: status ?? this.status,
      watchDate: watchDate ?? this.watchDate,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      isDeleted: isDeleted ?? this.isDeleted,
    );
  }
}

/// 书籍条目模型
class Book {
  final String id;
  final String title; // 书籍名称
  final String? coverPath; // 本地封面路径
  final List<String> authors; // 作者列表
  final List<String> alternateTitles; // 别名
  final String? publisher; // 出版社
  final List<String> genres; // 类型
  final String? summary; // 书籍简介
  final double? rating; // 评分 1-10
  final String status; // read/reading/want_to_read
  final String? isbn; // ISBN编号
  final DateTime? publishDate; // 出版时间
  final DateTime createdAt;
  final DateTime updatedAt;
  final bool isDeleted;

  Book({
    required this.id,
    required this.title,
    this.coverPath,
    this.authors = const [],
    this.alternateTitles = const [],
    this.publisher,
    this.genres = const [],
    this.summary,
    this.rating,
    required this.status,
    this.isbn,
    this.publishDate,
    required this.createdAt,
    required this.updatedAt,
    this.isDeleted = false,
  });

  factory Book.fromJson(Map<String, dynamic> json) {
    return Book(
      id: json['id'] ?? '',
      title: json['title'] ?? '',
      coverPath: json['cover_path'],
      authors: Movie.parseStringList(json['authors']),
      alternateTitles: Movie.parseStringList(json['alternate_titles']),
      publisher: json['publisher'],
      genres: Movie.parseStringList(json['genres']),
      summary: json['summary'],
      rating: json['rating']?.toDouble(),
      status: json['status'] ?? 'want_to_read',
      isbn: json['isbn'],
      publishDate: json['publish_date'] != null
          ? DateTime.parse(json['publish_date'])
          : null,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'cover_path': coverPath,
      'authors': jsonEncode(authors),
      'alternate_titles': jsonEncode(alternateTitles),
      'publisher': publisher,
      'genres': jsonEncode(genres),
      'summary': summary,
      'rating': rating,
      'status': status,
      'isbn': isbn,
      'publish_date': publishDate?.toUtc().toIso8601String(),
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
      'is_deleted': isDeleted ? 1 : 0,
    };
  }
  
  /// 获取封面文件
  File? get coverFile {
    if (coverPath == null || coverPath!.isEmpty) return null;
    return File(coverPath!);
  }

  /// 复制并修改
  Book copyWith({
    String? id,
    String? title,
    Object? coverPath = _copyWithNull,
    List<String>? authors,
    List<String>? alternateTitles,
    String? publisher,
    List<String>? genres,
    Object? summary = _copyWithNull,
    double? rating,
    String? status,
    Object? isbn = _copyWithNull,
    DateTime? publishDate,
    DateTime? createdAt,
    DateTime? updatedAt,
    bool? isDeleted,
  }) {
    return Book(
      id: id ?? this.id,
      title: title ?? this.title,
      coverPath: coverPath is _CopyWithNullSentinel ? this.coverPath : (coverPath as String?),
      authors: authors ?? this.authors,
      alternateTitles: alternateTitles ?? this.alternateTitles,
      publisher: publisher ?? this.publisher,
      genres: genres ?? this.genres,
      summary: summary is _CopyWithNullSentinel ? this.summary : (summary as String?),
      rating: rating ?? this.rating,
      status: status ?? this.status,
      isbn: isbn is _CopyWithNullSentinel ? this.isbn : (isbn as String?),
      publishDate: publishDate ?? this.publishDate,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      isDeleted: isDeleted ?? this.isDeleted,
    );
  }
}

/// 笔记模型
class Note {
  final String id;
  final String title;
  final String content;
  final String contentType; // 内容类型（markdown）
  final List<String> tags;
  final List<String> images; // 图片路径列表
  final DateTime createdAt;
  final DateTime updatedAt;
  final bool isDeleted;

  Note({
    required this.id,
    required this.title,
    required this.content,
    this.contentType = 'markdown',
    this.tags = const [],
    this.images = const [],
    required this.createdAt,
    required this.updatedAt,
    this.isDeleted = false,
  });

  factory Note.fromJson(Map<String, dynamic> json) {
    return Note(
      id: json['id']?.toString() ?? '',
      title: json['title'] ?? '',
      content: json['content'] ?? '',
      contentType: json['content_type'] ?? 'markdown',
      tags: Movie.parseStringList(json['tags']),
      images: Movie.parseStringList(json['images']),
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'content': content,
      'content_type': contentType,
      'tags': jsonEncode(tags),
      'images': jsonEncode(images),
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
      'is_deleted': isDeleted ? 1 : 0,
    };
  }
  
  /// 复制并修改
  Note copyWith({
    String? id,
    String? title,
    String? content,
    String? contentType,
    List<String>? tags,
    List<String>? images,
    DateTime? createdAt,
    DateTime? updatedAt,
    bool? isDeleted,
  }) {
    return Note(
      id: id ?? this.id,
      title: title ?? this.title,
      content: content ?? this.content,
      contentType: contentType ?? this.contentType,
      tags: tags ?? this.tags,
      images: images ?? this.images,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      isDeleted: isDeleted ?? this.isDeleted,
    );
  }
  
  /// 获取内容摘要（前100字）
  String get summary {
    if (content.length <= 100) return content;
    return '${content.substring(0, 100)}...';
  }
}

/// 影评模型
class MovieReview {
  final String id;
  final String movieId;
  final String content;
  final String reviewer;
  final String source;
  final int reviewType; // 1: 短评, 2: 长评
  final bool isDeleted;
  final DateTime createdAt;
  final DateTime updatedAt;

  MovieReview({
    required this.id,
    required this.movieId,
    required this.content,
    this.reviewer = '',
    this.source = '',
    this.reviewType = 1,
    this.isDeleted = false,
    required this.createdAt,
    required this.updatedAt,
  });

  factory MovieReview.fromJson(Map<String, dynamic> json) {
    return MovieReview(
      id: json['id']?.toString() ?? '',
      movieId: json['movie_id']?.toString() ?? '',
      content: json['content'] ?? '',
      reviewer: json['reviewer'] ?? '',
      source: json['source'] ?? '',
      reviewType: json['review_type'] ?? 1,
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'movie_id': movieId,
      'content': content,
      'reviewer': reviewer,
      'source': source,
      'review_type': reviewType,
      'is_deleted': isDeleted ? 1 : 0,
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
    };
  }
  
  /// 复制并修改
  MovieReview copyWith({
    String? id,
    String? movieId,
    String? content,
    String? reviewer,
    String? source,
    int? reviewType,
    bool? isDeleted,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return MovieReview(
      id: id ?? this.id,
      movieId: movieId ?? this.movieId,
      content: content ?? this.content,
      reviewer: reviewer ?? this.reviewer,
      source: source ?? this.source,
      reviewType: reviewType ?? this.reviewType,
      isDeleted: isDeleted ?? this.isDeleted,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }
  
  /// 获取评论摘要
  String get summary {
    if (content.length <= 50) return content;
    return '${content.substring(0, 50)}...';
  }
  
  /// 评论类型文本
  String get typeText => reviewType == 1 ? '短评' : '长评';
}

/// 影视海报墙模型
class MoviePoster {
  final String id;
  final String movieId;
  final String posterPath;
  final bool isDeleted;
  final DateTime createdAt;

  MoviePoster({
    required this.id,
    required this.movieId,
    required this.posterPath,
    this.isDeleted = false,
    required this.createdAt,
  });

  factory MoviePoster.fromJson(Map<String, dynamic> json) {
    return MoviePoster(
      id: json['id']?.toString() ?? '',
      movieId: json['movie_id']?.toString() ?? '',
      posterPath: json['poster_path'] ?? '',
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
      createdAt: json['created_at'] != null 
          ? DateTime.parse(json['created_at']) 
          : DateTime.now(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'movie_id': movieId,
      'poster_path': posterPath,
      'is_deleted': isDeleted ? 1 : 0,
      'created_at': createdAt.toUtc().toIso8601String(),
    };
  }
  
  /// 获取海报文件
  File? get posterFile {
    if (posterPath.isEmpty) return null;
    return File(posterPath);
  }
}

/// 书评模型
class BookReview {
  final String id;
  final String bookId;
  final String content;
  final String reviewer;
  final String source;
  final int reviewType; // 1: 短评, 2: 长评
  final bool isDeleted;
  final DateTime createdAt;
  final DateTime updatedAt;

  BookReview({
    required this.id,
    required this.bookId,
    required this.content,
    this.reviewer = '',
    this.source = '',
    this.reviewType = 1,
    this.isDeleted = false,
    required this.createdAt,
    required this.updatedAt,
  });

  factory BookReview.fromJson(Map<String, dynamic> json) {
    return BookReview(
      id: json['id']?.toString() ?? '',
      bookId: json['book_id']?.toString() ?? '',
      content: json['content'] ?? '',
      reviewer: json['reviewer'] ?? '',
      source: json['source'] ?? '',
      reviewType: json['review_type'] ?? 1,
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'book_id': bookId,
      'content': content,
      'reviewer': reviewer,
      'source': source,
      'review_type': reviewType,
      'is_deleted': isDeleted ? 1 : 0,
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
    };
  }

  /// 复制并修改
  BookReview copyWith({
    String? id,
    String? bookId,
    String? content,
    String? reviewer,
    String? source,
    int? reviewType,
    bool? isDeleted,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return BookReview(
      id: id ?? this.id,
      bookId: bookId ?? this.bookId,
      content: content ?? this.content,
      reviewer: reviewer ?? this.reviewer,
      source: source ?? this.source,
      reviewType: reviewType ?? this.reviewType,
      isDeleted: isDeleted ?? this.isDeleted,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }

  /// 获取评论摘要
  String get summary {
    if (content.length <= 50) return content;
    return '${content.substring(0, 50)}...';
  }

  /// 评论类型文本
  String get typeText => reviewType == 1 ? '短评' : '长评';
}

/// 书籍摘抄模型
class BookExcerpt {
  final String id;
  final String bookId;
  final String chapter; // 章节
  final String content; // 摘抄内容
  final String comment; // 摘抄的评论/感悟
  final bool isDeleted;
  final DateTime createdAt;
  final DateTime updatedAt;

  BookExcerpt({
    required this.id,
    required this.bookId,
    this.chapter = '',
    required this.content,
    this.comment = '',
    this.isDeleted = false,
    required this.createdAt,
    required this.updatedAt,
  });

  factory BookExcerpt.fromJson(Map<String, dynamic> json) {
    return BookExcerpt(
      id: json['id']?.toString() ?? '',
      bookId: json['book_id']?.toString() ?? '',
      chapter: json['chapter'] ?? '',
      content: json['content'] ?? '',
      comment: json['comment'] ?? '',
      isDeleted: json['is_deleted'] == 1 || json['is_deleted'] == true,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'])
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'])
          : DateTime.now(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'book_id': bookId,
      'chapter': chapter,
      'content': content,
      'comment': comment,
      'is_deleted': isDeleted ? 1 : 0,
      'created_at': createdAt.toUtc().toIso8601String(),
      'updated_at': updatedAt.toUtc().toIso8601String(),
    };
  }

  /// 复制并修改
  BookExcerpt copyWith({
    String? id,
    String? bookId,
    String? chapter,
    String? content,
    String? comment,
    bool? isDeleted,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return BookExcerpt(
      id: id ?? this.id,
      bookId: bookId ?? this.bookId,
      chapter: chapter ?? this.chapter,
      content: content ?? this.content,
      comment: comment ?? this.comment,
      isDeleted: isDeleted ?? this.isDeleted,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }

  /// 获取摘抄摘要
  String get summary {
    if (content.length <= 50) return content;
    return '${content.substring(0, 50)}...';
  }
}

