import { useEffect, useState } from '@wordpress/element';
import { store as blocksStore } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import { Button } from '@wordpress/components';
import { ScrollList } from '@components/ui/ScrollList';
import { Checkbox } from '@components/ui/Checkbox';
import apiFetch from '@wordpress/api-fetch';
import { useBlockSupportStore } from './BlockSupportStore';

import { Button as WordpressButton } from '@components/ui/Button';

import {
  Modal,
  ModalClose,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalTitle,
  ModalTrigger,
} from '@components/ui/Modal';

type Category = {
  key: number;
  name: string;
  value: string;
};

type Categories = {
  name: string;
  values: Category[];
};

type SupportData = {
  disallowed: string[];
  dynamic: string[];
  allowed_dynamic: string[];
};

type SupportDataSave = {
  disallowed: string[];
};

export const initBlockSupport = () => {
  const url = `/blockbite/v1/block-support`;

  apiFetch({ path: url })
    .then((response) => {
      return response;
    })
    .then((data: SupportData) => {
      const { setDisAllowed, setDynamic, setAllowedDynamic } =
        useBlockSupportStore.getState();

      setDisAllowed(data.disallowed);
      setDynamic(data.dynamic);
      setAllowedDynamic(data.allowed_dynamic);
    });
};

export const BlockSupportModal = () => {
  const { disallowed } = useBlockSupportStore();
  const [open, setOpen] = useState(false);
  const [filteredBlocks, setFilteredBlocks] = useState([]);
  const [selectedIds, setSelectedIds] = useState([]);
  const [selection, setSelection] = useState(false);

  const blockTypes = useSelect(
    // @ts-ignore
    (select) => select(blocksStore).getBlockTypes(),
    []
  );

  useEffect(() => {
    if (disallowed !== null) setSelectedIds(disallowed);
  }, disallowed);

  /*
    Create categories outof a flat list of blocks 
  */
  useEffect(() => {
    const categorizedList: Categories[] = [];
    let key = 0;
    blockTypes.forEach((block: any) => {
      const category = block.name.split('/')[0];
      const value = block.name.split('/')[1];
      key += 1;

      const existingCategory = categorizedList.find((c) => c.name === category);
      if (existingCategory) {
        existingCategory.values.push({
          key: key,
          name: value,
          value: block.name,
        });
      } else {
        categorizedList.push({
          name: category,
          values: [{ key: key, name: value, value: block.name } as Category],
        });
      }
    });

    setFilteredBlocks(categorizedList);
  }, [blockTypes]);

  const handleCheckboxChange = (checked: Boolean, value: string) => {
    const setSelectedIds = selectedIds;
    if (checked) {
      setSelectedIds.push(value);
    } else {
      setSelectedIds.splice(selectedIds.indexOf(value), 1);
    }
  };

  const selectAll = () => {
    const allIds = blockTypes.map((block: any) => block.name);
    setSelectedIds(allIds);
  };

  const onSave = () => {
    apiFetch({
      path: `/blockbite/v1/block-support/allowed`,
      method: 'POST',
      data: { blocks: selectedIds },
    }).then((res: SupportDataSave) => {
      setSelectedIds(res.disallowed);
    });
  };

  return (
    <Modal defaultOpen={open} onOpenChange={setOpen}>
      <ModalTrigger>
        <Button variant="primary" className="justify-center">
          Block Support
        </Button>
      </ModalTrigger>
      <ModalContent className="min-h-[640px] sm:max-w-5xl">
        <ModalHeader>
          <ModalTitle>Block Support</ModalTitle>
          <nav className="mt-4 flex w-full flex-wrap gap-4">
            {filteredBlocks.map((category: Categories) => (
              <WordpressButton
                onClick={() =>
                  document.getElementById(category.name)?.scrollIntoView()
                }
                key={category.name}
              >
                {category.name}
              </WordpressButton>
            ))}
          </nav>
        </ModalHeader>
        <ScrollList>
          <div className="mb-8 flex flex-col gap-2">
            <h4 className="text-primary my-4 text-2xl">
              Disable Blockbite Editor for blocks
            </h4>
            {filteredBlocks.map((category: Categories) => (
              <div key={category.name} className="flex flex-col gap-2">
                <h2 id={category.name} className="font-bold">
                  {category.name}
                </h2>
                <div className="grid grid-cols-3 gap-2">
                  {category.values.map((item: any) => (
                    <Checkbox
                      key={item.key}
                      label={item.name}
                      id={item.value}
                      defaultChecked={selectedIds.includes(item.value)}
                      onCheckedChange={(checked: Boolean, value: string) =>
                        handleCheckboxChange(checked, value)
                      }
                    />
                  ))}
                </div>
              </div>
            ))}
          </div>
        </ScrollList>
        <ModalFooter>
          {selection ? (
            <Button
              variant="primary"
              onClick={() => [setSelectedIds([]), setSelection(false)]}
            >
              Deselect All
            </Button>
          ) : (
            <Button
              variant="primary"
              onClick={() => [selectAll(), setSelection(true)]}
            >
              Select All
            </Button>
          )}
          <Button variant="primary" onClick={() => onSave()}>
            Save
          </Button>
          <ModalClose>
            <Button variant="secondary">Cancel</Button>
          </ModalClose>
        </ModalFooter>
      </ModalContent>
    </Modal>
  );
};

export default {
  initBlockSupport,
  BlockSupportModal,
};
