import React, { useState } from 'react';
import { Editor as MonacoEditor } from '@monaco-editor/react';
import { observer } from 'mobx-react-lite';
import { Instance, onSnapshot, types } from 'mobx-state-tree';
import Css from './editor.module.css';

export const Store = types
  .model({
    loaded: false,
    dashboardId: '',
    visible: false,
    data: '',
  })
  .actions((self) => {
    return {
      setData: (data: string) => {
        self.loaded = true;
        self.data = data;
      },
      show: () => {
        if (!self.loaded) LoadDashboardToStore(self as any);
        self.visible = true;
      },
      hide: () => {
        self.visible = false;
      },
      toggleVisible: () => {
        self.visible = !self.visible;
      },
    };
  })
  .views((self) => {
    return {
      get displayStyle(): React.CSSProperties {
        return { display: self.visible ? 'block' : 'none' };
      },
    };
  });

type IStore = Instance<typeof Store>;

export async function LoadDashboard(dashboardId: string): Promise<string> {
  const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${dashboardId}`;
  const resp = await fetch(url);
  if (!resp || !resp.ok) return '';
  const data = await resp.json();
  const text = JSON.stringify(data, null, '  ');
  return text;
}

export async function LoadDashboardToStore(store: IStore): Promise<void> {
  const data = await LoadDashboard(store.dashboardId);
  if (data) store.setData(data);
}

export async function SaveDashboard(
  dashboardId: string,
  data: string,
): Promise<void> {
  const url = `${process.env.REACT_APP_BACKEND}api/dashboard/${dashboardId}`;
  await fetch(url, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: data,
  });
}

export async function SaveDashboardFromStore(store: IStore): Promise<void> {
  await SaveDashboard(store.dashboardId, store.data);
}

export type Props = {
  store: IStore;
};

export const Editor = observer((props: Props): JSX.Element => {
  const onCloseClick = (e: React.MouseEvent) => {
    if (e.target !== e.currentTarget) return;
    e.stopPropagation();
    props.store.hide();
  };
  const onSaveClick = async (e: React.MouseEvent) => {
    if (e.target !== e.currentTarget) return;
    e.stopPropagation();
    props.store.setData(editorValue);
    await SaveDashboardFromStore(props.store);
    alert('Сохранено');
  };

  const [editorValue, setEditorValue] = useState(props.store.data);
  onSnapshot(props.store, (state) => {
    setEditorValue(state.data);
  });

  return (
    <div className={Css.reset}>
      <div
        className={Css.modal}
        style={props.store.displayStyle}
        onClick={onCloseClick}
      >
        <div className={Css.modalContent}>
          <h1>
            <button onClick={onCloseClick}>close</button>
            <button onClick={onSaveClick}>save</button>
            Редактор дашборда
          </h1>
          <MonacoEditor
            height="80%"
            defaultLanguage="json"
            defaultValue={editorValue}
            value={editorValue}
            onChange={(value) => setEditorValue(value || '')}
            options={{ tabSize: 2, detectIndentation: true }}
          ></MonacoEditor>
        </div>
      </div>
      Editor
    </div>
  );
});
