import { KintoneRestAPIClient } from '@kintone/rest-api-client';
import moize from 'moize';
import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { loadConfig, type PluginConfig } from '../common/config';
import ErrorFallback from '../common/ErrorFallback';
import Loading from '../common/Loading';
import type { KintoneFormFieldProperties } from '../common/types';
import { checkConfig } from './checkConfig';
import MenuPanel from './MenuPanel';

interface DesktopAppProps {
  pluginId: string;
  event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent;
}

const cachedFormFieldsProperties = moize.promise(async (appId: number): Promise<KintoneFormFieldProperties> => {
  const client = new KintoneRestAPIClient();
  const { properties } = await client.app.getFormFields({ app: appId, preview: false });
  return properties;
});

const cachedConfigCheck = moize.promise(
  async (config: PluginConfig, record: kintone.types.SavedFields): Promise<string> => {
    return await checkConfig(config, record);
  },
);

const DesktopApp: React.FC<DesktopAppProps> = (props) => {
  const { pluginId, event } = props;

  const config = loadConfig(pluginId);
  const propertiesPromise = cachedFormFieldsProperties(event.appId);
  const fileKeyPromise = cachedConfigCheck(config, event.record);

  return (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <React.Suspense fallback={<Loading />}>
        <MenuPanel
          pluginId={pluginId}
          event={event}
          propertiesPromise={propertiesPromise}
          fileKeyPromise={fileKeyPromise}
        />
      </React.Suspense>
    </ErrorBoundary>
  );
};
export default DesktopApp;
