import React from "react";
import BufrChart from "../Bufr/BufrChart";
import { Query, ApolloProvider } from "react-apollo";

import moment from "moment";
import ApolloClient from "apollo-boost";
import ReactLoading from "react-loading";
import gql from "graphql-tag";
import * as color from "../Bufr/color-utils";

const BUFR_SLICE_QUERY = gql`
  query($token: String!, $at: DateTime, $dataType: String!, $line: [Float]!) {
    bufrSlice(
      token: $token

      dataType: $dataType
      line: $line
      at: $at
    ) {
      station {
        id
        name
      }
      slice {
        rows {
          data
          height1
          height2
        }
        ordinates
      }
    }
  }
`;
function measure(lat1, lon1, lat2, lon2) {
  // generally used geo measurement function
  var R = 6378.137; // Radius of earth in KM
  var dLat = (lat2 * Math.PI) / 180 - (lat1 * Math.PI) / 180;
  var dLon = (lon2 * Math.PI) / 180 - (lon1 * Math.PI) / 180;
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos((lat1 * Math.PI) / 180) *
      Math.cos((lat2 * Math.PI) / 180) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c;
  return d; // meters
}

class BufrChartGen extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      token: this.props.token,
      dataType: this.props.dataType,
      line: this.props.line,
      at: this.props.time
        ? moment(this.props.time).format("YYYY-MM-DDTHH:mm:ss")
        : moment().format("YYYY-MM-DDTHH:mm:ss"),
    };
    this.deep = true;
    this.apollo = new ApolloClient({
      uri: this.props.client,
    });
  }
  componentDidUpdate() {
    if (this.state.line !== this.props.line) {
      this.setState({ line: this.props.line });
    }
    if (this.state.dataType !== this.props.dataType) {
      this.setState({ dataType: this.props.dataType });
    }
    if (
      this.state.at !== moment(this.props.time).format("YYYY-MM-DDTHH:mm:ss")
    ) {
      this.setState({
        at: moment(this.props.time).format("YYYY-MM-DDTHH:mm:ss"),
      });
    }
  }
  render() {
    const variables = {
      token: this.state.token,
      dataType: this.state.dataType,
      line: this.state.line,
      at: this.state.at
        ? moment(this.state.at).format("YYYY-MM-DDTHH:mm:ss")
        : moment().format("YYYY-MM-DDTHH:mm:ss"),
    };

    return (
      <ApolloProvider client={this.apollo}>
        <div className="bufrGraph" style={{ width: "100%", height: "100%" }}>
          <Query
            query={BUFR_SLICE_QUERY}
            variables={variables}
            partialRefetch={true}
          >
            {({ loading, error, data: plotdata, refetch, client }) => {
              if (loading)
                return (
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "center",
                      alignContent: "center",
                      alignItems: "center",

                      flexDirection: "column",
                      fontSize: "17px",
                      height: "100%",
                    }}
                  >
                    <ReactLoading
                      type="balls"
                      color="#333333"
                      height={25}
                      width={50}
                    />{" "}
                    <p> Загрузка графиков </p>
                  </div>
                );
              if (error) return setTimeout(() => refetch(), 5000);

              if (plotdata) {
                let ignoreBounds = this.props.getIgnoreBufrs(
                  this.props.dataType
                ) || [-100, 100000];
                let data = plotdata.bufrSlice.map((st) =>
                  st.slice.rows.map((row) =>
                    row.data.map((d, d_indx) => ({
                      // x: +(st.slice.ordinates[d_indx + 1] * 1000).toFixed(3),
                      // x0: +(st.slice.ordinates[d_indx] * 1000).toFixed(3),
                      x0: measure(
                        st.slice.ordinates[0],
                        st.slice.ordinates[1],
                        st.slice.ordinates[d_indx * 2],
                        st.slice.ordinates[d_indx * 2 + 1]
                      ),
                      x: measure(
                        st.slice.ordinates[0],
                        st.slice.ordinates[1],
                        st.slice.ordinates[(d_indx + 1) * 2],
                        st.slice.ordinates[(d_indx + 1) * 2 + 1]
                      ),

                      y:
                        row.height2 == 0
                          ? color.getHeightlessElevation(d, this.props.dataType)
                          : row.height2,
                      y0: row.height1 == -1 ? 0 : row.height1,
                      color: this.props.getColorByType
                        ? this.props.getColorByType(
                            this.props.dataType,
                            d,
                            "hex"
                          )
                        : color.getColorByType(this.props.dataType, d),

                      opacity:
                        d >= ignoreBounds[0] && d <= ignoreBounds[1] ? 1 : 0,

                      valu: d,
                      measure: color.getMeasureByType(this.props.dataType),
                    }))
                  )
                );
                let stations = plotdata.bufrSlice.map((d, indx) => ({
                  title: d.station.name,
                  index: indx,
                }));

                let fulldata = [];
                data.forEach((d, indx) =>
                  d.forEach((s) => {
                    if (!fulldata[indx]) fulldata[indx] = [];
                    fulldata[indx] = fulldata[indx].concat(s);
                  })
                );

                return (
                  <BufrChart
                    opacity={this.props.opacity}
                    superArr={fulldata}
                    stations={stations}
                    dataType={this.props.dataType}
                    line={variables.line}
                    getBufrTranlation={this.props.getBufrTranlation}
                    isBufrWithHeight={this.props.isBufrWithHeight}
                    //   plotHeight={150}
                  />
                );
                return null;
              }
            }}
          </Query>
        </div>{" "}
      </ApolloProvider>
    );
  }
}

export default BufrChartGen;
