import { create } from 'zustand';
import { produce } from 'immer';
import { query } from '@/modules';
import { message } from 'antd';

type QueryPath = {
  key?: string;
  path?: string;
};
export type ParseData = {
  updatePath: QueryPath;
  data?: string | Object;
};
type CodeEditorStore = {
  code: string;
  type: string; // javascript, json
  setCode: (code: string) => void;
  loading: boolean;
  setLoading: (loading: boolean) => void;
  data: any;
  dataType: string | Object;
  setData: (data: any) => void;
  updatePath: QueryPath;
  setUpdatePath: (updatePath: any) => void;
  onUpdate: (data: string) => Promise<any>;
  init: (parseData: { updatePath: QueryPath; data?: string | Object }) => void;
};
export const useCodeEditorStore = create<CodeEditorStore>((set, get) => ({
  code: '',
  type: 'javascript',
  setCode: (code: string) => set({ code }),
  loading: false,
  setLoading: (loading: boolean) => set({ loading }),
  data: {},
  dataType: 'json',
  setData: (data: any) => set({ data }),
  updatePath: {},
  setUpdatePath: (updatePath) => set({ updatePath }),
  onUpdate: async (data: string) => {
    const { updatePath, dataType } = get();
    const { path, key } = updatePath;
    let _newData = data;
    if (dataType === 'object') {
      try {
        _newData = JSON.parse(data);
      } catch (error) {
        console.error(error);
        return;
      }
    } else if (dataType === 'string') {
      _newData = data;
    }
    if (path && key) {
      const load = message.loading('loading...', 0);

      const res = await query.post({ path, key, data: _newData });
      load();
      if (res.code === 200) {
        message.success('success');
        set(
          produce((state) => {
            state.data = res.data;
          }),
        );
      }
    }
  },
  init({ updatePath, data }) {
    if (typeof data === 'string' && data) {
      set(
        produce((state) => {
          state.code = data;
          state.data = data;
          state.dataType = 'string';
          state.updatePath = updatePath;
        }),
      );
    } else if (typeof data === 'object' && data) {
      set(
        produce((state) => {
          state.data = data;
          state.code = JSON.stringify(data, null, 2);
          state.dataType = 'object';
          state.updatePath = updatePath;
        }),
      );
    }
  },
}));
