import 'dart:collection';

import 'package:flutter/material.dart';
//import 'package:grpc/grpc_web.dart';
import 'package:grpc/grpc.dart';
import 'package:logger/logger.dart';
import 'package:ui/call.dart';
import 'package:ui/gen/signaler_service.pbgrpc.dart';
import 'package:ui/session_service.dart';

void main() async {
  Logger logger = Logger();
  logger.i("Establishing connection...");
  final channel = ClientChannel(
    'home.chathaway.codes',
    //port: 8080,
    //options: const ChannelOptions(credentials: ChannelCredentials.insecure()),
    channelShutdownHandler: () {
      logger.e("Channel shutdown unexpectedly");
    },
  );
  logger.i("Have connection, making stub");
  final stub = SignalerServiceClient(channel);
  final sessionService = SessionService(stub);
  logger.i("Have stub, starting app");
  runApp(MyApp(
    stub,
    sessionService,
  ));
}

class MyApp extends StatelessWidget {
  final SignalerServiceClient client;
  final SessionService sessionService;
  const MyApp(this.client, this.sessionService, {super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Home Sensors',
      theme: ThemeData.dark(
        // colorScheme: ColorScheme.fromSeed(seedColor: Colors.black87),
        useMaterial3: true,
      ),
      home: MyHomePage(
        client,
        sessionService,
        title: 'Home Sensors',
        home: "Sunnyvale",
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final SignalerServiceClient client;
  final SessionService sessionService;
  final String home;
  const MyHomePage(this.client, this.sessionService,
      {super.key, required this.title, required this.home});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String topMessage = "Creating session...";
  List<Widget> camerasToRender = [];
  Map<String, Widget> cameraSamples = {};

  @override
  void initState() {
    super.initState();
    _getSession();
    _listCameras();
    _listSensors();
  }

  _getSession() async {
    var token = await widget.sessionService.getAuthToken(widget.home);
    topMessage = "Created session $token";
    setState(() {});
  }

  _listSensors() async {
    var callOptions = CallOptions(metadata: {
      'Authorization': await widget.sessionService.getAuthToken(widget.home)
    });
    var resp = await widget.client
        .listSamples(ListSamplesRequest(), options: callOptions);

    for (var sample in resp.samples) {
      if (sample.type == Sample_Type.TEMPERATURE_C) {
        var reading = (sample.reading * 9.0 / 5.0) + 32;
        cameraSamples[sample.cameraId.id] =
            Text("${reading.toStringAsFixed(2)} f");
      }
    }
    setState(() {});
  }

  _listCameras() async {
    var callOptions = CallOptions(metadata: {
      'Authorization': await widget.sessionService.getAuthToken(widget.home)
    });
    var cameras = await widget.client
        .listCameras(ListCamerasRequest(), options: callOptions);

    cameras.cameras.sort((a, b) => a.identifier.id.compareTo(b.identifier.id));
    camerasToRender = [];
    for (var camera in cameras.cameras) {
      List<Widget> children = [
        Call(
          widget.client,
          widget.sessionService,
          cameraID: camera.identifier,
          home: widget.home,
        ),
      ];
      if (cameraSamples.containsKey(camera.identifier.id)) {
        children.add(cameraSamples[camera.identifier.id]!);
      }
      camerasToRender.add(Column(
        children: children,
      ));
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text(widget.title),
        ),
        body: SingleChildScrollView(
          child: Column(
            // Center is a layout widget. It takes a single child and positions it
            // in the middle of the parent.

            children: <Widget>[
                  Text(topMessage),
                ] +
                camerasToRender,
          ),
        ));
  }
}
