import 'dart:convert';
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
import 'package:worker/core/database/models/enums.dart';

part 'project_submission_model.g.dart';

@HiveType(typeId: HiveTypeIds.projectSubmissionModel)
class ProjectSubmissionModel extends HiveObject {
  ProjectSubmissionModel({
    required this.submissionId,
    required this.userId,
    required this.projectName,
    required this.projectAddress,
    required this.projectValue,
    required this.projectType,
    this.beforePhotos,
    this.afterPhotos,
    this.invoices,
    required this.status,
    this.reviewNotes,
    this.rejectionReason,
    this.pointsEarned,
    required this.submittedAt,
    this.reviewedAt,
    this.reviewedBy,
  });

  @HiveField(0)
  final String submissionId;
  @HiveField(1)
  final String userId;
  @HiveField(2)
  final String projectName;
  @HiveField(3)
  final String projectAddress;
  @HiveField(4)
  final double projectValue;
  @HiveField(5)
  final ProjectType projectType;
  @HiveField(6)
  final String? beforePhotos;
  @HiveField(7)
  final String? afterPhotos;
  @HiveField(8)
  final String? invoices;
  @HiveField(9)
  final SubmissionStatus status;
  @HiveField(10)
  final String? reviewNotes;
  @HiveField(11)
  final String? rejectionReason;
  @HiveField(12)
  final int? pointsEarned;
  @HiveField(13)
  final DateTime submittedAt;
  @HiveField(14)
  final DateTime? reviewedAt;
  @HiveField(15)
  final String? reviewedBy;

  factory ProjectSubmissionModel.fromJson(
    Map<String, dynamic> json,
  ) => ProjectSubmissionModel(
    submissionId: json['submission_id'] as String,
    userId: json['user_id'] as String,
    projectName: json['project_name'] as String,
    projectAddress: json['project_address'] as String,
    projectValue: (json['project_value'] as num).toDouble(),
    projectType: ProjectType.values.firstWhere(
      (e) => e.name == json['project_type'],
    ),
    beforePhotos: json['before_photos'] != null
        ? jsonEncode(json['before_photos'])
        : null,
    afterPhotos: json['after_photos'] != null
        ? jsonEncode(json['after_photos'])
        : null,
    invoices: json['invoices'] != null ? jsonEncode(json['invoices']) : null,
    status: SubmissionStatus.values.firstWhere((e) => e.name == json['status']),
    reviewNotes: json['review_notes'] as String?,
    rejectionReason: json['rejection_reason'] as String?,
    pointsEarned: json['points_earned'] as int?,
    submittedAt: DateTime.parse(json['submitted_at']?.toString() ?? ''),
    reviewedAt: json['reviewed_at'] != null
        ? DateTime.parse(json['reviewed_at']?.toString() ?? '')
        : null,
    reviewedBy: json['reviewed_by'] as String?,
  );

  Map<String, dynamic> toJson() => {
    'submission_id': submissionId,
    'user_id': userId,
    'project_name': projectName,
    'project_address': projectAddress,
    'project_value': projectValue,
    'project_type': projectType.name,
    'before_photos': beforePhotos != null ? jsonDecode(beforePhotos!) : null,
    'after_photos': afterPhotos != null ? jsonDecode(afterPhotos!) : null,
    'invoices': invoices != null ? jsonDecode(invoices!) : null,
    'status': status.name,
    'review_notes': reviewNotes,
    'rejection_reason': rejectionReason,
    'points_earned': pointsEarned,
    'submitted_at': submittedAt.toIso8601String(),
    'reviewed_at': reviewedAt?.toIso8601String(),
    'reviewed_by': reviewedBy,
  };

  List<String>? get beforePhotosList {
    if (beforePhotos == null) return null;
    try {
      final decoded = jsonDecode(beforePhotos!) as List;
      return decoded.map((e) => e.toString()).toList();
    } catch (e) {
      return null;
    }
  }

  List<String>? get afterPhotosList {
    if (afterPhotos == null) return null;
    try {
      final decoded = jsonDecode(afterPhotos!) as List;
      return decoded.map((e) => e.toString()).toList();
    } catch (e) {
      return null;
    }
  }
}
