import React, { memo, useEffect, useState, useRef } from 'react';
import { watch, writeFileSync, readFileSync } from 'fs';
import { Spinner } from '@vizality/components';
import { Editor } from '@vizality/components';

export default memo(props => {
  const { builtin, getSetting, updateSetting, popout } = props;
  const [ value, setValue ] = useState(getSetting('customCSS', ''));
  const customCSSFile = builtin._customCSSFilePath;
  const valueGetter = useRef();
  let editor = useRef();
  let model = useRef();

  const _handleMonacoUpdate = async (_evt, val) => {
    try {
      val = val.trim();
      writeFileSync(customCSSFile, val);
      updateSetting('customCSS', val);
    } catch (err) {
      builtin.error(err);
    }
  };

  const _watchFiles = async () => {
    try {
      if (builtin.watcher) return;
      builtin.watcher = watch(customCSSFile, { persistent: false }, async (eventType, filename) => {
        if (!eventType || !filename) {
          return;
        }
        const val = readFileSync(customCSSFile)?.toString();
        if (val !== getSetting('customCSS')) {
          updateSetting('customCSS', val);
        }
        if (val !== value) {
          setValue(val);
        }
      });
    } catch (err) {
      builtin.error(err);
    }
  };

  const handleEditorDidMount = async (_valueGetter, _editor) => {
    try {
      valueGetter.current = _valueGetter;
      editor = _editor;
      model = await editor?.getModel();
      model?.updateOptions({ insertSpaces: true, tabSize: 2 });
      editor?.onDidChangeModelContent(ev => {
        _handleMonacoUpdate(ev, valueGetter.current());
      });
    } catch (err) {
      builtin.error(err);
    }
  };

  useEffect(() => {
    _watchFiles();
  }, []);

  return (
    <Editor
      wrapperClassName='vz-quick-code-editor-wrapper'
      className='vz-quick-code-editor'
      language='scss'
      value={value}
      editorDidMount={handleEditorDidMount}
      loading={<div className='vz-quick-code-loading'>
        <Spinner />
      </div>}
      popout={popout}
      options={{
        minimap: {
          enabled: false
        }
      }}
    />
  );
});
