import 'package:softplayer_dart_proto/main.dart';
import 'package:softplayer_web/api/grpc/creds.dart';

class EnvironmentLocalData {
  EnvironmentLocalData(
      {required this.serverType,
      required this.serverLocation,
      required this.provider,
      required this.name,
      required this.description,
      this.uuid});

  final String name;
  final String description;
  final String provider;
  final String serverType;
  final String serverLocation;
  String? uuid;
}

class EnvironmentsGrpc {
  // final GrpcWebClientChannel channel;
  final EnvironmentsClient envStub;

  // Init the grpc channel for environments
  EnvironmentsGrpc(channel) : envStub = EnvironmentsClient(channel);

  // Get environments from the API
  Future<EnvironmentLocalData> get(String uuid, SoftplayerCreds creds) async {
    final request = GetOptions(
      id: EnvironmentId(uuid: uuid),
      ownerId: OwnerId(uuid: creds.uuid),
      token: Token(token: creds.token),
    );

    try {
      final response = await envStub.get(request);
      return EnvironmentLocalData(
          uuid: uuid,
          serverType: response.spec.serverType.toString(),
          serverLocation: response.spec.serverLocation.toString(),
          provider: response.spec.provider.toString(),
          name: response.metadata.name,
          description: response.metadata.description);
    } catch (e) {
      rethrow;
    }
  }

  Future<EnvironmentLocalData> create(
      EnvironmentLocalData data, SoftplayerCreds creds) async {
    print(data);
    final request = CreateOptions(
      metadata:
          EnvironmentMetadata(description: data.description, name: data.name),
      spec: EnvironmentSpec(
        // Currently we do not support other kinds
        kubernetes: Kubernetes.KUBERNETES_K3S,
        // Currently we do not support other providers
        provider: Provider.PROVIDER_HETZNER,
        serverLocation: Location.values
            .firstWhere((e) => e.toString() == data.serverLocation),
        serverType: ServerType.values
            .firstWhere((e) => e.toString() == data.serverType),
      ),
      ownerId: OwnerId(uuid: creds.uuid),
      token: Token(token: creds.token),
    );
    try {
      final response = await envStub.create(request);
      return EnvironmentLocalData(
          uuid: response.id.uuid,
          serverType: response.spec.serverType.toString(),
          serverLocation: response.spec.serverLocation.toString(),
          provider: response.spec.provider.toString(),
          name: response.metadata.name,
          description: response.metadata.description);
    } catch (e) {
      rethrow;
    }
  }

  Stream<List<EnvironmentLocalData>> list(SoftplayerCreds creds) async* {
    List<EnvironmentLocalData> envs = [];
    try {
      await for (var feature in envStub.list(
        ListOptions(
          ownerId: OwnerId(uuid: creds.uuid),
          token: Token(token: creds.token),
        ),
      )) {
        envs.add(EnvironmentLocalData(
          uuid: feature.id.uuid,
          serverType: feature.spec.serverType.toString(),
          serverLocation: feature.spec.serverLocation.toString(),
          provider: feature.spec.provider.toString(),
          name: feature.metadata.name,
          description: feature.metadata.description,
        ));
      }
    } catch (e) {
      rethrow;
    }
    yield envs;
  }
}
