import {
  ActionResponseType,
  EditorLanguage,
  FormComponentType,
  InputDataType,
  Plugin,
  PluginResponseType,
  PluginType
} from '../../types/index.js';
import { SERVICE_ACCOUNT_GHOST_TEXT, PUBLIC_INTEGRATIONS_LOGO_URL, DOCS_BASE_URL } from './constants.js';
import { S3ActionType } from './s3.js';

const GCSPluginVersions = {
  V1: '0.0.1'
};

enum GCSActionType {
  LIST_OBJECTS = 'LIST_OBJECTS',
  GET_OBJECT = 'GET_OBJECT',
  DELETE_OBJECT = 'DELETE_OBJECT',
  UPLOAD_OBJECT = 'UPLOAD_OBJECT',
  LIST_BUCKETS = 'LIST_BUCKETS',
  CREATE_BUCKET = 'CREATE_BUCKET',
  UPLOAD_MULTIPLE_OBJECTS = 'UPLOAD_MULTIPLE_OBJECTS',
  GENERATE_PRESIGNED_URL = 'GENERATE_PRESIGNED_URL'
}

const GCS_ACTION_DISPLAY_NAMES: Record<GCSActionType, string> = {
  [GCSActionType.LIST_OBJECTS]: 'List files',
  [GCSActionType.GET_OBJECT]: 'Read file',
  [GCSActionType.DELETE_OBJECT]: 'Delete file',
  [GCSActionType.UPLOAD_OBJECT]: 'Upload file',
  [GCSActionType.LIST_BUCKETS]: 'List buckets',
  [GCSActionType.CREATE_BUCKET]: 'Create bucket',
  [GCSActionType.UPLOAD_MULTIPLE_OBJECTS]: 'Upload multiple files',
  [GCSActionType.GENERATE_PRESIGNED_URL]: 'Generate presigned URL'
};

const DEFAULT_GCS_PRESIGNED_URL_EXPIRATION_SECONDS = 60 * 10;

export const GCSPlugin: Plugin = {
  id: 'gcs',
  name: 'Google Cloud Storage',
  moduleName: 'GCSPlugin',
  modulePath: 'plugins/gcs/GCSPlugin',
  iconLocation: `${PUBLIC_INTEGRATIONS_LOGO_URL}/gcs.png`,
  docsUrl: `${DOCS_BASE_URL}/google-cloud-storage`,
  type: PluginType.API,
  responseType: PluginResponseType.JSON,
  hasRawRequest: true,
  hasMetadata: true,
  rawRequestName: 'Executed action',
  datasourceTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            label: 'Display name',
            name: 'name',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.INPUT_TEXT,
            rules: [{ required: true, message: 'Display name is required' }]
          },
          {
            label: 'Service account key',
            name: 'authentication.custom.googleServiceAccount.value',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.JSON,
            placeholder: SERVICE_ACCOUNT_GHOST_TEXT,
            rules: [{ required: true, message: 'Service account key is required' }]
          }
        ]
      }
    ]
  },
  actionTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            label: 'Action',
            name: 'action',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DROPDOWN,
            initialValue: GCSActionType.GET_OBJECT,
            rules: [{ required: true }],
            options: [
              {
                key: GCSActionType.LIST_OBJECTS,
                value: GCSActionType.LIST_OBJECTS,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.LIST_OBJECTS]
              },
              {
                key: GCSActionType.GET_OBJECT,
                value: GCSActionType.GET_OBJECT,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.GET_OBJECT]
              },
              {
                key: GCSActionType.DELETE_OBJECT,
                value: GCSActionType.DELETE_OBJECT,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.DELETE_OBJECT]
              },
              {
                key: GCSActionType.UPLOAD_OBJECT,
                value: GCSActionType.UPLOAD_OBJECT,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.UPLOAD_OBJECT]
              },
              {
                key: GCSActionType.UPLOAD_MULTIPLE_OBJECTS,
                value: GCSActionType.UPLOAD_MULTIPLE_OBJECTS,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.UPLOAD_MULTIPLE_OBJECTS]
              },
              {
                key: GCSActionType.LIST_BUCKETS,
                value: GCSActionType.LIST_BUCKETS,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.LIST_BUCKETS]
              },
              {
                key: GCSActionType.GENERATE_PRESIGNED_URL,
                value: GCSActionType.GENERATE_PRESIGNED_URL,
                displayName: GCS_ACTION_DISPLAY_NAMES[GCSActionType.GENERATE_PRESIGNED_URL]
              }
            ]
          },
          {
            label: 'Bucket name prefix (optional)',
            name: 'prefix',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DYNAMIC_INPUT_TEXT,
            display: {
              show: {
                action: [GCSActionType.LIST_BUCKETS]
              }
            }
          },
          {
            label: 'Bucket name',
            name: 'resource',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DYNAMIC_INPUT_TEXT,
            display: {
              show: {
                action: [
                  GCSActionType.LIST_OBJECTS,
                  GCSActionType.GET_OBJECT,
                  GCSActionType.UPLOAD_OBJECT,
                  GCSActionType.DELETE_OBJECT,
                  GCSActionType.UPLOAD_MULTIPLE_OBJECTS,
                  GCSActionType.GENERATE_PRESIGNED_URL
                ]
              }
            }
          },
          {
            label: 'File prefix (optional)',
            name: 'prefix',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DYNAMIC_INPUT_TEXT,
            display: {
              show: {
                action: [GCSActionType.LIST_OBJECTS]
              }
            }
          },
          {
            label: 'File name',
            name: 'path',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DYNAMIC_INPUT_TEXT,
            display: {
              show: {
                action: [
                  GCSActionType.UPLOAD_OBJECT,
                  GCSActionType.GET_OBJECT,
                  GCSActionType.DELETE_OBJECT,
                  GCSActionType.GENERATE_PRESIGNED_URL
                ]
              }
            }
          },
          {
            name: 'responseType',
            label: 'File content type',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.DROPDOWN,
            initialValue: ActionResponseType.AUTO,
            display: {
              show: {
                action: [S3ActionType.GET_OBJECT]
              }
            },
            options: [
              {
                key: ActionResponseType.AUTO,
                value: ActionResponseType.AUTO,
                displayName: 'Auto'
              },
              {
                key: ActionResponseType.JSON,
                value: ActionResponseType.JSON,
                displayName: 'JSON'
              },
              {
                key: ActionResponseType.TEXT,
                value: ActionResponseType.TEXT,
                displayName: 'Text'
              },
              {
                key: ActionResponseType.BINARY,
                value: ActionResponseType.BINARY,
                displayName: 'Binary'
              }
            ]
          },
          {
            label: 'File content',
            name: 'body',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.TEXT,
            display: {
              show: {
                action: [GCSActionType.UPLOAD_OBJECT]
              }
            }
          },
          {
            label: 'File objects array',
            name: 'fileObjects',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.TEXT,
            placeholder: `File objects represent a Superblocks file entity.

Access the files from {{FilePicker1.files}}, or manipulate the files using:

{{FilePicker1.files.map((file) => ({
  ...file,
  name: 'user-assets/' + file.name,
}))}}
            `,
            display: {
              show: {
                action: [GCSActionType.UPLOAD_MULTIPLE_OBJECTS]
              }
            }
          },
          {
            label: 'Presigned URL expiration (seconds)',
            name: 'custom.presignedExpiration.value',
            startVersion: GCSPluginVersions.V1,
            componentType: FormComponentType.INPUT_TEXT,
            initialValue: DEFAULT_GCS_PRESIGNED_URL_EXPIRATION_SECONDS,
            dataType: InputDataType.NUMBER,
            display: {
              show: {
                action: [GCSActionType.GENERATE_PRESIGNED_URL]
              }
            }
          }
        ]
      }
    ]
  }
};
