import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/common/utils/json_utils.dart';

import '../../domain/entities/menu.dart';

/// 메뉴(Menu) API 응답을 표현하는 DTO.
class MenuDto {
  MenuDto({
    this.id,
    required this.menuCode,
    required this.menuName,
    this.parent,
    this.path,
    this.displayOrder,
    this.isActive = true,
    this.isDeleted = false,
    this.note,
    this.createdAt,
    this.updatedAt,
  });

  final int? id;
  final String menuCode;
  final String menuName;
  final MenuSummaryDto? parent;
  final String? path;
  final int? displayOrder;
  final bool isActive;
  final bool isDeleted;
  final String? note;
  final DateTime? createdAt;
  final DateTime? updatedAt;

  /// JSON에서 메뉴 정보를 파싱한다.
  factory MenuDto.fromJson(Map<String, dynamic> json) {
    return MenuDto(
      id: json['id'] as int?,
      menuCode: json['menu_code'] as String,
      menuName: json['menu_name'] as String,
      parent: json['parent_menu'] is Map<String, dynamic>
          ? MenuSummaryDto.fromJson(json['parent_menu'] as Map<String, dynamic>)
          : json['parent'] is Map<String, dynamic>
          ? MenuSummaryDto.fromJson(json['parent'] as Map<String, dynamic>)
          : null,
      path: json['path'] as String? ?? json['route_path'] as String?,
      displayOrder: json['display_order'] as int?,
      isActive: (json['is_active'] as bool?) ?? true,
      isDeleted: (json['is_deleted'] as bool?) ?? false,
      note: json['note'] as String?,
      createdAt: _parseDate(json['created_at']),
      updatedAt: _parseDate(json['updated_at']),
    );
  }

  /// DTO를 도메인 [MenuItem]으로 변환한다.
  MenuItem toEntity() => MenuItem(
    id: id,
    menuCode: menuCode,
    menuName: menuName,
    parent: parent?.toEntity(),
    path: path,
    displayOrder: displayOrder,
    isActive: isActive,
    isDeleted: isDeleted,
    note: note,
    createdAt: createdAt,
    updatedAt: updatedAt,
  );

  /// 페이징 응답을 [PaginatedResult]로 변환한다.
  static PaginatedResult<MenuItem> parsePaginated(Map<String, dynamic>? json) {
    final rawItems = JsonUtils.extractList(json, keys: const ['items']);
    final items = rawItems
        .map(MenuDto.fromJson)
        .map((dto) => dto.toEntity())
        .toList(growable: false);
    return PaginatedResult<MenuItem>(
      items: items,
      page: JsonUtils.readInt(json, 'page', fallback: 1),
      pageSize: JsonUtils.readInt(json, 'page_size', fallback: items.length),
      total: JsonUtils.readInt(json, 'total', fallback: items.length),
    );
  }
}

/// 하위 메뉴 요약 정보를 담는 DTO.
class MenuSummaryDto {
  MenuSummaryDto({required this.id, required this.menuName});

  final int id;
  final String menuName;

  /// JSON에서 요약 정보를 파싱한다.
  factory MenuSummaryDto.fromJson(Map<String, dynamic> json) {
    return MenuSummaryDto(
      id: json['id'] as int,
      menuName: json['menu_name'] as String,
    );
  }

  /// DTO를 [MenuSummary] 엔티티로 변환한다.
  MenuSummary toEntity() => MenuSummary(id: id, menuName: menuName);
}

/// 문자열/DateTime을 파싱해 [DateTime]으로 변환한다.
DateTime? _parseDate(Object? value) {
  if (value == null) return null;
  if (value is DateTime) return value;
  if (value is String) return DateTime.tryParse(value);
  return null;
}
