"use client";

import * as React from "react";
import dynamic from "next/dynamic";
import {
  Box,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
  IconButton,
  Tooltip,
  TextField,
  Button,
  Stack,
} from "@mui/material";
import AddIcon from "@mui/icons-material/Add";

const Canvas = dynamic(() => import("@react-three/fiber").then((m) => m.Canvas), {
  ssr: false,
});
const OrbitControls = dynamic(
  () => import("@react-three/drei").then((m) => m.OrbitControls),
  { ssr: false }
);

const Text = dynamic(() => import("@react-three/drei").then((m) => m.Text), {
  ssr: false,
});

const RoundedBox = dynamic(
  () => import("@react-three/drei").then((m) => m.RoundedBox),
  { ssr: false }
);

const Environment = dynamic(
  () => import("@react-three/drei").then((m) => m.Environment),
  { ssr: false }
);


type Product = {
  record_num: number;
  product_id: number;
  name: string;
  exp_date: string; // ISO yyyy-mm-dd
};

function isoTodayPlus(days: number) {
  const d = new Date();
  d.setDate(d.getDate() + days);
  const yyyy = d.getFullYear();
  const mm = String(d.getMonth() + 1).padStart(2, "0");
  const dd = String(d.getDate()).padStart(2, "0");
  return `${yyyy}-${mm}-${dd}`;
}

const seed: Product[] = [
  { record_num: 2, product_id: 1002, name: "Eggs", exp_date: isoTodayPlus(12) },
  { record_num: 3, product_id: 1003, name: "Bread", exp_date: isoTodayPlus(6) },
  { record_num: 4, product_id: 1004, name: "Cheese", exp_date: isoTodayPlus(90) },
  { record_num: 5, product_id: 1005, name: "Yogurt", exp_date: isoTodayPlus(20) },
  { record_num: 6, product_id: 1006, name: "Butter", exp_date: isoTodayPlus(120) },
];

const glassPaperSx = {
  borderRadius: 3,
  // glossy glass look
  background: `
    linear-gradient(180deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.05) 100%),
    radial-gradient(1200px 600px at 20% 0%, rgba(130,170,255,0.20) 0%, rgba(0,0,0,0) 55%),
    radial-gradient(900px 500px at 80% 10%, rgba(255,140,180,0.14) 0%, rgba(0,0,0,0) 60%)
  `,
  border: "1px solid rgba(255,255,255,0.14)",
  backdropFilter: "blur(14px) saturate(130%)",
  boxShadow: "0 12px 40px rgba(0,0,0,0.35)",
  color: "rgba(245,245,245,0.92)",
};

const PLANE_SIDE = 4;
const CUBE_SIZE = 1.0;
const GAP = 0.25;
const GAP_Z = 0.9;

export default function Products() {
  const [products, setProducts] = React.useState<Product[]>(seed);
  const [selected, setSelected] = React.useState<Product | null>(null);
  const [mode, setMode] = React.useState<"view3d" | "form">("view3d");

  const sorted = React.useMemo(() => {
    return [...products].sort((a, b) => (a.exp_date < b.exp_date ? -1 : 1));
  }, [products]);

  const startCreate = () => {
    setSelected({
      record_num: -1,
      product_id: -1,
      name: "",
      exp_date: isoTodayPlus(1),
    });
    setMode("form");
  };

  const startEdit = (p: Product) => {
    setSelected(p);
    setMode("form");
  };

  const cancelForm = () => {
    setMode("view3d");
    setSelected(null);
  };

  const saveForm = (p: Product) => {
    const isNew = p.record_num === -1;

    if (isNew) {
      const nextRecord =
        Math.max(0, ...products.map((x) => x.record_num)) + 1;
      const nextProductId =
        Math.max(0, ...products.map((x) => x.product_id)) + 1;

      const inserted: Product = {
        ...p,
        record_num: nextRecord,
        product_id: nextProductId,
      };
      setProducts((prev) => [inserted, ...prev]);
    } else {
      setProducts((prev) =>
        prev.map((x) => (x.record_num === p.record_num ? p : x))
      );
    }

    setMode("view3d");
    setSelected(null);
  };

  return (
    <Box
      sx={{
        minHeight: "100vh",
        display: "flex",
        gap: 2,
        p: 2,
      }}
    >
      <Box sx={{ width: { xs: "100%", md: 520 }, flex: "0 0 auto" }}>
        <TableContainer
          component={Paper}
          sx={{
            ...glassPaperSx,
            height: "calc(100vh - 16px)",
            overflow: "auto",
          }}
        >
          <Table stickyHeader size="small" aria-label="products table">
            <TableHead>
              <TableRow>
                <TableCell
                   sx={{
                    position: "sticky",
                    top: 0,
                    zIndex: 3,
                    fontWeight: 800,
                    whiteSpace: "nowrap",
                    backgroundColor: "rgba(15, 18, 28, 0.65)", 
                    backdropFilter: "blur(10px)",
                    borderBottom: "1px solid rgba(255,255,255,0.10)",
                    color: "rgba(245,245,245,0.92)",
                  }}
                >
                  Products
                </TableCell>

                <TableCell
                   sx={{
                    position: "sticky",
                    top: 0,
                    zIndex: 3,
                    fontWeight: 800,
                    whiteSpace: "nowrap",
                    backgroundColor: "rgba(15, 18, 28, 0.65)",
                    backdropFilter: "blur(10px)",
                    borderBottom: "1px solid rgba(255,255,255,0.10)",
                    color: "rgba(245,245,245,0.92)",
                  }}
                >
                  Exp Date
                </TableCell>

                <TableCell
                  sx={{
                    position: "sticky",
                    top: 0,
                    zIndex: 4,
                    width: 1,
                    p: 0,
                  }}
                >
                  <Box sx={{ position: "relative", height: 1 }}>
                    <Tooltip title="Add product">
                      <IconButton
                        onClick={startCreate}
                        size="small"
                        sx={{
                          position: "absolute",
                          right: -18,
                          top: "50%",
                          transform: "translateY(-50%)",
                          bgcolor: "background.paper",
                          border: "1px solid",
                          borderColor: "divider",
                          boxShadow: 1,
                          "&:hover": { bgcolor: "action.hover" },
                        }}
                        aria-label="add product"
                      >
                        <AddIcon fontSize="small" />
                      </IconButton>
                    </Tooltip>
                  </Box>
                </TableCell>
              </TableRow>
            </TableHead>

            <TableBody>
              {sorted.map((p) => (
                <TableRow
                  key={p.record_num}
                  hover
                  onClick={() => startEdit(p)}
                  sx={{ cursor: "pointer" }}
                >
                  <TableCell>
                    <Typography fontWeight={700}>{p.name}</Typography>
                    <Typography variant="caption" sx={{ opacity: 0.7 }}>
                      record #{p.record_num} • product_id {p.product_id}
                    </Typography>
                  </TableCell>
                  <TableCell sx={{ whiteSpace: "nowrap" }}>{p.exp_date}</TableCell>
                  <TableCell sx={{ width: 1 }} />
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      </Box>

      <Box
        sx={{
          flex: "1 1 auto",
          minWidth: 0,
          position: "relative",
          borderRadius: 0,
          bgcolor: "transparent",
        }}
      >
        {mode === "view3d" ? (
          <Box sx={{ width: "100%", height: "calc(100vh - 16px)" }}>
            <World3D products={sorted} />
          </Box>
        ) : (
          <Box sx={{ width: "100%", height: "calc(100vh - 16px)" }}>
            <ProductForm
              value={selected}
              onCancel={cancelForm}
              onSave={saveForm}
            />
          </Box>
        )}
      </Box>
    </Box>
  );
}

function rowsUsedForPlane(total: number, planeIndex: number, side: number) {
  const perPlane = side * side;
  const start = planeIndex * perPlane;
  const remaining = Math.max(0, total - start);
  const countThisPlane = Math.min(perPlane, remaining);
  return Math.max(1, Math.ceil(countThisPlane / side));
}

function computePosition(
  i: number,
  total: number,
  side: number,
  cubeSize: number,
  gap: number,
  gapZ: number
) {
  const perPlane = side * side;

  const plane = Math.floor(i / perPlane);
  const planeStart = plane * perPlane;
  const planeCount = Math.min(perPlane, Math.max(0, total - planeStart));

  const within = i - planeStart; // 0..planeCount-1

  // Fill DOWN first, then LEFT (next column)
  const col = Math.floor(within / side); // 0..side-1 (right -> left)
  const row = within % side;             // 0..side-1 (top -> down)

  // How many cubes are actually in *this column* on this plane?
  // (last column may be partial)
  const countInThisCol = Math.min(side, planeCount - col * side);

  // spacing
  const step = cubeSize + gap;

  // Right-most column is col=0 => x positive
  const xHalfSpan = ((side - 1) * step) / 2;
  const x = xHalfSpan - col * step;

  // FLOOR-LOCK PER COLUMN:
  // bottom cube of this column sits at y = cubeSize/2
  // row=0 is top => higher y
  const y = cubeSize / 2 + (countInThisCol - 1 - row) * step;

  // Next plane goes "forward/back". You said you want front first,
  // so plane 0 should be the front. Put further planes behind it:
  const z = -plane * (cubeSize + gapZ);

  return [x, y, z] as const;
}


function World3D({ products }: { products: Product[] }) {
  return (
    <Canvas
      camera={{ position: [7, 6, 13], fov: 45, near: 0.1, far: 200 }}
      onCreated={({ camera }) => {
        camera.lookAt(2.8, 2.6, -2);
      }}
      gl={{ antialias: true }}
    >
      {/* Nice reflections / lighting */}
      <Environment preset="city" />

      {/* eslint-disable-next-line react/no-unknown-property */}
      <ambientLight intensity={0.35} />
      {/* eslint-disable-next-line react/no-unknown-property */}
      <directionalLight position={[8, 10, 6]} intensity={1.4} />
      {/* eslint-disable-next-line react/no-unknown-property */}
      <directionalLight position={[-8, 6, -6]} intensity={0.6} />

      <gridHelper args={[60, 60]} />

      {products.map((p, i) => (
        <ProductBox
          key={p.record_num}
          product={p}
          index={i}
          total={products.length}
        />
      ))}

      <OrbitControls
        enableRotate={true}
        enablePan={true}
        enableZoom={true}
        minDistance={10}
        maxDistance={14}
      />
    </Canvas>
  );
}

function ProductBox({
  product,
  index,
  total,
}: {
  product: Product;
  index: number;
  total: number;
}) {
  const [x, y, z] = computePosition(index, total, PLANE_SIDE, CUBE_SIZE, GAP, GAP_Z);

  const label = String(product.product_id);

  const s = CUBE_SIZE;
  const half = s / 2;
  const pad = 0.01; // push text slightly off the face to avoid z-fighting

  const fontSize = Math.max(0.14, s * 0.18);

  return (
    // eslint-disable-next-line react/no-unknown-property
    <group position={[x, y, z]}>
      {/* Rounded cube */}
      <RoundedBox args={[s, s, s]} radius={0.12} smoothness={6}>
        {/* eslint-disable-next-line react/no-unknown-property */}
        <meshPhysicalMaterial
          transmission={0.65}   // glassiness
          roughness={0.18}
          thickness={1.2}
          clearcoat={1}
          clearcoatRoughness={0.12}
          metalness={0.05}
          envMapIntensity={1.25}
        />
      </RoundedBox>

      {/* +Z (front) */}
      <Text
        position={[0, 0, half + pad]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>

      {/* -Z (back) */}
      <Text
        position={[0, 0, -half - pad]}
        rotation={[0, Math.PI, 0]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>

      {/* +X (right) */}
      <Text
        position={[half + pad, 0, 0]}
        rotation={[0, -Math.PI / 2, 0]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>

      {/* -X (left) */}
      <Text
        position={[-half - pad, 0, 0]}
        rotation={[0, Math.PI / 2, 0]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>

      {/* +Y (top) */}
      <Text
        position={[0, half + pad, 0]}
        rotation={[-Math.PI / 2, 0, 0]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>

      {/* -Y (bottom) */}
      <Text
        position={[0, -half - pad, 0]}
        rotation={[Math.PI / 2, 0, 0]}
        fontSize={fontSize}
        anchorX="center"
        anchorY="middle"
        outlineWidth={0.01}
        outlineColor="black"
      >
        {label}
      </Text>
    </group>
  );
}



function ProductForm({
  value,
  onCancel,
  onSave,
}: {
  value: Product | null;
  onCancel: () => void;
  onSave: (p: Product) => void;
}) {
  const [draft, setDraft] = React.useState<Product | null>(value);

  React.useEffect(() => {
    setDraft(value);
  }, [value]);

  if (!draft) return null;

  const isNew = draft.record_num === -1;

  return (
    <Box
      sx={{
        height: "100%",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        px: 2,
      }}
    >
      <Paper
        elevation={0}
        sx={{
          ...glassPaperSx,
          width: "min(720px, 100%)",
          p: 3,
        }}
      >        
        <Typography variant="h6" fontWeight={800} gutterBottom>
          {isNew ? "Create Product" : "Update Product"}
        </Typography>

        <Stack spacing={2} sx={{ mt: 2 }}>
          <TextField
            label="Name"
            value={draft.name}
            onChange={(e) =>
              setDraft((d) => (d ? { ...d, name: e.target.value } : d))
            }
            inputProps={{ maxLength: 20 }}
            fullWidth
          />

          <TextField
            label="Expiration Date"
            type="date"
            value={draft.exp_date}
            onChange={(e) =>
              setDraft((d) => (d ? { ...d, exp_date: e.target.value } : d))
            }
            InputLabelProps={{ shrink: true }}
            fullWidth
          />

          <Box sx={{ display: "flex", gap: 1, justifyContent: "flex-end" }}>
            <Button onClick={onCancel} variant="text">
              Cancel
            </Button>
            <Button
              onClick={() => onSave(draft)}
              variant="contained"
              disabled={!draft.name.trim() || !draft.exp_date}
            >
              Save
            </Button>
          </Box>
        </Stack>
      </Paper>
    </Box>
  );
}

