// resources\assets\ts\DataPage\TaskNavigator.tsx
import $ from 'jquery';

import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import Menu from '@mui/material/Menu';
import { RootState } from './rootReducer';
import { blue } from '@mui/material/colors';
import { clearTable } from './tableSlice';
import { fetchAll, fetchFav } from './dataSlice';
import {
  fetchTree,
  restoreTree,
  toggleNode,
} from './taskNavigatorSlice';
import { initForm as initCounterForm } from './counterFormSlice';
import { fetchLatest as initMeasurementForm } from './measurementFormSlice';
import { setNode } from './nodeSlice';
import { useDispatch, useSelector } from 'react-redux';
import AddIcon from '@mui/icons-material/Add';
import MenuItem from '@mui/material/MenuItem';
import React, { useEffect } from 'react';
import StarIcon from '@mui/icons-material/Star';
import { TreeItem, TreeItemProps, TreeItemContent } from '@mui/x-tree-view/TreeItem';
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
import axios from 'axios';
import styled from 'styled-components';
import StarsIcon from '@mui/icons-material/Stars';
import '../share/dialogPopup.tsx';


import { TreeNode } from './types';
const csrftoken = $('meta[name="csrf-token"]').attr('content');

export function typeIcons(type: string) {
  switch (type) {
    case 'department':
      return '/icon8/ber24.png';

    case 'BEM':
    case 'BEMi':
      return '/icon8/bem24.png';

    case 'BST':
    case 'BSTi':
      return '/icon8/bst24.png';

    case 'BSW':
      return '/icon8/bsw24.png';

    case 'CST':
      return '/icon8/cst24.png';

    case 'DEX':
      return '/icon8/exp24.png';

    case 'DYA':
      return '/icon8/dya24.png';

    case 'DYN':
      return '/icon8/dyn24.png';

    case 'ENY':
      return '/images/ord24.png';

    case 'GRP':
      return '/icon8/grp24.png';

    case 'INF':
      return '/icon8/inf24.png';

    case 'LGC':
      return '/icon8/lgc24.png';

    case 'MLD':
    case 'MLDi':
      return '/icon8/mld24.png';

    case 'MWE':
      return '/icon8/mwe24.png';

    case 'MWT':
    case 'MWTi':
      return '/icon8/mwt24.png';

    case 'ORD':
      return '/images/ord24.png';

    case 'REP':
      return '/icon8/pdf24.png';

    case 'RWG':
      return '/icon8/rgw24.png';

    case 'STR':
    case 'STRi':
      return '/icon8/str24.png';

    case 'STT':
    case 'STTi':
      return '/icon8/stt24.png';

    case 'VBG':
    case 'VBE':
    case 'VBGi':
      return '/icon8/vbg24.png';

    case 'WTG':
    case 'WTGi':
      return '/icon8/wtg24.png';

    case 'DOC':
      return '/icon8/doc24.png';

    case 'LST':
    case 'LSTi':
      return '/icon8/lst24.png';

    case 'MOD':
    case 'MODi':
      // TODO:MOD update png later
      return '/icon8/mod24.png';

    case 'USER':
      return '/icon8/app/login.png';

    default:
      return `${type}/missing.png`;
  }
}


// add width 100 and flex 1 so the tree scales with the adjusted width
const CustomTreeItemContent = styled(TreeItemContent)({
  width: '100%',
});


const StyledTreeItem = (props: TreeItemProps & { isDepartment?: boolean }) => {
  return (
    <TreeItem
      {...props}
      slots={{
        content: CustomTreeItemContent,
      }}
    />
  );
};

const FolderDiv = styled.div`
  /* display: flex;
  align-items: center;
  img {
    flex-shrink: 0;
  } */
`;

const TaskDiv = styled.div`
  /* width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  img {
    flex-shrink: 0;
  } */
`;

const FolderName = styled.div`
  /* padding: 1em; */
`;
const TaskName = styled.div`
  /* padding: 1em; */
  /* text-align: center; */
`;

const LabelView = ({
  favs,
  node,
  type,
  name,
  isCreateable,
  handleCreateNew,
  setIsFav,
  setBers_ids,
  showFavButton,
}) => {
  function onClick(e) {
    e.stopPropagation();
    handleCreateNew();
  }
  const isFav = (node) => {
    let isFavorite = false;

    if (node.uid && node.nodeID) {
      if (node.uid.slice(0, 3) === 'AGB' || node.nodeID.slice(0, 3) === 'LST') {
        for (let key in favs) {
          for (let i = 0; i < favs[key].length; i++) {
            if (
              (favs[key][i].task_id === node.id &&
                node.uid.slice(0, 3) === 'AGB') ||
              (favs[key][i].grp_id === node.id &&
                node.nodeID.slice(0, 3) === 'LST')
            ) {
              isFavorite = true;
              break;
            }
          }
        }
      }
    }
    return isFavorite;
  };
  const [isFavorit, setIsFavItem] = React.useState(isFav(node));

  const addFavorite = async (node) => {
    try {
      const response = await fetch('/add-favorite-monitor', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          // Include authorization headers if required:
          // 'Authorization': `Bearer ${token}`,
        },
        body: JSON.stringify({
          fav_id: node.id,
          fav_typ: node.uid.slice(0, 3),
          _token: csrftoken,
        }),
      });
      if (!response.ok) throw new Error('Failed to add favorite');
      return response.json();
    } catch (error) {
      console.error('Error adding favorite:', error);
    }
  };

  const removeFavorite = async (node) => {
    try {
      const response = await fetch('/remove-favorite-monitor', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          fav_id: node.id,
          fav_typ: node.uid.slice(0, 3),
          _token: csrftoken,
        }),
      });
      if (!response.ok) throw new Error('Failed to remove favorite');
      return response.json();
    } catch (error) {
      console.error('Error removing favorite:', error);
    }
  };

  const clickHandler = async (e) => {
    e.stopPropagation();
    e.preventDefault();
    // Toggle the favorite status based on current state
    if (isFavorit) {
      const result = await removeFavorite(node);
      if (result) {
        setIsFavItem(false); // Update state only on successful API response
      }
    } else {
      const result = await addFavorite(node);
      if (result) {
        setIsFavItem(true); // Update state only on successful API response
        // ////console.log('Favorite added', result);
      }
    }
    axios.get('/getLstFavAllByUser').then((res) => {
      setIsFav(res.data);
    });
    axios
      .get('/get-all-favorite-bers')
      .then((res) => {
        setBers_ids(res.data.ber_ids);
      })
      .catch((err) => {
        ////console.log(err);
      });
  };

  return (
    <Box
      display='flex'
      alignItems='center'
      flexWrap='wrap'
      p={0.5}
      overflow='hidden'
    >
      <img src={typeIcons(type)} alt={`${type} icon`} />
      <Box pl='0.3em'>
        <span>{name}</span>
      </Box>
      <Box marginLeft='auto'>
        {isCreateable && (
          <IconButton size='small' onClick={onClick}>
            <AddIcon style={{ color: blue[500] }} />
          </IconButton>
        )}
      </Box>

      {type !== 'GRP' && type !== 'department' ? (
        <IconButton size='small' onClick={clickHandler}>
          <StarIcon
            style={{
              color: blue[500],
              borderBlockColor: blue[500],
              fill: isFav(node) ? blue[500] : '#c7bfbf',
              fontSize: '20px',
            }}
          />
        </IconButton>
      ) : null}
      {showFavButton ?? null}
      {type !== 'department' && (
  <Box sx={{ width: '8px', flexShrink: 0 }} />
)}
    </Box>
    
  );
};

const RenderTree = ({
  node,
  type,
  nodeID,
  name,
  expandable,
  childNode,
  favs,
  setIsFav,
  setBers_ids,
  showFavButton
}) => {
  const d = useDispatch();

  function handleItemClick(event: React.MouseEvent) {
    event.stopPropagation();
    d(clearTable());
    d(setNode(node));
    d(fetchAll());
  }

  function handleCreateNew() {
    const isMeasurement = node.type === 'MWTi' || node.type === 'MWT';
    if (isMeasurement) {
      return d(initMeasurementForm({ ID: node.id, name: node.name }));
    }

    const isCounter = node.type === 'VBG' || node.type === 'VBGi';
    if (isCounter) {
      return d(initCounterForm({ ID: node.id, name: node.name }));
    }

    const url = `form?byid=${node.id}`;
    const onClose = (e: Event) => {
      if ((e as CustomEvent).detail?.submitted) {
        d(clearTable());
        d(fetchAll());
      }
    };

    window.addEventListener('formPopupClosed', onClose, { once: true });

    window.openFormPopup(url);
  }

  const isEmptyExpandableNode = expandable && childNode === undefined;
  if (isEmptyExpandableNode) {
    return (
      <StyledTreeItem
        itemId={nodeID}
        isDepartment={type === 'department'}
        label={
          <LabelView
            favs={favs}
            node={node}
            type={type}
            name={name}
            nodeId={node.id}
            isCreateable={node.isCreateable}
            handleCreateNew={handleCreateNew}
            setIsFav={setIsFav}
            setBers_ids={setBers_ids}
            showFavButton={showFavButton}
          />
        }
        onClick={handleItemClick}
      >
        <StyledTreeItem itemId={nodeID + '-noChildren'} label={''}></StyledTreeItem>
      </StyledTreeItem>
    );
  }

  //create a function that will delete a fav from the obj using the node uid like isFav function

  return (
    <StyledTreeItem
      itemId={nodeID}
      label={
        <LabelView
          favs={favs}
          node={node}
          type={type}
          name={name}
          nodeId={node.id}
          isCreateable={node.isCreateable && node.type != 'INF'}
          handleCreateNew={handleCreateNew}
          setIsFav={setIsFav}
          setBers_ids={setBers_ids}
          showFavButton={showFavButton}  
        />
      }
      onClick={handleItemClick}
    >
      {Array.isArray(childNode)
        ? childNode.map((node, index) => (
          <RenderTree
            node={node}
            key={node.nodeID}
            nodeID={node.nodeID}
            name={node.name}
            type={node.type}
            expandable={node.isExpandable}
            childNode={node.childrens}
            favs={favs}
            setIsFav={setIsFav}
            setBers_ids={setBers_ids}
            showFavButton={null} 
          />
        ))
        : null}
    </StyledTreeItem>
  );
};

type TaskNavigatorProps = {
  selectedNode: TreeNode;
};

export default function TaskNavigator({ selectedNode }: TaskNavigatorProps) {
  const d = useDispatch();
  const treeData = useSelector((s: RootState) => s.tree.treeData);
  const treeEntities = useSelector((s: RootState) => s.tree.entities);
  const expanded = useSelector((s: RootState) => s.tree.expanded);
  const status = useSelector((s: RootState) => s.tree.status);
  const [isFav, setIsFav] = React.useState(null);
  const [bers_ids, setBers_ids] = React.useState(null);

  const [anchorEl, setAnchorEl] = React.useState(null);
  const [MenuItems, setMenuItems] = React.useState(null);
  const open = Boolean(anchorEl);
  useEffect(
    function initTree() {
      if (status !== 'init') {
        return;
      }

      d(fetchTree());
    },
    [d, status],
  );

  function handleCreateNewItem(e, item) {
    const isMeasurement = item.typ === 'MWTi' || item.typ === 'MWT';
    if (isMeasurement) {
      return d(initMeasurementForm({ ID: item.agb_id, name: item.agb_name }));
    }

    const isCounter = item.typ === 'VBG' || item.typ === 'VBGi';
    if (isCounter) {
      return d(initCounterForm({ ID: item.agb_id, name: item.agb_name }));
    }
    const url = `form?byid=${item.agb_id}`;

    const onClose = () => {
      d(clearTable());
      d(fetchAll());
    };
    window.addEventListener('formPopupClosed', onClose, { once: true });
    window.openFormPopup(url);
    handleClose();
  }
  function expandListBesrclick(e) {
    e.stopPropagation();
    //go to the next closest div parent
    let nodeId = e.target.closest('div').id;
    axios
      .post('/getLstFav', { id: nodeId })
      .then((res) => {
        for (let i = 0; i < res.data.length; i++) {
          res.data[i].key = i;
        }
        setMenuItems(res.data);
      })
      .catch((err) => {
        ////console.log(err);
      });

    setAnchorEl(e.currentTarget);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  function handleMenuItemClick(e, item) {
    d(clearTable());
    let type = e.target.id.slice(0, 3);
    let id = e.target.id.slice(3);
    let obj = { type, id };
    //the node will look like this
    /**
     * return {
    id: treeData.id,
    uid: treeData.uid,
    nodeID: `${treeData.type}::${treeData.id}`,
    name: treeData.name,
    isExpandable: treeData.expandable === 1,
    isCreateable: treeData.createable > 0,
    type: treeData.type,
    path: [],
    selected: false,
  };
     */
    let node: TreeNode = {
      id: null,
      type: null,
      uid: null,
      nodeID: null,
      name: null,
      isExpandable: false,
      isCreateable: false,
      path: [],
      selected: false,
    };
    if (item.agb_typ === 'INF' || item.agb_typ === 'DOC') {
      node.id = item.agb_id;
      node.type = item.agb_typ;
      d(setNode(node));
    }

    d(fetchFav(obj));
    handleClose();
  }

  useEffect(() => { }, [anchorEl]);

  useEffect(
    function startRestoreTree() {
      if (status !== 'restore') {
        return;
      }

      d(restoreTree(0));
    },
    [d, status],
  );

  if (treeData === []) {
    return null;
  }

  useEffect(() => {
    axios.get('/getLstFavAllByUser').then((res) => {
      setIsFav(res.data);
    });
    axios
      .get('/get-all-favorite-bers')
      .then((res) => {
        setBers_ids(res.data.ber_ids);
      })
      .catch((err) => {
        ////console.log(err);
      });
  }, []);

  const handleItemExpansionToggle = (
    event: React.SyntheticEvent,
    itemId: string,
  ) => {
    event.stopPropagation();
    const nodeToExpand =
      treeEntities[itemId] ??
      (selectedNode?.nodeID === itemId ? selectedNode : null);
    if (!nodeToExpand) return;
    d(toggleNode(nodeToExpand));
  };

  return (
    <SimpleTreeView
      onItemExpansionToggle={handleItemExpansionToggle}
      expansionTrigger={"iconContainer"}
    >
      {treeData.map((v) => {
  const departmentId = v.nodeID.match(/\d+$/)?.[0];
  const hasFav = v.type === 'department' && bers_ids &&
    bers_ids.indexOf(Number(departmentId)) !== -1;

  const favButton = hasFav ? (
    <div id={departmentId}>
      <IconButton onClick={expandListBesrclick} size='large'>
        <StarsIcon style={{ color: blue[500] }} />
      </IconButton>
      <Menu
        id='lock-menu'
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        MenuListProps={{ 'aria-labelledby': 'lock-button', role: 'listbox', style: { maxHeight: 300, overflow: 'auto' } }}
        anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
      >
        {MenuItems && MenuItems.map((item) => {
          let srcString = item.agb_typ ? typeIcons(item.agb_typ) : typeIcons('LST');
          let id = item.agb_id ? 'AGB' + item.agb_id.toString() : 'LST' + item.grp_id.toString();
          let isCreateable = item.createable;
          return (
            <MenuItem key={item.key} onClick={(e) => handleMenuItemClick(e, item)} id={id}>
              <img src={srcString} alt={`${v.type} icon`} style={{ marginRight: '.5rem' }} />
              {item.grp_name ? item.grp_name : item.agb_name}
              {isCreateable ? (
                <Box marginLeft='auto'>
                  <IconButton size='small' onClick={(e) => { e.stopPropagation(); handleCreateNewItem(e, item); }}>
                    <AddIcon style={{ color: blue[500] }} />
                  </IconButton>
                </Box>
              ) : <></>}
            </MenuItem>
          );
        })}
      </Menu>
    </div>
  ) : null;

  return (
    <RenderTree
      key={v.nodeID}
      node={v}
      nodeID={v.nodeID}
      name={v.name}
      childNode={v.childrens}
      type={v.type}
      expandable={v.isExpandable}
      setIsFav={setIsFav}
      favs={isFav}
      setBers_ids={setBers_ids}
      showFavButton={favButton}  
    />
  );
})}
    </SimpleTreeView>
  );
}
