import {
  AreaChartData,
  ComponentTypeExtension,
  GraphFilters,
  LineChartData,
  simpleAreaChartData,
  simpleLineChartData,
  Summary,
  unitMeasurementSummaries
} from "pbHelpers/ComponentType";
import { quack } from "protobuf-ts/quack";
import { or } from "utils/types";
import { geolocate } from "services/google/googleAPI";
// @ts-ignore
import { parseGPS } from "services/google/mapHelpers";
import { convertedUnitMeasurement } from "models/UnitMeasurement";
import { pond } from "protobuf-ts/pond";

export function GPS(subtype: number = 0): ComponentTypeExtension {
  return {
    type: quack.ComponentType.COMPONENT_TYPE_GPS,
    subtypes: [],
    friendlyName: "GPS",
    description: "Measures the location of a device",
    isController: false,
    isSource: false,
    isCalibratable: false,
    addressTypes: [quack.AddressType.ADDRESS_TYPE_GPS],
    interactionResultTypes: [],
    states: [],
    measurements: [],
    measurementSummary: async function(measurement: quack.Measurement): Promise<Array<Summary>> {
      return new Promise(function(resolve, reject) {
        let summary: Array<Summary> = [];
        const { request, lat, lng } = parseGPS(measurement.gps);
        if (request !== undefined) {
          geolocate(request)
            .then((response: any) => {
              let lat = or(response.data.location.lat, 0);
              let lng = or(response.data.location.lng, 0);
              summary.push({
                label: "Latitude",
                value: lat.toFixed(7).toString(),
                colour: ""
              } as Summary);

              summary.push({
                label: "Longitude",
                value: lng.toFixed(7).toString(),
                colour: ""
              } as Summary);

              return resolve(summary);
            })
            .catch((error: any) => {
              return reject();
            });
        } else {
          summary.push({
            label: "Latitude",
            value: lat.toFixed(7).toString(),
            colour: ""
          } as Summary);

          summary.push({
            label: "Longitude",
            value: lng.toFixed(7).toString(),
            colour: ""
          } as Summary);

          return resolve(summary);
        }
      });
    },
    unitMeasurementSummary: (
      measurements: convertedUnitMeasurement,
    ): Summary[] => {
      return unitMeasurementSummaries(
        measurements,
        quack.ComponentType.COMPONENT_TYPE_GPS,
        subtype,
      );
    },
    areaChartData: (
      measurement: pond.UnitMeasurementsForComponent,
      smoothingAverages?: number,
      filters?: GraphFilters
    ): AreaChartData => {
      return simpleAreaChartData(measurement, smoothingAverages, filters);
    },
    lineChartData: (
      measurement: pond.UnitMeasurementsForComponent,
      smoothingAverages?: number,
      filters?: GraphFilters
    ): LineChartData => {
      return simpleLineChartData(
        quack.ComponentType.COMPONENT_TYPE_GPS,
        measurement,
        smoothingAverages,
        filters
      );
    },
    minMeasurementPeriodMs: 1000
  };
}
