import 'dart:async';

import 'package:flutter_map/flutter_map.dart';
import 'package:hub/src/features/hub/domain/entities/position_entity.dart';
import 'package:hub/src/features/hub/domain/get_devices_use_case.dart';
import 'package:hub/src/features/hub/domain/get_latest_positions_use_case.dart';
import 'package:hub/src/features/hub/presentation/providers/get_devices_use_case_provider.dart';
import 'package:hub/src/features/hub/presentation/providers/get_latest_positions_use_case_provider.dart';
import 'package:hub/src/features/hub/presentation/state/hub_view_state.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.dart';

final hubViewModelProvider =
NotifierProvider.autoDispose<HubViewModel, HubViewState>(
  HubViewModel.new,
);

class HubViewModel extends Notifier<HubViewState> {
  late final GetDevicesUseCase _getDevicesUseCase;
  late final GetLatestPositionsUseCase _getLatestPositionsUseCase;

  late final SelectedDeviceNotifier selectedDeviceNotifier;

  late final MapController mapController;

  @override
  HubViewState build() {
    _getDevicesUseCase = ref.read(getDevicesUseCaseProvider);
    _getLatestPositionsUseCase = ref.read(getLatestPositionsUseCaseProvider);

    selectedDeviceNotifier = ref.read(selectedDeviceProvider.notifier);

    mapController = MapControllerImpl();

    ref.read(loggedUserProvider.future)
      .then((loggedUser) {
        state = state.copyWith(loggedUser: loggedUser);
        return _getDevicesUseCase.getDevices(
          userId: loggedUser.id
        );
      }).then((List<DeviceEntity> res){
      state = state.copyWith(
        devices: res,
      );
      setSelectedDevice(res.first);
      return Future.wait(res.map((device) =>
        _getLatestPositionsUseCase.getLatestPositions(
          deviceId: device.identificator
        )
      ));
    }).then(
      (List<List<PositionEntity>> res) {
        setPositions(res);
      }
    );

    ref.onDispose(disposeControllers);

    return HubViewState();
  }

  void setPositions(List<List<PositionEntity>> positions) {
    final devicePositions = positions.map((List<PositionEntity> devicePositions)=>devicePositions[0]).toList();
    final selectedPosition = devicePositions.where((p)=>
      p.deviceIdentificator == state.selectedDevice!.identificator).firstOrNull;
    state = state.copyWith(
      positions: devicePositions,
      selectedPosition: selectedPosition,
    );
    if (selectedPosition != null) {
      mapController.move(LatLng(
        selectedPosition.latitude,
        selectedPosition.longitude,
      ), 15);
    }
  }

  void setSelectedDevice(DeviceEntity device) {
    final selectedPosition = state.positions.where((p)=>
      p.deviceIdentificator == device.identificator).firstOrNull;
    state = state.copyWith(
      selectedDevice: device,
      selectedPosition: selectedPosition,
    );

    selectedDeviceNotifier.setSelectedDevice(device);
  }

  void disposeControllers(){
    mapController.dispose();
  }
}
