import { Container } from '@kevisual/container';
import { useEffect, useRef, useState } from 'react';
import { useParams } from 'react-router';
import { query } from '@/modules';

import { message } from '@/modules/message';
export const useListener = (id?: string, opts?: any) => {
  const { refresh } = opts || {};
  const [connected, setConnected] = useState(false);
  // 监听服务器的消息
  useEffect(() => {
    if (!id) return;
    if (!connected) return;
    const ws = query.qws.ws;
    ws.send(
      JSON.stringify({
        type: 'subscribe',
        data: {
          type: 'pageEdit',
          data: {
            cid: id,
            // cids: [],
            // pids:'',
          },
        },
      }),
    );
    ws.addEventListener('message', listener);
    return () => {
      if (!id) return;
      if (!connected) return;
      ws.removeEventListener('message', listener);
    };
  }, [id, connected]);
  const init = async () => {
    query.qws.listenConnect(() => {
      setConnected(true);
    });
  };
  useEffect(() => {
    init();
  }, []);
  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 } = receivedData;
      if (containerData.id !== id) return;
      if (refresh) {
        refresh(containerData);
      }
    }
  };
};
export const Preview = () => {
  const params = useParams<{ id: string }>();
  const id = params.id;
  const ref = useRef<HTMLDivElement>(null);
  const containerRef = useRef<Container | null>(null);

  useEffect(() => {
    if (!id) return;
    fetch();
  }, []);
  const fetch = async () => {
    const res = await query.post({
      path: 'container',
      key: 'get',
      id,
    });
    if (res.code === 200) {
      const data = res.data;
      // setData([data]);
      console.log('data', data);
      const code = {
        id: data.id,
        title: data.title,
        codeId: data.id,
        code: data.code,
        data: data.data,
      };
      init([code]);
    } else {
      message.error(res.message || 'Failed to fetch data');
    }
  };
  const refresh = (data: any) => {
    if (!data.id) return;
    const code = {
      id: data.id,
      title: data.title,
      codeId: data.id,
      code: data.code,
      data: data.data,
      hash: '',
    };
    init([code], true);
  };
  useListener(id, { refresh: refresh });
  const init = async (data: any[], replace: boolean = false) => {
    // console.log('data', data, ref.current);
    if (containerRef.current) {
      const container = containerRef.current;
      console.log('data', data, container.data);
      container.updateData(data);
      await new Promise((resolve) => {
        setTimeout(resolve, 2000);
      });
      console.log('update---data', data, container.data);
      container.destroy(id!);
      container.render(id!);
      return;
    }
    console.log('data', containerRef.current);
    const container = new Container({
      root: ref.current!,
      data: data as any,
    });
    container.render(id!);
    containerRef.current = container;
  };
  return <div className='mx-auto border bg-gray-200 h-full w-full' ref={ref}></div>;
};
export const PreviewWrapper = () => {
  const params = useParams<{ id: string }>();
  const id = params.id;
  const ref = useRef<HTMLDivElement>(null);
  const containerRef = useRef<Container | null>(null);
  useEffect(() => {
    if (!id) return;
    fetch();
  }, []);
  const fetch = async () => {
    const res = await query.post<any, any>({
      path: 'container',
      key: 'get',
      id,
    });
    if (res.code === 200) {
      const data = res.data;
      // setData([data]);
      console.log('data', data);
      const code = {
        id: data.id,
        title: data.title,
        codeId: data.id,
        code: data.code,
        data: data.data,
      };
      init([code]);
    } else {
      message.error(res.message || 'Failed to fetch data');
    }
  };
  const refresh = (data: any) => {
    if (!data.id) return;
    const code = {
      id: data.id,
      title: data.title,
      codeId: data.id,
      code: data.code,
      data: data.data,
      hash: '',
    };
    init([code], true);
  };
  useListener(id, { refresh: refresh });
  const init = async (data: any[], replace: boolean = false) => {
    // console.log('data', data, ref.current);
    if (containerRef.current) {
      const container = containerRef.current;
      console.log('data', data, container.data);
      container.updateData(data);
      await new Promise((resolve) => {
        setTimeout(resolve, 2000);
      });
      console.log('update---data', data, container.data);
      container.destroy(id!);
      container.render(id!);
      return;
    }
    console.log('data', containerRef.current);
    const container = new Container({
      root: ref.current!,
      data: data as any,
    });
    container.render(id!);
    containerRef.current = container;
  };
  return (
    <div className='w-full h-full bg-gray-200'>
      <div className='text-center mb-4 pt-2 font-bold text-4xl '>Preview</div>
      <div
        className='flex '
        style={{
          height: 'calc(100% - 32px)',
        }}>
        <div className='mx-auto border bg-white h-h-full w-[80%] h-[80%] overflow-scroll scrollbar relative' ref={ref}></div>
      </div>
    </div>
  );
};
