import React, { useState, useEffect } from "react";
import {
  Box,
  Typography,
  Paper,
  TextField,
  Button,
  Tooltip,
  IconButton,
  Alert,
  Stack,
  Divider,
} from "@mui/material";
import {
  Search as SearchIcon,
  DataObject as DataObjectIcon,
  Output as OutputIcon,
  UploadFile as UploadFileIcon,
  FileOpen as FileOpenIcon,
  Restore as RestoreIcon,
  FormatAlignLeft as FormatAlignLeftIcon,
  Clear as ClearIcon,
  ContentCopy as ContentCopyIcon,
  Download as DownloadIcon,
  Check as CheckIcon,
  Refresh as RefreshIcon,
} from "@mui/icons-material";
import Grid from "@mui/material/Grid";
import jmespath from "jmespath";

function MainPage({
  showReloadButton,
  onReloadSampleData,
  jmespathExpression,
  setJmespathExpression,
  jsonData,
  setJsonData,
}) {
  const [result, setResult] = useState("");
  const [error, setError] = useState("");
  const [jsonError, setJsonError] = useState("");
  const [copySuccess, setCopySuccess] = useState(false);

  const evaluateExpression = () => {
    try {
      // Clear previous errors
      setError("");
      setJsonError("");

      // Validate and parse JSON
      let parsedData;
      try {
        parsedData = JSON.parse(jsonData);
      } catch (jsonErr) {
        setJsonError(`Invalid JSON: ${jsonErr.message}`);
        setResult("");
        return;
      }

      // Evaluate JMESPath expression
      const queryResult = jmespath.search(parsedData, jmespathExpression);

      // Format the result
      if (queryResult === null || queryResult === undefined) {
        setResult("null");
      } else {
        setResult(JSON.stringify(queryResult, null, 2));
      }
    } catch (jmesErr) {
      setError(`JMESPath Error: ${jmesErr.message}`);
      setResult("");
    }
  };

  // Auto-evaluate when inputs change
  useEffect(() => {
    if (jmespathExpression && jsonData) {
      evaluateExpression();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [jmespathExpression, jsonData]);

  const handleJmespathChange = (e) => {
    setJmespathExpression(e.target.value);
  };

  const handleJsonChange = (e) => {
    setJsonData(e.target.value);
  };

  const formatJson = () => {
    try {
      const parsed = JSON.parse(jsonData);
      setJsonData(JSON.stringify(parsed, null, 2));
    } catch (err) {
      // If JSON is invalid, don't format
    }
  };

  const clearAll = () => {
    setJmespathExpression("");
    setJsonData("");
    setResult("");
    setError("");
    setJsonError("");
  };

  const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(result);
      setCopySuccess(true);
      setTimeout(() => setCopySuccess(false), 2000);
    } catch (err) {
      console.error("Failed to copy!", err);
    }
  };

  const downloadResult = () => {
    const blob = new Blob([result], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "result.json";
    a.click();
    URL.revokeObjectURL(url);
  };

  const loadSample = () => {
    const sampleData = {
      users: [
        { name: "Alice", age: 30, city: "New York" },
        { name: "Bob", age: 25, city: "San Francisco" },
        { name: "Charlie", age: 35, city: "Chicago" },
      ],
      total: 3,
    };
    setJsonData(JSON.stringify(sampleData, null, 2));
    setJmespathExpression("users[?age > `30`].name");
  };

  const loadFromDisk = () => {
    const input = document.createElement("input");
    input.type = "file";
    input.accept = ".json";
    input.onchange = (e) => {
      const file = e.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (e) => {
          try {
            const content = e.target.result;
            const parsed = JSON.parse(content);
            setJsonData(JSON.stringify(parsed, null, 2));
          } catch (error) {
            alert("Invalid JSON file");
          }
        };
        reader.readAsText(file);
      }
    };
    input.click();
  };

  const loadLogFile = () => {
    const input = document.createElement("input");
    input.type = "file";
    input.accept = ".log,.jsonl,.ndjson";
    input.onchange = (e) => {
      const file = e.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (e) => {
          try {
            const content = e.target.result;
            const lines = content.trim().split("\n");
            const logs = lines.map((line) => JSON.parse(line));
            setJsonData(JSON.stringify(logs, null, 2));
            setJmespathExpression("[*].message");
          } catch (error) {
            alert("Invalid JSON Lines file");
          }
        };
        reader.readAsText(file);
      }
    };
    input.click();
  };

  return (
    <Box
      sx={{
        flexGrow: 1,
        pt: 1,
        pb: 3,
        px: { xs: 2, md: 4 },
        display: "flex",
        flexDirection: "column",
        minHeight: 0,
        overflow: "hidden",
      }}
    >
      <Box sx={{ mb: 2, flexShrink: 0 }}>
        <Typography
          variant="body2"
          color="text.secondary"
          align="left"
          mt="1rem"
        >
          Validate and test JMESPath expressions against JSON data in real-time.
          Enter your JMESPath query and JSON data below to see the results
          instantly.
        </Typography>
      </Box>

      <Paper
        sx={{
          flexShrink: 0,
          bgcolor: "background.paper",
          border: 1,
          borderColor: "divider",
          overflow: "hidden",
          mb: 2
        }}
      >
        <Box
          sx={{
            px: 2,
            py: 1,
            bgcolor: "action.hover",
            borderBottom: 1,
            borderColor: "divider",
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
          }}
        >
          <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
            <SearchIcon sx={{ fontSize: 20 }} color="primary" />
            <Typography variant="subtitle2" color="text.primary">
              JMESPath Expression
            </Typography>
          </Box>
        </Box>
        <Box sx={{ p: 1.5, mt: 0.5 }}>
          <TextField
            fullWidth
            size="small"
            placeholder="Enter JMESPath expression (e.g., people[*].name)"
            value={jmespathExpression}
            onChange={handleJmespathChange}
            error={!!error}
            helperText={error || " "}
            sx={{
              "& .MuiInputBase-root": {
                fontFamily: "'Noto Sans Mono', monospace",
                fontSize: "0.9rem",
              },
              "& .MuiFormHelperText-root": {
                mt: 0.75,
                mb: -0.5,
              },
            }}
          />
        </Box>
      </Paper>

      <Grid container spacing={3} sx={{ flex: "1 1 0", minHeight: 0, height: 0 }}>
        <Grid size={{ xs: 12, md: 6 }} sx={{ display: "flex", flexDirection: "column", minHeight: 0 }}>
          <Paper
            sx={{
              flexGrow: 1,
              display: "flex",
              flexDirection: "column",
              overflow: "hidden",
              bgcolor: "background.paper",
              border: 1,
              borderColor: "divider",
              minHeight: 0,
            }}
          >
            <Box
              sx={{
                px: 2,
                py: 1,
                bgcolor: "action.hover",
                borderBottom: 1,
                borderColor: "divider",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
              }}
            >
              <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                <DataObjectIcon sx={{ fontSize: 20 }} color="primary" />
                <Typography variant="subtitle2" color="text.primary">
                  JSON Input
                </Typography>
                {showReloadButton && (
                  <Button
                    variant="contained"
                    color="secondary"
                    onClick={onReloadSampleData}
                    startIcon={<RefreshIcon fontSize="inherit" />}
                    size="small"
                    sx={{
                      ml: 1,
                      px: 1,
                      py: 0.25,
                      fontSize: "0.65rem",
                      textTransform: "none",
                      whiteSpace: "nowrap",
                      minWidth: "auto",
                    }}
                  >
                    Reload data
                  </Button>
                )}
              </Box>
              <Stack direction="row" spacing={1} alignItems="center">
                <Tooltip title="Load from Disk">
                  <IconButton
                    size="small"
                    onClick={loadFromDisk}
                    color="primary"
                    aria-label="Load from Disk"
                  >
                    <FileOpenIcon fontSize="small" />
                  </IconButton>
                </Tooltip>
                <Tooltip title="Load Logs">
                  <IconButton
                    size="small"
                    onClick={loadLogFile}
                    color="primary"
                    aria-label="Load Logs"
                  >
                    <UploadFileIcon fontSize="small" />
                  </IconButton>
                </Tooltip>
                <Tooltip title="Load Sample">
                  <IconButton
                    size="small"
                    onClick={loadSample}
                    color="primary"
                    aria-label="Load Sample"
                  >
                    <RestoreIcon fontSize="small" />
                  </IconButton>
                </Tooltip>
                <Tooltip title="Format">
                  <IconButton
                    size="small"
                    onClick={formatJson}
                    color="primary"
                    aria-label="Format"
                  >
                    <FormatAlignLeftIcon fontSize="small" />
                  </IconButton>
                </Tooltip>
                <Divider orientation="vertical" flexItem sx={{ mx: 0.5 }} />
                <Tooltip title="Clear all inputs">
                  <IconButton
                    size="small"
                    onClick={clearAll}
                    color="secondary"
                    aria-label="Clear all inputs"
                  >
                    <ClearIcon fontSize="small" />
                  </IconButton>
                </Tooltip>
              </Stack>
            </Box>
            <Box sx={{ p: 2, flex: "1 1 0", display: "flex", flexDirection: "column", minHeight: 0, overflow: "hidden" }}>
              <TextField
                multiline
                fullWidth
                value={jsonData}
                onChange={handleJsonChange}
                placeholder="Enter JSON data here..."
                variant="standard"
                slotProps={{
                  input: {
                    disableUnderline: true,
                    style: {
                      fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
                      fontSize: "0.85rem",
                      lineHeight: 1.5,
                      height: "100%",
                      boxSizing: "border-box",
                    },
                  },
                }}
                sx={{
                  flex: "1 1 0",
                  display: "flex",
                  flexDirection: "column",
                  height: 0,
                  minHeight: 0,
                  "& .MuiInputBase-root": {
                    flex: "1 1 0",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "stretch",
                    height: "100%",
                    minHeight: 0,
                  },
                  "& .MuiInputBase-input": {
                    flexGrow: 1,
                    overflow: "auto !important",
                    height: "100% !important",
                    resize: "none",
                    padding: 0,
                  },
                }}
              />
              {jsonError && (
                <Alert severity="error" sx={{ mt: 1, flexShrink: 0 }} variant="filled">
                  {jsonError}
                </Alert>
              )}
            </Box>
          </Paper>
        </Grid>

        <Grid size={{ xs: 12, md: 6 }} sx={{ display: "flex", flexDirection: "column", minHeight: 0 }}>
          <Paper
            sx={{
              flexGrow: 1,
              display: "flex",
              flexDirection: "column",
              overflow: "hidden",
              bgcolor: "background.paper",
              border: 1,
              borderColor: "divider",
              minHeight: 0,
            }}
          >
            <Box
              sx={{
                px: 2,
                py: 1,
                bgcolor: "action.hover",
                borderBottom: 1,
                borderColor: "divider",
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
              }}
            >
              <Box sx={{ display: "flex", alignItems: "center" }}>
                <OutputIcon sx={{ mr: 1, fontSize: 20 }} color="primary" />
                <Typography variant="subtitle2" color="text.primary">
                  Query Result
                </Typography>
              </Box>
              <Stack direction="row" spacing={1}>
                <Tooltip title="Copy to Clipboard">
                  <span>
                    <IconButton
                      size="small"
                      onClick={copyToClipboard}
                      disabled={!result || result === "null"}
                      color={copySuccess ? "success" : "primary"}
                    >
                      {copySuccess ? <CheckIcon fontSize="small" /> : <ContentCopyIcon fontSize="small" />}
                    </IconButton>
                  </span>
                </Tooltip>
                <Tooltip title="Download Result">
                  <span>
                    <IconButton
                      size="small"
                      onClick={downloadResult}
                      disabled={!result || result === "null"}
                      color="primary"
                    >
                      <DownloadIcon fontSize="small" />
                    </IconButton>
                  </span>
                </Tooltip>
              </Stack>
            </Box>
            <Box sx={{ p: 2, flex: "1 1 0", display: "flex", flexDirection: "column", minHeight: 0, overflow: "hidden" }}>
              <TextField
                multiline
                fullWidth
                value={result}
                variant="standard"
                placeholder="Results will appear here..."
                slotProps={{
                  input: {
                    readOnly: true,
                    disableUnderline: true,
                    style: {
                      fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
                      fontSize: "0.85rem",
                      lineHeight: 1.5,
                      height: "100%",
                      boxSizing: "border-box",
                    },
                  },
                }}
                sx={{
                  flex: "1 1 0",
                  display: "flex",
                  flexDirection: "column",
                  height: 0,
                  minHeight: 0,
                  "& .MuiInputBase-root": {
                    flex: "1 1 0",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "stretch",
                    height: "100%",
                    minHeight: 0,
                  },
                  "& .MuiInputBase-input": {
                    flexGrow: 1,
                    overflow: "auto !important",
                    height: "100% !important",
                    resize: "none",
                    padding: 0,
                  },
                }}
              />
            </Box>
          </Paper>
        </Grid>
      </Grid>
    </Box>
  );
}

export default MainPage;
