import {
  Box,
  Button,
  Checkbox,
  CircularProgress,
  FormControlLabel,
  FormGroup,
  Grid,
  IconButton,
  List,
  ListItem,
  MenuItem,
  TextField,
  Theme,
  Typography,
  useTheme
} from "@mui/material";
import { pond } from "protobuf-ts/pond";
import { useEffect, useState } from "react";
import LogCard from "./LogCard";
import moment from "moment";
import { useDataDogProxyAPI } from "providers";
import { Cell, Legend, Pie, PieChart, ResponsiveContainer } from "recharts";
import { grey, lightBlue, orange, red } from "@mui/material/colors";
import SearchIcon from "@mui/icons-material/Search";
import { makeStyles } from "@mui/styles";

interface DataAmount {
  dataAmount: number;
  name: string;
  color: string;
}

interface Props {
  deviceID?: number;
}

const levelOptions = [
  {
    key: "All",
    val: "all"
  },
  {
    key: "Info",
    val: "info"
  },
  {
    key: "Debug",
    val: "debug"
  },
  {
    key: "Warning",
    val: "warning"
  },
  {
    key: "Error",
    val: "error"
  },
  {
    key: "Critical",
    val: "critical"
  }
];

const sortOptions = [
  {
    key: "Ascending",
    val: "asc"
  },
  {
    key: "Descending",
    val: "desc"
  }
];

const useStyles = makeStyles((theme: Theme) => ({
    sidebox: {
      borderRadius: 5,
      borderColor: theme.palette.text.primary,
      border: "1px solid",
      padding: theme.spacing(1),
      marginRight: theme.spacing(2)
    }
  })
);

export default function LogsDisplay(props: Props) {
  const { deviceID } = props;

  const theme = useTheme();
  const classes = useStyles();

  const [sort, setSort] = useState("desc");
  const [limit, setLimit] = useState(50);
  const [level, setLevel] = useState("all");
  const [service, setService] = useState("all");
  const [logs, setLogs] = useState<pond.Log[]>([]);
  const [loading, setLoading] = useState(false);
  const [device, setDevice] = useState(0);

  const [usage, setUsage] = useState<DataAmount[]>([]);
  const [customQuery, setCustomQuery] = useState<string>("");
  // const [pieLabel, setPieLabel] = useState("");
  // const [pieData, setPieData] = useState("");

  const DDAPI = useDataDogProxyAPI();

  const [from, setFrom] = useState(
    moment()
      .subtract(1, "day")
      .format("YYYY-MM-DD")
  );
  const [to, setTo] = useState(
    moment()
      .add("2", "days")
      .format("YYYY-MM-DD")
  );

  const addToQuery = (query: string, input: string) => {
    if (query.length > 0) query = query + " AND ";
    query = query + input;
    return query;
  };

  const getLogs = () => {
    setLoading(true);
    let query = "";
    if (level !== "all")
      query = addToQuery(query, "@level:(" + level + " OR " + level.toUpperCase() + ")");
    if (deviceID) {
      query = addToQuery(query, "@device:" + deviceID);
    } else if (device > 0) {
      query = addToQuery(query, "@device:" + device);
    }
    if (service !== "all") query = addToQuery(query, "service:" + service);
    setCustomQuery(query);
    DDAPI.listLogs(from, to, sort, limit, query)
      .then(resp => {
        setLogs(resp.data.logs);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const getCustomQuery = () => {
    setLoading(true);
    DDAPI.listLogs(from, to, sort, limit, customQuery)
      .then(resp => {
        setLogs(resp.data.logs);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const titleGrid = () => {
    return (
      <Grid container direction="row" alignItems="center">
        <Grid item xs={2}>
          <TextField
            fullWidth
            variant="outlined"
            label="From:"
            type="date"
            InputLabelProps={{
              shrink: true
            }}
            value={from}
            onChange={e => setFrom(e.target.value)}
          />
        </Grid>
        <Grid item xs={2}>
          <TextField
            fullWidth
            variant="outlined"
            label="To:"
            type="date"
            InputLabelProps={{
              shrink: true
            }}
            value={to}
            onChange={e => setTo(e.target.value)}
          />
        </Grid>
        <Grid item xs={2}>
          <TextField
            fullWidth
            variant="outlined"
            select
            label="level"
            value={level}
            onChange={event => setLevel(event.target.value)}>
            {levelOptions.map(op => (
              <MenuItem key={op.key} value={op.val}>
                {op.key}
              </MenuItem>
            ))}
          </TextField>
        </Grid>
        <Grid item xs>
          <TextField
            fullWidth
            variant="outlined"
            label="Number of Logs:"
            type="number"
            InputLabelProps={{
              shrink: true
            }}
            value={limit}
            onChange={e => setLimit(+e.target.value)}
          />
        </Grid>
        <Grid item xs={2}>
          <TextField
            fullWidth
            variant="outlined"
            select
            label="Sort Order"
            value={sort}
            onChange={event => setSort(event.target.value)}>
            {sortOptions.map(op => (
              <MenuItem key={op.key} value={op.val}>
                {op.key}
              </MenuItem>
            ))}
          </TextField>
        </Grid>
        {!deviceID && (
          <Grid item xs>
            <TextField
              fullWidth
              variant="outlined"
              type="number"
              label="Device"
              value={device}
              onChange={event => setDevice(parseInt(event.target.value))}>
              {sortOptions.map(op => (
                <MenuItem key={op.key} value={op.val}>
                  {op.key}
                </MenuItem>
              ))}
            </TextField>
          </Grid>
        )}
        <Grid item xs style={{ textAlign: "center" }}>
          {loading ? (
            <CircularProgress />
          ) : (
            <Button variant="contained" color="primary" onClick={getLogs}>
              Get Logs
            </Button>
          )}
        </Grid>
      </Grid>
    );
  };

  const endAdornment = () => {
    // if (loading) return <CircularProgress/>
    return (
      <IconButton onClick={getCustomQuery} disabled={loading}>
        <SearchIcon />
      </IconButton>
    );
  };

  const searchBar = () => {
    return (
      <Grid container direction="row" alignItems="center" style={{ marginTop: theme.spacing(1) }}>
        <Grid item xs>
          <TextField
            fullWidth
            variant="outlined"
            label="Query:"
            InputLabelProps={{
              shrink: true
            }}
            InputProps={{ endAdornment: endAdornment() }}
            value={customQuery}
            onChange={e => setCustomQuery(e.target.value)}
            onKeyPress={e => {
              if (e.key === "Enter" && !loading) {
                getCustomQuery();
              }
            }}
          />
        </Grid>
      </Grid>
    );
  };

  useEffect(() => {
    if (logs.length < 1) {
      let data = { dataAmount: 100, name: "Dummy", color: theme.palette.background.paper };
      setUsage([data]);
      return;
    }

    let debugData = { dataAmount: 0, name: "Debug", color: grey[500] };
    let infoData = { dataAmount: 0, name: "Info", color: lightBlue[200] };
    let warningData = { dataAmount: 0, name: "Warning", color: orange[500] };
    let errorData = { dataAmount: 0, name: "Error", color: red[500] };
    let criticalData = { dataAmount: 0, name: "Critical", color: red["A100"] };
    logs.forEach(log => {
      switch (log.level.toLowerCase()) {
        case "debug":
          debugData.dataAmount++;
          break;
        case "info":
          infoData.dataAmount++;
          break;
        case "warning":
          warningData.dataAmount++;
          break;
        case "error":
          errorData.dataAmount++;
          break;
        case "critical":
          criticalData.dataAmount++;
          break;
      }
    });
    setUsage([debugData, infoData, warningData, errorData, criticalData]);
  }, [logs, theme.palette.background.paper]);

  const logPieChart = () => {
    return (
      <Box width={"100%"} style={{ aspectRatio: "1" }} padding={2} paddingLeft={1}>
        <ResponsiveContainer>
          <PieChart>
            <Legend
              verticalAlign="middle"
              content={() => (
                <Box textAlign="center" marginY={0.5}>
                  {/* <Typography>
                    hi
                  </Typography> */}
                  {logs.length < 1 && <Typography>No Logs</Typography>}
                  {/* {device.status.bytesTimestamp.length > 1 && (
                    <Typography>{pieData}</Typography>
                  )} */}
                </Box>
              )}
            />
            <Pie
              data={usage}
              dataKey="dataAmount"
              nameKey="name"
              innerRadius={0}
              cx="50%"
              cy="50%"
              outerRadius={"100%"}
              stroke="none"
              //cornerRadius={6}
            >
              {usage.map((entry, index) => (
                <Cell
                  key={`cell-${index}`}
                  fill={entry.color}
                  style={{ outline: "none !important" }}
                  onMouseOver={() => {
                    // setPieLabel(entry.name);
                    // setPieData(entry.dataAmount.toString());
                  }}
                />
              ))}
            </Pie>
          </PieChart>
        </ResponsiveContainer>
      </Box>
    );
  };

  // const check = (label: string) => {
  //   if (service === label) {
  //     setService("all");
  //   } else {
  //     setService(label);
  //   }
  // };

  const serviceSelector = () => {
    return (
      <Box className={classes.sidebox} padding={2} marginTop={1}>
        <Typography>Service</Typography>
        <FormGroup aria-label="position">
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "all"}
                onChange={() => setService("all")}
              />
            }
            label="all"
            labelPlacement="end"
          />
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "pond"}
                onChange={() => setService("pond")}
              />
            }
            label="pond"
            labelPlacement="end"
          />
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "quay"}
                onChange={() => setService("quay")}
              />
            }
            label="quay"
            labelPlacement="end"
          />
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "traefik"}
                onChange={() => setService("traefik")}
              />
            }
            label="traefik"
            labelPlacement="end"
          />
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "webui"}
                onChange={() => setService("webui")}
              />
            }
            label="webui"
            labelPlacement="end"
          />
          <FormControlLabel
            // value="end"
            control={
              <Checkbox
                color="primary"
                checked={service === "agent"}
                onChange={() => setService("agent")}
              />
            }
            label="agent"
            labelPlacement="end"
          />
        </FormGroup>
      </Box>
    );
  };

  const getPercent = (dataNum: number) => {
    if (logs.length < 1 || logs.length < dataNum) return 0 + "%";
    let newNum = (dataNum / logs.length) * 100;
    return newNum.toFixed(0) + "%";
  };

  const logLevels = () => {
    let debugNum = 0;
    let infoNum = 0;
    let warningNum = 0;
    let errorNum = 0;
    let criticalNum = 0;
    usage.forEach(data => {
      switch (data.name) {
        case "Debug":
          debugNum = data.dataAmount;
          break;
        case "Info":
          infoNum = data.dataAmount;
          break;
        case "Warning":
          warningNum = data.dataAmount;
          break;
        case "Error":
          errorNum = data.dataAmount;
          break;
        case "Critical":
          criticalNum = data.dataAmount;
          break;
      }
    });
    return (
      <Box className={classes.sidebox}>
        <List dense>
          <ListItem style={{ display: "flex", float: "left" }}>
            <Typography style={{ color: lightBlue[400] }}>■</Typography>
            <Typography variant="caption" style={{ marginLeft: theme.spacing(1) }}>
              Info: {infoNum}
            </Typography>
            <Typography variant="caption" style={{ marginLeft: "auto" }}>
              ({getPercent(infoNum)})
            </Typography>
          </ListItem>
          <ListItem>
            <Typography style={{ color: grey[500] }}>■</Typography>
            <Typography variant="caption" style={{ marginLeft: theme.spacing(1) }}>
              Debug: {debugNum}
            </Typography>
            <Typography variant="caption" style={{ marginLeft: "auto" }}>
              ({getPercent(debugNum)})
            </Typography>
          </ListItem>
          <ListItem>
            <Typography style={{ color: orange[500] }}>■</Typography>
            <Typography variant="caption" style={{ marginLeft: theme.spacing(1) }}>
              Warning: {warningNum}
            </Typography>
            <Typography variant="caption" style={{ marginLeft: "auto" }}>
              ({getPercent(warningNum)})
            </Typography>
          </ListItem>
          <ListItem>
            <Typography style={{ color: red[500] }}>■</Typography>
            <Typography variant="caption" style={{ marginLeft: theme.spacing(1) }}>
              Error: {errorNum}
            </Typography>
            <Typography variant="caption" align="right" style={{ marginLeft: "auto" }}>
              ({getPercent(errorNum)})
            </Typography>
          </ListItem>
          <ListItem>
            <Typography style={{ color: red[900] }}>■</Typography>
            <Typography variant="caption" style={{ marginLeft: theme.spacing(1) }}>
              Critical: {criticalNum}
            </Typography>
            <Typography variant="caption" style={{ marginLeft: "auto" }}>
              ({getPercent(criticalNum)})
            </Typography>
          </ListItem>
        </List>
      </Box>
    );
  };

  return (
    <Box style={{ display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }}>
      {/* Title Section */}
      <Box margin={2}>
        {titleGrid()}
        {searchBar()}
      </Box>

      {/* Header Section */}
      <Grid container style={{ height: "100%" }}>
        <Grid item xs={2}>
          <Typography>Log Metrics</Typography>
          {/* Pie chart and service selector will go here */}
          {logPieChart()}
          {logLevels()}
          {/* <br /> */}
          {serviceSelector()}
        </Grid>
        <Grid item xs={10} style={{ height: "100%", overflow: "hidden" }}>
          <Grid container direction="row" justifyContent="space-around" alignItems="center">
            <Grid item xs={2.2}>
              Timestamp
            </Grid>
            <Grid item xs={1}>
              Service
            </Grid>
            <Grid item xs={1}>
              Device
            </Grid>
            <Grid item xs={2}>
              Message
            </Grid>
            <Grid item xs zeroMinWidth>
              Content
            </Grid>
          </Grid>

          {/* Scrollable List Section */}
          <Box
            style={{
              height: "100%",
              overflowY: "auto",
              textAlign: logs.length < 1 ? "center" : "left"
            }}>
            {logs.map((l, i) => (
              <LogCard key={i} datalog={l} index={i} />
            ))}
            {logs.length < 1 && (
              <Typography
                variant="body1"
                color="textSecondary"
                style={{ marginTop: theme.spacing(12), alignSelf: "center" }}>
                Found logs will be displayed here
              </Typography>
            )}
          </Box>
        </Grid>
      </Grid>
    </Box>
  );
}
