import * as React from "react";
import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import EditIcon from "@mui/icons-material/Edit";
import Grid from "@mui/material/Unstable_Grid2"; // Grid version 2
import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
import MenuItem from "@mui/material/MenuItem";
import Select from "@mui/material/Select";
import { useRecoilValue } from "recoil";
import { useSnackbar } from "notistack";
import CircleIcon from "@mui/icons-material/Circle";
import Chip from "@mui/material/Chip";
import SearchIcon from "@mui/icons-material/Search";

import {
  selectProductList,
  retrieveProductList,
  updateProduct,
} from "@/utils/mysqlCompatible";
import { sessionState } from "@/recoil/atoms";
import { useInitCRUD } from "@/utils/hook";
import type { SQLResult as SQLResultType } from "@/pages/api/sql/run";

import {
  ActionTemplate,
  ResultPreviewTemplate,
  TextFieldWrapper,
  ResultTable,
} from "@/components/Sections/MysqlCompatible/Content/Create";

const SQL_CONTENT = `UPDATE products
SET price = \${price}
WHERE product_id = \${product_id};`;

export default function UpdateContent() {
  const [sql, setSql] = React.useState(SQL_CONTENT);
  const [price, setPrice] = React.useState<number | null>(null);
  const [priceError, setPriceError] = React.useState<string | null>(null);
  const [prodId, setProdId] = React.useState<number | null>(null);
  const [result, setResult] = React.useState<SQLResultType | null>(null);
  const [originalResult, setOriginalResult] =
    React.useState<SQLResultType | null>(null);
  const [submitting, setSubmitting] = React.useState(false);
  const [globalLoading, setGlobalLoading] = React.useState(true);

  const { enqueueSnackbar } = useSnackbar();
  const session = useRecoilValue(sessionState);
  const [isInitCRUD] = useInitCRUD((error) => {
    enqueueSnackbar(`Error[init simple CRUD]: ${error?.message}`, {
      variant: "error",
    });
    setGlobalLoading(false);
  }, !!session);

  React.useEffect(() => {
    if (!price) {
      setSql(SQL_CONTENT);
      return;
    }
    const newSql = SQL_CONTENT.replace(
      /\${price}/g,
      price?.toString() || ""
    ).replace(/\${product_id}/g, prodId?.toString() || "");
    setSql(newSql);
  }, [price, prodId]);

  React.useEffect(() => {
    if (!isInitCRUD) return;

    const fetchData = async () => {
      try {
        const originalData = await retrieveProductList();
        setOriginalResult(originalData);
      } catch (error: any) {
        console.error(error);
        enqueueSnackbar(`Error[fetch data]: ${error?.message}`, {
          variant: "error",
        });
      } finally {
        setGlobalLoading(false);
      }
    };

    fetchData();
  }, [isInitCRUD]);

  React.useEffect(() => {
    if (originalResult?.rows && originalResult?.rows?.length > 0) {
      setProdId(originalResult.rows[0].productId);
    }
  }, [originalResult]);

  const handleEditPrice = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value.trim();
    if (value.length === 0) {
      setPriceError("Price cannot be empty");
      setPrice(null);
    } else {
      const price = Number(value);
      if (isNaN(price)) {
        setPriceError("Price must be a number");
        setPrice(null);
      } else if (price <= 0 || price > 1000000) {
        setPriceError("Price must be a positive number");
        setPrice(null);
      } else {
        setPriceError(null);
        setPrice(price);
      }
    }
  };

  const tableFieldsMemo = React.useMemo(() => {
    // if (result?.fields) {
    //   return result.fields.map((field) => field.name);
    // } else if (originalResult?.fields) {
    //   return originalResult.fields.map((field) => field.name);
    // }
    return ["productId", "productName", "price"];
  }, [result, originalResult]);

  const tableRowsMemo = React.useMemo(() => {
    const originalResultRowsIdList =
      originalResult?.rows?.map((i) => i[tableFieldsMemo[0] || "productId"]) ||
      [];
    if (result?.rows) {
      const priceIdx = tableFieldsMemo.indexOf("price");
      const resultRows = result.rows.map((row) => {
        if (row[tableFieldsMemo[0] || "productId"] === prodId) {
          row._updatedIdx = [priceIdx];
          row._add = true;
        }
        return row;
      });
      return resultRows;
    } else if (originalResult?.rows) {
      return originalResult.rows;
    }
    return [];
  }, [result, originalResult, tableFieldsMemo]);

  const handleSubmmit = async () => {
    if (!price) {
      return;
    }
    setSubmitting(true);
    setResult(null);
    try {
      await updateProduct({
        price: `${price}`,
        productId: `${prodId}`,
      });
      const result = await retrieveProductList();
      setResult(result);
    } catch (error: any) {
      console.error(error);
      enqueueSnackbar(`Error[run SQL]: ${error?.message}`, {
        variant: "error",
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <>
      <ActionTemplate
        inputTitle="Choose a product and update the price:"
        sqlContent={sql}
        handleSubmmit={handleSubmmit}
        disableSubbmit={!!priceError || globalLoading}
        submitting={globalLoading || submitting}
        submitBtnLabel={
          globalLoading ? "Init sample data" : "Run SQL and Update"
        }
        result={result?.rows?.length ? `OK, affects 1 row (s).` : null}
      >
        <TextFieldWrapper title="Product ID">
          <Select
            size="small"
            id="product_id"
            value={prodId || ""}
            onChange={(event) => {
              const value = event.target.value;
              setProdId(value as number);
            }}
            disabled={globalLoading}
            sx={{
              width: "239px",
            }}
          >
            {globalLoading && (
              <MenuItem value="">
                <em>Loading...</em>
              </MenuItem>
            )}
            {originalResult?.rows?.map((row) => (
              <MenuItem key={row.productId} value={row.productId}>
                {row.productName}({row.productId})
              </MenuItem>
            ))}
          </Select>
        </TextFieldWrapper>
        <TextFieldWrapper title="Price($)">
          <TextField
            id="price"
            size="small"
            InputProps={{
              endAdornment: (
                <EditIcon
                  sx={{
                    color: "rgba(168, 177, 193, 0.3)",
                  }}
                />
              ),
            }}
            defaultValue={price}
            onChange={handleEditPrice}
            error={!!priceError}
            helperText={priceError}
          />
        </TextFieldWrapper>
      </ActionTemplate>

      <ResultPreviewTemplate>
        <ResultTable fields={tableFieldsMemo} rows={tableRowsMemo} />
      </ResultPreviewTemplate>
    </>
  );
}
