import 'package:equatable/equatable.dart';

double _parseDouble(dynamic value, {double fallback = 0.0}) {
  if (value == null) return fallback;
  if (value is double) return value;
  if (value is int) return value.toDouble();
  if (value is String) {
    final parsed = double.tryParse(value.trim());
    return parsed ?? fallback;
  }
  return fallback;
}

int _parseInt(dynamic value, {int fallback = 0}) {
  if (value == null) return fallback;
  if (value is int) return value;
  if (value is double) return value.toInt();
  if (value is String) {
    final parsed = int.tryParse(value.trim());
    return parsed ?? fallback;
  }
  return fallback;
}

String _parseString(dynamic value, {String fallback = ''}) {
  if (value == null) return fallback;
  if (value is String) return value;
  return value.toString();
}

// ==================== 经营概览看板 ====================

class ElectricityTodayBO extends Equatable {
  final double value;
  final double yesterdayValue;

  const ElectricityTodayBO({
    required this.value,
    required this.yesterdayValue,
  });

  factory ElectricityTodayBO.fromJson(Map<String, dynamic> json) {
    return ElectricityTodayBO(
      value: _parseDouble(json['value']),
      yesterdayValue: _parseDouble(json['yesterdayValue']),
    );
  }

  @override
  List<Object?> get props => [value, yesterdayValue];
}

class AlertPendingBO extends Equatable {
  final int count;

  const AlertPendingBO({required this.count});

  factory AlertPendingBO.fromJson(Map<String, dynamic> json) {
    return AlertPendingBO(count: _parseInt(json['count']));
  }

  @override
  List<Object?> get props => [count];
}

class DashboardTrendPointBO extends Equatable {
  final String time;
  final double value;

  const DashboardTrendPointBO({required this.time, required this.value});

  factory DashboardTrendPointBO.fromJson(Map<String, dynamic> json) {
    return DashboardTrendPointBO(
      time: _parseString(json['time']),
      value: _parseDouble(json['value']),
    );
  }

  @override
  List<Object?> get props => [time, value];
}

class ElectricityTrendBO extends Equatable {
  final String dateRange;
  final double maxValue;
  final List<DashboardTrendPointBO> points;

  const ElectricityTrendBO({
    required this.dateRange,
    required this.maxValue,
    required this.points,
  });

  factory ElectricityTrendBO.fromJson(Map<String, dynamic> json) {
    return ElectricityTrendBO(
      dateRange: _parseString(json['dateRange']),
      maxValue: _parseDouble(json['maxValue']),
      points: (json['points'] as List<dynamic>?)
              ?.map((e) =>
                  DashboardTrendPointBO.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
    );
  }

  @override
  List<Object?> get props => [dateRange, maxValue, points];
}

class RoomStatusItemBO extends Equatable {
  final String statusLabel;
  final int count;
  final double percent;

  const RoomStatusItemBO({
    required this.statusLabel,
    required this.count,
    required this.percent,
  });

  factory RoomStatusItemBO.fromJson(Map<String, dynamic> json) {
    return RoomStatusItemBO(
      statusLabel: _parseString(json['statusLabel']),
      count: _parseInt(json['count']),
      percent: _parseDouble(json['percent']),
    );
  }

  @override
  List<Object?> get props => [statusLabel, count, percent];
}

class RoomStatusDistributionBO extends Equatable {
  final int total;
  final List<RoomStatusItemBO> items;

  const RoomStatusDistributionBO({required this.total, required this.items});

  factory RoomStatusDistributionBO.fromJson(Map<String, dynamic> json) {
    return RoomStatusDistributionBO(
      total: _parseInt(json['total']),
      items: (json['items'] as List<dynamic>?)
              ?.map((e) =>
                  RoomStatusItemBO.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
    );
  }

  @override
  List<Object?> get props => [total, items];
}

class DeviceTypeItemBO extends Equatable {
  final String typeLabel;
  final int count;

  const DeviceTypeItemBO({required this.typeLabel, required this.count});

  factory DeviceTypeItemBO.fromJson(Map<String, dynamic> json) {
    return DeviceTypeItemBO(
      typeLabel: _parseString(json['typeLabel']),
      count: _parseInt(json['count']),
    );
  }

  @override
  List<Object?> get props => [typeLabel, count];
}

class DeviceTypeDistributionBO extends Equatable {
  final int totalDeviceCount;
  final List<DeviceTypeItemBO> items;

  const DeviceTypeDistributionBO({
    required this.totalDeviceCount,
    required this.items,
  });

  factory DeviceTypeDistributionBO.fromJson(Map<String, dynamic> json) {
    return DeviceTypeDistributionBO(
      totalDeviceCount: _parseInt(json['totalDeviceCount']),
      items: (json['items'] as List<dynamic>?)
              ?.map((e) =>
                  DeviceTypeItemBO.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
    );
  }

  @override
  List<Object?> get props => [totalDeviceCount, items];
}

class DashboardOverviewBO extends Equatable {
  final ElectricityTodayBO electricityToday;
  final AlertPendingBO alertPending;
  final ElectricityTrendBO electricityTrend;
  final RoomStatusDistributionBO roomStatusDistribution;
  final DeviceTypeDistributionBO deviceTypeDistribution;

  const DashboardOverviewBO({
    required this.electricityToday,
    required this.alertPending,
    required this.electricityTrend,
    required this.roomStatusDistribution,
    required this.deviceTypeDistribution,
  });

  factory DashboardOverviewBO.fromJson(Map<String, dynamic> json) {
    return DashboardOverviewBO(
      electricityToday: ElectricityTodayBO.fromJson(
          json['electricityToday'] as Map<String, dynamic>? ?? {}),
      alertPending: AlertPendingBO.fromJson(
          json['alertPending'] as Map<String, dynamic>? ?? {}),
      electricityTrend: ElectricityTrendBO.fromJson(
          json['electricityTrend'] as Map<String, dynamic>? ?? {}),
      roomStatusDistribution: RoomStatusDistributionBO.fromJson(
          json['roomStatusDistribution'] as Map<String, dynamic>? ?? {}),
      deviceTypeDistribution: DeviceTypeDistributionBO.fromJson(
          json['deviceTypeDistribution'] as Map<String, dynamic>? ?? {}),
    );
  }

  @override
  List<Object?> get props => [
        electricityToday,
        alertPending,
        electricityTrend,
        roomStatusDistribution,
        deviceTypeDistribution,
      ];
}

// ==================== 能耗分析 ====================

class HourlyPointBO extends Equatable {
  final String time;
  final double value;

  const HourlyPointBO({required this.time, required this.value});

  factory HourlyPointBO.fromJson(Map<String, dynamic> json) {
    return HourlyPointBO(
      time: _parseString(json['time']),
      value: _parseDouble(json['value']),
    );
  }

  @override
  List<Object?> get props => [time, value];
}

class HourlyUsageTodayBO extends Equatable {
  final double maxValue;
  final List<HourlyPointBO> hourlyPoints;

  const HourlyUsageTodayBO({
    required this.maxValue,
    required this.hourlyPoints,
  });

  factory HourlyUsageTodayBO.fromJson(Map<String, dynamic> json) {
    return HourlyUsageTodayBO(
      maxValue: _parseDouble(json['maxValue']),
      hourlyPoints: (json['hourlyPoints'] as List<dynamic>?)
              ?.map(
                  (e) => HourlyPointBO.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
    );
  }

  @override
  List<Object?> get props => [maxValue, hourlyPoints];
}

class ZoneUsageItemBO extends Equatable {
  final String zoneLabel;
  final double todayKwh;
  final double yesterdayKwh;

  const ZoneUsageItemBO({
    required this.zoneLabel,
    required this.todayKwh,
    required this.yesterdayKwh,
  });

  factory ZoneUsageItemBO.fromJson(Map<String, dynamic> json) {
    return ZoneUsageItemBO(
      zoneLabel: _parseString(json['zoneLabel']),
      todayKwh: _parseDouble(json['todayKwh']),
      yesterdayKwh: _parseDouble(json['yesterdayKwh']),
    );
  }

  @override
  List<Object?> get props => [zoneLabel, todayKwh, yesterdayKwh];
}

class ZoneUsageRatioBO extends Equatable {
  final double totalToday;
  final double totalYesterday;
  final List<ZoneUsageItemBO> zones;

  const ZoneUsageRatioBO({
    required this.totalToday,
    required this.totalYesterday,
    required this.zones,
  });

  factory ZoneUsageRatioBO.fromJson(Map<String, dynamic> json) {
    return ZoneUsageRatioBO(
      totalToday: _parseDouble(json['totalToday']),
      totalYesterday: _parseDouble(json['totalYesterday']),
      zones: (json['zones'] as List<dynamic>?)
              ?.map((e) =>
                  ZoneUsageItemBO.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
    );
  }

  @override
  List<Object?> get props => [totalToday, totalYesterday, zones];
}

class EnergyAnalysisBO extends Equatable {
  final double todayElectricity;
  final double yesterdayElectricity;
  final double monthElectricity;
  final double lastMonthElectricity;
  final double monthCostEstimate;
  final HourlyUsageTodayBO hourlyUsageToday;
  final ZoneUsageRatioBO zoneUsageRatio;

  const EnergyAnalysisBO({
    required this.todayElectricity,
    required this.yesterdayElectricity,
    required this.monthElectricity,
    required this.lastMonthElectricity,
    required this.monthCostEstimate,
    required this.hourlyUsageToday,
    required this.zoneUsageRatio,
  });

  factory EnergyAnalysisBO.fromJson(Map<String, dynamic> json) {
    return EnergyAnalysisBO(
      todayElectricity: _parseDouble(json['todayElectricity']),
      yesterdayElectricity: _parseDouble(json['yesterdayElectricity']),
      monthElectricity: _parseDouble(json['monthElectricity']),
      lastMonthElectricity: _parseDouble(json['lastMonthElectricity']),
      monthCostEstimate: _parseDouble(json['monthCostEstimate']),
      hourlyUsageToday: HourlyUsageTodayBO.fromJson(
          json['hourlyUsageToday'] as Map<String, dynamic>? ?? {}),
      zoneUsageRatio: ZoneUsageRatioBO.fromJson(
          json['zoneUsageRatio'] as Map<String, dynamic>? ?? {}),
    );
  }

  @override
  List<Object?> get props => [
        todayElectricity,
        yesterdayElectricity,
        monthElectricity,
        lastMonthElectricity,
        monthCostEstimate,
        hourlyUsageToday,
        zoneUsageRatio,
      ];
}
