import { Container, ContainerEdit } from '@abearxiong/container';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useParams } from 'react-router';
import { query, useStore, ws } from '@/modules';
import { Button, message, Tooltip } from 'antd';
import { getContainerData } from '@/modules/deck-to-flow/deck';
import { usePanelStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { TextArea } from '@/pages/container/components/TextArea';
import { CloseOutlined, MessageOutlined, SaveOutlined, SelectOutlined } from '@ant-design/icons';
import { useDeckPageStore } from './deck-store';
import { FormModal } from './Model.tsx';
import { useAiStore } from '@/pages/ai-chat/index.tsx';

export const useListener = (id?: string, opts?: any) => {
  const { refresh } = opts || {};
  const connected = useStore((state) => state.connected);
  // 监听服务器的消息
  useEffect(() => {
    if (!id) return;
    if (!connected) return;
    ws.send(
      JSON.stringify({
        type: 'subscribe',
        data: {
          type: 'pageEdit',
          data: {
            pid: id,
            cids: ['170c0b55-8c13-4d6e-bf35-3f935d979a0d'],
          },
        },
      }),
    );
    ws.addEventListener('message', listener);
    return () => {
      if (!id) return;
      if (!connected) return;
      ws.removeEventListener('message', listener);
    };
  }, [id, connected]);
  const listener = (event) => {
    const parseIfJson = (data: string) => {
      try {
        return JSON.parse(data);
      } catch (e) {
        return data;
      }
    };
    const receivedData = parseIfJson(event.data);
    if (typeof receivedData === 'string') return;
    if (receivedData.type === 'pageEdit' && receivedData.source === 'container') {
      const { data: containerData, pid } = receivedData;
      if (pid !== id) return;
      if (refresh) {
        refresh(containerData);
      }
    }
  };
};
const getParent = (data: { children?: string[]; [key: string]: any }[], id: string, list: string[]) => {
  for (let item of data) {
    if (item.children?.includes(id)) {
      // 找到了当前的父亲节点
      list.unshift(item.id);
      getParent(data, item.id, list);
      return;
    }
  }
  return;
};

export const Deck = () => {
  const params = useParams<{ id: string }>();
  const id = params.id;
  const ref = useRef<HTMLDivElement>(null);
  const containerRef = useRef<ContainerEdit | null>(null);
  const deckPageStore = useDeckPageStore();
  const { code, setCode } = deckPageStore;
  const { selected, setSelected } = deckPageStore;
  const aiStore = useAiStore(
    useShallow((state) => {
      return {
        setOpen: state.setOpen,
        setKey: state.setKey,
      };
    }),
  );
  const panelStore = usePanelStore(
    useShallow((state) => {
      return {
        updateNodeDataStyle: state.updateNodeDataStyle,
      };
    }),
  );
  useEffect(() => {
    if (!id) return;
    deckPageStore.setId(id);
    fetch();
  }, []);
  useEffect(() => {
    ref.current?.addEventListener('onContainer', onContainer);
    return () => {
      ref.current?.removeEventListener('onContainer', onContainer);
      if (ref.current) {
        const children = ref.current;
        children.innerHTML = '';
      }
    };
  }, []);
  const fetch = async () => {
    const res = await query.post({
      path: 'page',
      key: 'getDeck',
      id,
    });
    if (res.code === 200) {
      const data = res.data;
      console.log('data', data);
      const { page, containerList } = data;
      const result = getContainerData({ page, containerList });
      deckPageStore.setPageData(result);
      init(result);
    }
  };
  const refresh = async (data: any) => {
    console.log('refresh', data);
    if (!data.id) return;
    const code = {
      codeId: data.id,
      code: data.code,
      hash: '',
    };
    const container = containerRef.current!;
    // @ts-ignore
    await container.updateDataCode([code]);
    const containerList = container.data.filter((item) => item.codeId === data.id);
    await new Promise((resolve) => {
      setTimeout(resolve, 2000);
    });
    console.log('containerList update', containerList);
    // container.reRender();
    containerList.forEach((item) => {
      container.hotReload(item.id);
    });
    // @ts-ignore
    window.c = container;
  };
  useListener(id, { refresh });
  const onContainer = (e) => {
    const { data } = e;
    const types = ['position', 'resize'];
    if (types.includes(data.type)) {
      const { type, data: containerData } = data;
      if (type === 'position') {
        const { cid, left, top, rid } = containerData;
        const newData = {
          id: rid,
          nodeData: {
            id: cid,
            data: {
              style: {
                // position: 'absolute',
                left,
                top,
              },
            },
          },
        };
        if (left && top) {
          panelStore.updateNodeDataStyle(newData);
        }
        updateStyle(cid, { left, top });
        setTimeout(() => {
          setCodeStyle(cid);
        }, 1000);
      } else if (type === 'resize') {
        const { cid, rid, width, height } = containerData;
        const newData = {
          id: rid,
          nodeData: {
            id: cid,
            data: {
              style: {
                width,
                height,
              },
            },
          },
        };
        if (width && height) {
          panelStore.updateNodeDataStyle(newData);
        }
        updateStyle(cid, { width, height });
        setTimeout(() => {
          setCodeStyle(cid);
        }, 1000);
      }
    } else if (data.type === 'active') {
      if (!data?.data?.cid) {
        setSelected(null);
        return;
      }
      const { cid, rid } = data?.data || {};
      setSelected(data);
      setCodeStyle(cid);
    } else {
      console.log('onContainer', data);
    }
  };
  const onSave = () => {
    const { cid, rid } = selected?.data || {};
    let data: any;
    try {
      data = JSON.parse(code);
    } catch (error) {
      message.error('JSON format error');
      return;
    }
    const newData = {
      id: rid,
      nodeData: {
        id: cid,
        data: {
          style: data,
        },
      },
    };
    panelStore.updateNodeDataStyle(newData);
  };
  const setCodeStyle = (cid: string) => {
    const pageData = deckPageStore.getPageData();
    const selected = deckPageStore.getSeleted();
    const _data = pageData.find((item) => item.id === cid);
    const node = _data?.data?.node || {};
    if (selected?.data?.cid === cid) {
      setCode('');
      setCode(JSON.stringify(node?.data?.style || {}, null, 2));
    }
  };
  useEffect(() => {
    if (selected) {
      const { cid } = selected?.data || {};
      cid && setCodeStyle(cid);
    }
  }, [deckPageStore.selected]);

  const updateStyle = (rid: string, style: any) => {
    const pageData = deckPageStore.getPageData();
    const _pageData = pageData.map((item) => {
      if (item.id === rid) {
        return {
          ...item,
          data: {
            ...item.data,
            node: {
              ...item.data.node,
              data: {
                ...item.data.node.data,
                style: {
                  ...item.data.node.data.style,
                  ...style,
                },
              },
            },
          },
        };
      }
      return item;
    });
    deckPageStore.setPageData([..._pageData]);
  };
  const init = async (data: any[]) => {
    // console.log('data', data, ref.current);
    const container = new ContainerEdit({
      root: ref.current!,
      data: data,
      showChild: true,
      // edit: false,
    });
    container.render(id!);
    containerRef.current = container;
    containerRef.current.event.on('save', (data) => {
      console.log('save', data);
      const { id, code } = data;
    });
  };
  return (
    <div className='w-full h-full relative'>
      <div className='w-full h-full bg-gray-200 '>
        <div className='text-center mb-10 font-bold text-4xl pt-4 flex items-center justify-center group'>
          Deck
          <Tooltip>
            <Button
              className='ml-4 hidden group-hover:block'
              icon={<SelectOutlined />}
              onClick={() => {
                deckPageStore.setShowEdit(true);
              }}></Button>
          </Tooltip>
        </div>
        <div
          className='flex '
          style={{
            height: 'calc(100% - 32px)',
          }}>
          <div className='mx-auto border  rounded-md bg-white  w-[80%] h-[80%] scrollbar overflow-scroll relative' ref={ref}></div>
        </div>
      </div>
      {selected && (
        <div className='absolute bottom-5 z-50 w-full h-[200px]'>
          <div className=' p-2 card w-[80%]  mx-auto border bg-slate-200 rounded-md overflow-scroll scrollbar'>
            {/* <pre>{JSON.stringify(selected, null, 2)}</pre> */}
            <div>
              <Button.Group>
                <Tooltip title='Close'>
                  <Button
                    onClick={() => {
                      setSelected(null);
                    }}
                    icon={<CloseOutlined />}></Button>
                </Tooltip>
                <Tooltip title='Ai Chat'>
                  <Button
                    onClick={() => {
                      aiStore.setOpen(true);
                      aiStore.setKey(location.pathname);
                    }}
                    icon={<MessageOutlined />}></Button>
                </Tooltip>
                <Tooltip title='Save'>
                  <Button
                    onClick={() => {
                      onSave();
                    }}
                    icon={<SaveOutlined />}></Button>
                </Tooltip>
              </Button.Group>
            </div>
            <div className='h-[200px]'>
              <TextArea className='h-[100px] rounded-md' value={code} />
            </div>
          </div>
        </div>
      )}
      <FormModal />
    </div>
  );
};
