import type { ComponentProps, FC } from 'react';
import React, { useEffect, useState } from 'react';
import { EditFilled } from '@ant-design/icons';
import { Tooltip } from 'antd';
import { createStyles } from 'antd-style';
import SourceCodeEditor from 'dumi/theme-default/slots/SourceCodeEditor';

import useLocale from '../../hooks/useLocale';
import LiveError from '../slots/LiveError';

const useStyle = createStyles(({ token, css }) => {
  const { colorBgContainer, colorIcon } = token;

  return {
    editor: css`
      // override dumi editor styles
      .dumi-default-source-code-editor {
        .dumi-default-source-code {
          background: ${colorBgContainer};
        }

        .dumi-default-source-code > pre,
        .dumi-default-source-code-scroll-content > pre,
        .dumi-default-source-code-editor-textarea {
          padding: 12px 16px;
        }

        .dumi-default-source-code > pre,
        .dumi-default-source-code-scroll-content > pre {
          font-size: 13px;
          line-height: 2;
          font-family: 'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        }

        // disable dumi default copy button
        .dumi-default-source-code-copy {
          display: none;
        }

        &::after {
          border-radius: 0 !important;
        }

        &:hover:not(:focus-within) {
          &::after {
            box-shadow: 0 0 0 1px ${token.colorPrimaryBorderHover} inset;
          }
        }
      }
    `,

    editableIcon: css`
      position: absolute;
      z-index: 2;
      height: 32px;
      width: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      top: 16px;
      inset-inline-end: 56px;
      color: ${colorIcon};
    `,
  };
});

const locales = {
  cn: {
    demoEditable: '编辑 Demo 可实时预览',
  },
  en: {
    demoEditable: 'Edit demo with real-time preview',
  },
};

const HIDE_LIVE_DEMO_TIP = 'hide-live-demo-tip';

const LiveCode: FC<
  {
    error: Error | null;
  } & Pick<ComponentProps<typeof SourceCodeEditor>, 'lang' | 'initialValue' | 'onChange'>
> = (props) => {
  const [open, setOpen] = useState(false);
  const { styles } = useStyle();
  const [locale] = useLocale(locales);

  useEffect(() => {
    const shouldOpen = !localStorage.getItem(HIDE_LIVE_DEMO_TIP);
    if (shouldOpen) {
      setOpen(true);
    }
  }, []);

  const handleOpenChange = (newOpen: boolean) => {
    setOpen(newOpen);
    if (!newOpen) {
      localStorage.setItem(HIDE_LIVE_DEMO_TIP, 'true');
    }
  };

  return (
    <>
      <div className={styles.editor}>
        <SourceCodeEditor
          lang={props.lang}
          initialValue={props.initialValue}
          onChange={props.onChange}
        />
        <LiveError error={props.error} />
      </div>
      <Tooltip title={locale.demoEditable} open={open} onOpenChange={handleOpenChange}>
        <EditFilled className={styles.editableIcon} />
      </Tooltip>
    </>
  );
};

export default LiveCode;