import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';

abstract final class FetchEnergyManagementDataHelper {
  const FetchEnergyManagementDataHelper._();

  static AnalyticsDevice? getSelectedDevice(BuildContext context) {
    return context.read<AnalyticsDevicesBloc>().state.selectedDevice;
  }

  static void loadEnergyManagementData(
    BuildContext context, {
    required String communityId,
    required String spaceId,
    DateTime? selectedDate,
    bool shouldFetchAnalyticsDevices = true,
  }) {
    if (communityId.isEmpty && spaceId.isEmpty) {
      clearAllData(context);
      return;
    }

    final datePickerState = context.read<AnalyticsDatePickerBloc>().state;
    final selectedDate0 = selectedDate ?? datePickerState.monthlyDate;
    if (shouldFetchAnalyticsDevices) {
      loadAnalyticsDevices(
        context,
        communityUuid: communityId,
        spaceUuid: spaceId,
        selectedDate: selectedDate0,
      );
      loadRealtimeDeviceChanges(context);
      loadPowerClampInfo(context);
    }
    loadTotalEnergyConsumption(
      context,
      selectedDate: selectedDate0,
      spaceId: spaceId,
    );
    final selectedDevice = getSelectedDevice(context);
    if (selectedDevice case final AnalyticsDevice device) {
      loadEnergyConsumptionByPhases(
        context,
        powerClampUuid: device.uuid,
        selectedDate: selectedDate0,
      );
    }
    loadEnergyConsumptionPerDevice(
      context,
      spaceId: spaceId,
      selectedDate: selectedDate0,
    );
  }

  static void loadEnergyConsumptionByPhases(
    BuildContext context, {
    required String powerClampUuid,
    DateTime? selectedDate,
  }) {
    final param = GetEnergyConsumptionByPhasesParam(
      date: selectedDate,
      powerClampUuid: powerClampUuid,
    );
    context.read<EnergyConsumptionByPhasesBloc>().add(
          LoadEnergyConsumptionByPhasesEvent(param: param),
        );
  }

  static void loadTotalEnergyConsumption(
    BuildContext context, {
    DateTime? selectedDate,
    required String spaceId,
  }) {
    final param = GetTotalEnergyConsumptionParam(
      spaceId: spaceId,
      monthDate: selectedDate,
    );
    context.read<TotalEnergyConsumptionBloc>().add(
          TotalEnergyConsumptionLoadEvent(param: param),
        );
  }

  static void loadEnergyConsumptionPerDevice(
    BuildContext context, {
    DateTime? selectedDate,
    required String spaceId,
  }) {
    final param = GetEnergyConsumptionPerDeviceParam(
      spaceId: spaceId,
      monthDate: selectedDate,
    );
    context.read<EnergyConsumptionPerDeviceBloc>().add(
          LoadEnergyConsumptionPerDeviceEvent(param),
        );
  }

  static void loadPowerClampInfo(BuildContext context) {
    final selectedDevice = getSelectedDevice(context);
    if (selectedDevice case final AnalyticsDevice device) {
      context.read<PowerClampInfoBloc>().add(
            LoadPowerClampInfoEvent(device.uuid),
          );
    }
  }

  static void loadRealtimeDeviceChanges(
    BuildContext context, {
    String? deviceUuid,
  }) {
    final selectedDevice = getSelectedDevice(context);

    context.read<RealtimeDeviceChangesBloc>().add(
          RealtimeDeviceChangesStarted(deviceUuid ?? selectedDevice?.uuid ?? ''),
        );
  }

  static void loadAnalyticsDevices(
    BuildContext context, {
    required String communityUuid,
    required String spaceUuid,
    required DateTime selectedDate,
  }) {
    context.read<AnalyticsDevicesBloc>().add(
          LoadAnalyticsDevicesEvent(
            onSuccess: (device) {
              context.read<PowerClampInfoBloc>().add(
                    LoadPowerClampInfoEvent(device.uuid),
                  );
              loadEnergyConsumptionByPhases(
                context,
                powerClampUuid: device.uuid,
                selectedDate: selectedDate,
              );
              context.read<RealtimeDeviceChangesBloc>().add(
                    RealtimeDeviceChangesStarted(device.uuid),
                  );
            },
            param: GetAnalyticsDevicesParam(
              communityUuid: communityUuid,
              spaceUuid: spaceUuid,
              deviceTypes: ['PC'],
              requestType: AnalyticsDeviceRequestType.energyManagement,
            ),
          ),
        );
  }

  static void clearAllData(BuildContext context) {
    context.read<PowerClampInfoBloc>().add(
          const ClearPowerClampInfoEvent(),
        );
    context.read<RealtimeDeviceChangesBloc>().add(
          const RealtimeDeviceChangesClosed(),
        );

    context.read<EnergyConsumptionPerDeviceBloc>().add(
          const ClearEnergyConsumptionPerDeviceEvent(),
        );

    context.read<TotalEnergyConsumptionBloc>().add(
          const ClearTotalEnergyConsumptionEvent(),
        );

    context.read<EnergyConsumptionByPhasesBloc>().add(
          const ClearEnergyConsumptionByPhasesEvent(),
        );
    context.read<AnalyticsDevicesBloc>().add(const ClearAnalyticsDeviceEvent());
  }
}
