'use client'
import React, { SyntheticEvent } from "react";
import styles from "@/styles/dev-tools.module.css"
import { Container, Select, Stack, Chip, MenuItem, InputLabel, Snackbar, IconButton, SnackbarCloseReason, Typography } from "@mui/material"
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
import CloseIcon from '@mui/icons-material/Close';
import Draggable from 'react-draggable';

type EditorMode = "insert" | "update";

interface DBObject {
  record_num: number
  data_id: string;
  change_timestamp: string;
}

interface Unit extends DBObject {

}

interface Card extends DBObject {

}

interface EditorContextType {
  editorMode: "insert" | "update";
  currentRecordNum: number | null;
  currentDataId: string | null;
  cards: Card[] | null;
  units: Unit[] | null;
  error: string | null,

  changeEditorMode?: (m: string) => void; 
  changeCurrentRecordNum?: (n: number) => void;
  changeCurrentDataId?: (n: string) => void;
  changeError?: (e: string) => void;
}
const EditorContext = React.createContext<EditorContextType>({
  currentRecordNum: null,
  currentDataId: null,
  editorMode: "insert",
  cards: null,
  units: null,
  error: null,
})

function useEditor() {
  const ctx = React.useContext(EditorContext);
  if(!ctx){
    throw new Error("Error: use Editor must be used within an EditorContext")
  }

  return ctx;
}


const unitTypes: string[] = ["minion", "enemy", "hero", "ally"];
const buildingTypes: string[] = ["enemy", "minion", "terrain", "support"];

export default function Page(){
  const [currentRecordNum, setCurrentRecordNum] = React.useState<number>(0);
  const [currentDataId, setCurrentDataId] = React.useState<string>("");
  const [editorMode, setEditorMode] = React.useState<EditorMode>("insert");
  const [cards, setCards] = React.useState<Card[] | null>(null);
  const [units, setUnits] = React.useState<Unit[] | null>(null);
  const [error, setError] = React.useState<string | null>(null);
  const [open, setOpen] = React.useState<boolean>(false);
  
  const changeCurrentRecordNum = (n: number) => setCurrentRecordNum(n)
  const changeCurrentDataId = (id: string) => setCurrentDataId(id)
  const changeEditorMode = (m: string) =>{
    if(m !== "insert" && m !== "update") return
    setEditorMode(m)
  } 
  const changeError = (e: string) => setError(e);
  // get all of the cards, or units
  React.useEffect(() => {
    const getCards = async () => {
      try{
        // fetch our db
      }catch (error) {

      }
    }

    const getUnits = async () => {
      try{

      }catch (error) {

      }
    }
    getCards();
    getUnits();
  }, [])

  const handleClose = (
    event: React.SyntheticEvent | Event,
    reason?: SnackbarCloseReason,
  ) => {
    if (reason === 'clickaway') {
      return;
    }

    setOpen(false);
  };

  const action = (
    <React.Fragment>
      <Typography>
        {error}
      </Typography>
      <IconButton
        size="small"
        aria-label="close"
        color="inherit"
        onClick={handleClose}
      >
        <CloseIcon fontSize="small" />
      </IconButton>
    </React.Fragment>
  );


  return (
    <EditorContext.Provider value={{
      currentRecordNum,
      currentDataId,
      editorMode,
      error,
      cards,
      units,

      changeCurrentRecordNum,
      changeCurrentDataId,
      changeEditorMode,
      changeError
    }}>
      <div className={styles.maincontainer}>
        <div className={styles.leftmenucontainer}>
          <LeftMenu />
        </div>
        <div className={styles.editorcontainer}>
          <Editor />
        </div>
      </div>
      {error && <Snackbar
        open={open}
        autoHideDuration={6000}
        onClose={handleClose}
        action={action}
      />}
    </EditorContext.Provider>
  )
}

function DynamicCard() {
  // to add a new kind of data type "map", "string", "bool", etc. they add a prop for it.
  return (
    <>
    </>
  )
}


interface ThemeSelection {
  value: string;
  label: string;
}


const debugCard = [
  {
    id: "terrain_forest",
    label: "Forest",
    children: [
      {
        id: "terrain_haunted_forest",
        label: "Haunted Forest",
        children: [
          {
            id: 'terrain_undead_candy_forest',
            label: "Undead Candy Forest"
          }
        ]
      }
    ]
  },
  {
    id: "support_blacksmith",
    label: "Forest",
    children: [
      {
        id: "support_terrain_haunted_forest",
        label: "Haunted Forest",
        children: [
          {
            id: 'SUppror_terrain_undead_candy_forest',
            label: "Undead Candy Forest"
          }
        ]
      }
    ]
  },
  {
    id: "enemy_graveyard",
    label: "Forest",
    children: [
      {
        id: "enemy_terrain_haunted_forest",
        label: "Haunted Forest",
        children: [
          {
            id: 'enemy_terrain_undead_candy_forest',
            label: "Undead Candy Forest"
          }
        ]
      }
    ]
  }
]

function LeftMenu(){

  const [themes, setThemes] = React.useState<ThemeSelection[]>([]); // get from the database
  const [menuMode, setMenuMode] = React.useState<"unit" | "card">("card");

  const { currentRecordNum,  } = useEditor();

  const handleSelectAsset = (e: React.MouseEvent<Element, MouseEvent>) => {
    console.log("Got e:", e)
  }
  return (
    <Container className={styles.leftmenu}>
      <Stack >
        <Typography id="assetTypeFilter">Asset Type</Typography>       
        <Select className="assetTypeFilter">
          <MenuItem value="">All</MenuItem>
          {menuMode === "card" ? 
            buildingTypes.map((opt, i) => (<MenuItem value={opt} key={i}>{opt[0].toUpperCase() + opt.slice(1)}</MenuItem>)) : 
            unitTypes.map((opt, i) => (<MenuItem value={opt} key={i}>{opt[0].toUpperCase() + opt.slice(1)}</MenuItem>))
          }
        </Select>

        <InputLabel id="themeFilter">Theme</InputLabel>       
        <Select className="themeFilter" label="Theme" >
          <MenuItem value="">All</MenuItem>
        </Select>
        
      </Stack>
      <Typography >
        Current {menuMode}s created
      </Typography>
      <RichTreeView items={debugCard} onItemClick={handleSelectAsset}>
      </RichTreeView>
    </Container>
  )
}


function Editor(){
  const { editorMode } = useEditor();

  const canvasWrapperRef = React.useRef<HTMLDivElement | null>(null);
  const canvasRef = React.useRef<HTMLCanvasElement | null>(null);

  const onMouseUp = (e: React.MouseEvent) => {
    
    console.log("event for mouse up", e)
  }

  const onMouseDown = (e: React.MouseEvent) => {

    console.log("event for mouse down", e)
  }

  const onDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    //console.log("event for drag over:", e)
  }

  const onDrop = (e: React.DragEvent) => {
    e.preventDefault();
    const raw = e.dataTransfer.getData("text/plain");
    console.log("DROP canvas raw:", raw);
    // create a box?
  }

  return (
    <Container className={styles.editor} maxWidth={false} disableGutters> 

      {editorMode === "insert" ? <CreateNewAsset type="building"/> : null}
      <div
        ref={canvasWrapperRef}
        onDragOver={(e: React.DragEvent) => {
          e.preventDefault(); 
          e.dataTransfer.dropEffect = "copy";
        }}
        onDrop={(e: React.DragEvent) => {
          e.preventDefault();
          const raw = e.dataTransfer.getData("text/plain");
          console.log("DROP wrapper raw:", raw);
        }}
        style={{ height: "100%", width: "100%", position: "relative" }}
      >
        <canvas
          ref={canvasRef}
          onDragOver={onDragOver}
          onDrop={onDrop}
          style={{ height: "100%", width: "100%" }}
        />
      </div>

    </Container>
  )
}

function CreateNewAsset({ type }: { type: string }) {
  return (
    <div style={{ backgroundColor: "#F1E9DB", borderRadius: 20, height: 40, display: "flex", alignItems: "center", justifyContent: "center", columnGap: 20 }}>
      {type === "building"
        ? buildingTypes.map((buildingType, i) => {
            const label = buildingType[0].toUpperCase() + buildingType.slice(1);

            return (
              <div
                key={i}
                draggable
                onDragStart={(e) => {
                  console.log("DRAG START", buildingType);
                  const payload = { kind: "building", type: buildingType, label, w: 160, h: 90 };
                  e.dataTransfer.setData("text/plain", JSON.stringify(payload)); 
                  e.dataTransfer.effectAllowed = "copy";
                }}
                style={{ display: "inline-flex" }}
              >
                <Chip sx={{ backgroundColor: "#5DB7DE" }} label={label} />
              </div>
            );
          })
        : unitTypes.map((unitType, i) => {
            const label = unitType[0].toUpperCase() + unitType.slice(1);
            return (
              <div
                key={i}
                draggable
                onDragStart={(e) => {
                  const payload = { kind: "unit", type: unitType, label, w: 140, h: 80 };
                  e.dataTransfer.setData("text/plain", JSON.stringify(payload));
                  e.dataTransfer.effectAllowed = "copy";
                }}
                style={{ display: "inline-flex" }}
              >
                <Chip sx={{ backgroundColor: "#5DB7DE" }} label={label} />
              </div>
            );
          })}
    </div>
  );
}

