import {
  Box,
  Grid2 as Grid,
  LinearProgress,
  Typography,
} from "@mui/material";
import { useState } from "react";
import OpenWeatherMap from "openweathermap-ts";
import { CurrentResponse, ThreeHourResponse } from "openweathermap-ts/dist/types";
import { useEffect } from "react";
import WeatherIcon from "./weatherIcon";
import { getThemeType } from "theme";
import { useMobile, useThemeType } from "hooks";
import WindSpeedDark from "assets/components/windSpeedDark.png";
import WindSpeedLight from "assets/components/windSpeedLight.png";
import { makeStyles } from "@mui/styles";
//import { WiHumidity } from "weather-icons-react";

const openWeather = new OpenWeatherMap({
  //apiKey: process.env.REACT_APP_OPEN_WEATHERMAP ? process.env.REACT_APP_OPEN_WEATHERMAP : ""
  apiKey: import.meta.env.VITE_OPEN_WEATHERMAP ? import.meta.env.VITE_OPEN_WEATHERMAP : ""
});

interface Props {
  longitude?: number;
  latitude?: number;
}

const useStyles = makeStyles(() => ({
    currentBox: {
      boxShadow: "0px 0px 10px black",
      height: "110px",
      borderRadius: 10,
      margin: 7
    },
    upperSquare: {
      height: "75%",
      display: "flex",
      justifyContent: "center",
      alignItems: "center"
    },
    lowerSquare: {
      height: "25%",
      display: "flex",
      justifyContent: "center",
      alignItems: "center"
    },
    dark: {
      backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(50, 50, 50)",
      padding: 5,
      opacity: 1
    },
    light: {
      backgroundColor: getThemeType() === "light" ? "rgb(235, 235, 235)" : "rgb(60, 60, 60)",
      padding: 5,
      opacity: 1
    }
}))

export default function Weather(props: Props) {
  const [currentConditions, setCurrentConditions] = useState<CurrentResponse>();
  const [forecast, setForecast] = useState<ThreeHourResponse>();
  const classes = useStyles();
  const isMobile = useMobile();
  const themeType = useThemeType();

  useEffect(() => {
    if (props.longitude && props.latitude) {
      openWeather
        .getThreeHourForecastByGeoCoordinates(props.latitude, props.longitude)
        .then(forecast => {
          setForecast(forecast);
        });
      openWeather
        .getCurrentWeatherByGeoCoordinates(props.latitude, props.longitude)
        .then(weather => {
          setCurrentConditions(weather);
        });
    }
  }, [props.latitude, props.longitude]);

  const celsiusConverter = (temp: number) => {
    return (temp - 32) * (5 / 9);
  };

  /**
   * gets the high and low of the first 8 readings in the 5 day forecast, is technically getting the high and low for tomorrow
   * but is usually close to the same temperatures, for actual current high/low must use a paid plan for open weather
   * @returns
   */
  const getHighLow = () => {
    if (!forecast) return;
    let loopCounter = 0;
    let currentHigh = -1000;
    let currentLow = 1000;
    while (loopCounter <= 7) {
      let temp = forecast.list[loopCounter].main.temp;
      if (temp < currentLow) {
        currentLow = temp;
      }
      if (temp > currentHigh) {
        currentHigh = temp;
      }
      loopCounter++;
    }
    return (
      <Typography variant="h5" style={{ fontSize: 25 }}>
        {Math.round(celsiusConverter(currentHigh))}&#176; /{" "}
        {Math.round(celsiusConverter(currentLow))}&#176;
      </Typography>
    );
  };

  const getDirection = (current: CurrentResponse) => {
    if (!current) return;
    let windDegrees = current.wind.deg;
    let direction = "";

    if (windDegrees > 338 || windDegrees <= 23) {
      direction = "N";
    }
    if (windDegrees > 23 && windDegrees <= 67) {
      direction = "NE";
    }
    if (windDegrees > 67 && windDegrees <= 112) {
      direction = "E";
    }
    if (windDegrees > 112 && windDegrees <= 158) {
      direction = "SE";
    }
    if (windDegrees > 158 && windDegrees <= 203) {
      direction = "S";
    }
    if (windDegrees > 203 && windDegrees <= 248) {
      direction = "SW";
    }
    if (windDegrees > 248 && windDegrees <= 293) {
      direction = "W";
    }
    if (windDegrees > 293 && windDegrees <= 338) {
      direction = "NW";
    }
    return direction;
  };

  const dayOfWeek = (day: number) => {
    switch (day) {
      case 1:
        return "Monday";
      case 2:
        return "Tuesday";
      case 3:
        return "Wednesday";
      case 4:
        return "Thursday";
      case 5:
        return "Friday";
      case 6:
        return "Saturday";
      default:
        return "Sunday";
    }
  };

  /**
   * Three hour response contains a list of 40 items for the weather, each 8 is a 24 hour period
   * loop through 8 items to get the forecast for that 24 hour period
   * @param forecast the three hour response that was retrieved
   * @param day the day we are getting the forecast for as a number
   */
  const getForeCast = (day: number) => {
    if (!forecast) return;
    let startingPoint = day * 8;
    let loopCount = 0;
    let high = -1000;
    let low = 1000;
    let d = forecast.list[startingPoint + 4].dt;
    let date = new Date(0);
    date.setUTCSeconds(d);

    while (loopCount < 8) {
      let temp = forecast.list[startingPoint].main.temp;
      if (temp > high) {
        high = temp;
      }
      if (temp < low) {
        low = temp;
      }
      startingPoint++;
      loopCount++;
    }

    return (
      <Box className={day % 2 === 0 ? classes.dark : classes.light}>
        <Box style={{ display: "flex", justifyContent: "space-between" }}>
          <Typography variant="subtitle1" style={{ fontWeight: 600 }}>
            {dayOfWeek(date.getDay())}
          </Typography>
          <Typography variant="subtitle1" style={{ fontWeight: 600 }}>
            {Math.round(celsiusConverter(high))}&#176; / {Math.round(celsiusConverter(low))}&#176;
          </Typography>
        </Box>
      </Box>
    );
  };

  return (
    <Box padding="25px">
      {currentConditions && forecast ? (
        <Box>
          <Box component="span">
            <Typography style={{ fontSize: 20, fontWeight: 750 }}>
              Current Weather - {dayOfWeek(new Date().getDay())}
            </Typography>
          </Box>
          <Grid container direction="row">
            <Grid size={6}>
              <Box className={classes.currentBox}>
                <Box
                  padding="5%"
                  className={classes.upperSquare}
                  style={{ flexDirection: isMobile ? "column" : "row" }}>
                  <WeatherIcon
                    openweatherIconId={currentConditions.weather[0].id}
                    size={isMobile ? 35 : 50}
                  />
                  <Typography variant="body1" style={{ fontSize: 25 }}>
                    {Math.round(celsiusConverter(currentConditions.main.temp))}&#8451;
                  </Typography>
                </Box>
                <Box className={classes.lowerSquare}>
                  <Typography variant="subtitle1" style={{ fontSize: isMobile ? 10 : 15 }}>
                    Feels like {Math.round(celsiusConverter(currentConditions.main.feels_like))}
                    &#8451;
                  </Typography>
                </Box>
              </Box>
            </Grid>
            <Grid size={6}>
              <Box className={classes.currentBox}>
                <Box
                  className={classes.upperSquare}
                  style={{ flexDirection: isMobile ? "column" : "row" }}>
                  {/* <WiHumidity size={isMobile ? 35 : 50} /> */}
                  <Typography variant="body1" style={{ fontSize: 25, display: "inline" }}>
                    {currentConditions.main.humidity}%
                  </Typography>
                </Box>
                <Box className={classes.lowerSquare}>
                  <Typography variant="subtitle1" style={{ fontSize: isMobile ? 10 : 15 }}>
                    Humidity
                  </Typography>
                </Box>
              </Box>
            </Grid>
            <Grid size={6}>
              <Box className={classes.currentBox}>
                <Box
                  className={classes.upperSquare}
                  style={{ flexDirection: isMobile ? "column" : "row" }}>
                  <img
                    src={themeType === "light" ? WindSpeedDark : WindSpeedLight}
                    alt="Wind Speed"
                    height={isMobile ? 35 : 50}
                    width={isMobile ? 35 : 50}
                  />
                  <Box>
                    <Typography variant="body1" style={{ fontSize: 25, display: "inline" }}>
                      {Math.round(currentConditions.wind.speed * 3.6)}/
                    </Typography>
                    <Typography variant="subtitle1" style={{ fontSize: 15, display: "inline" }}>
                      km/h
                    </Typography>
                  </Box>
                </Box>
                <Box className={classes.lowerSquare}>
                  <Typography variant="subtitle1" style={{ fontSize: isMobile ? 10 : 15 }}>
                    Direction {getDirection(currentConditions)}
                  </Typography>
                </Box>
              </Box>
            </Grid>
            <Grid size={6}>
              <Box className={classes.currentBox}>
                <Box className={classes.upperSquare} style={{ paddingTop: isMobile ? 35 : 0 }}>
                  {getHighLow()}
                </Box>
                <Box className={classes.lowerSquare}>
                  <Typography variant="subtitle1" style={{ fontSize: isMobile ? 10 : 15 }}>
                    Today's High/Low
                  </Typography>
                </Box>
              </Box>
            </Grid>
          </Grid>
          <Box component="span">
            <Typography style={{ fontSize: 20, fontWeight: 750 }}>5 - Day Forecast</Typography>
          </Box>
          <Box>
            {getForeCast(0)}
            {getForeCast(1)}
            {getForeCast(2)}
            {getForeCast(3)}
            {getForeCast(4)}
          </Box>
        </Box>
      ) : (
        <Box paddingTop="20px">
          <LinearProgress color="primary" />
        </Box>
      )}
    </Box>
  );
}
