import {
  ActionResponseType,
  EditorLanguage,
  ExtendedIntegrationPluginId,
  FormComponentType,
  FormSectionLayout,
  GENERIC_HTTP_REQUEST,
  HttpMethod,
  IntegrationAuthType,
  Plugin,
  PluginResponseType,
  PluginType,
  RestApiBodyDataType,
  RestApiFields,
  getDisplayName,
  getMethodColor,
  getRestApiBodyLabel,
  getRestApiDataTypeDisplayName,
  getRestApiFieldDisplayName
} from '../../types/index.js';
import { PUBLIC_INTEGRATIONS_LOGO_URL, DOCS_BASE_URL } from './constants.js';
import { RestApiIntegrationPluginMergedFieldNames, RestApiIntegrationPluginVersions, authSections } from './shared/index.js';

export const RestApiIntegrationPlugin: Plugin = {
  id: ExtendedIntegrationPluginId.REST_API,
  name: 'REST API',
  moduleName: 'RestApiIntegrationPlugin',
  modulePath: 'plugins/restApiIntegration/RestApiIntegrationPlugin',
  iconLocation: `${PUBLIC_INTEGRATIONS_LOGO_URL}/restapi.png`,
  docsUrl: `${DOCS_BASE_URL}/rest-api`,
  isStreamable: true,
  type: PluginType.API,
  responseType: PluginResponseType.JSON,
  hasRawRequest: true,
  hasTest: false,
  datasourceTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            label: 'Display name',
            name: 'name',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.INPUT_TEXT,
            placeholder: 'Example API',
            rules: [{ required: true, message: 'Display name is required' }]
          },
          {
            name: 'urlBase',
            label: 'Base URL',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.DYNAMIC_INPUT_WITH_METADATA_OPTIONS,
            placeholder: 'https://www.example.com/api',
            rules: [{ required: true, message: 'Base URL is required' }],
            valueAccessor: 'url',
            listAccessor: 'metadata.openApiSpec.servers'
          },
          {
            label: 'OpenAPI spec name',
            name: 'openApiSpecRef',
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.INPUT_TEXT,
            hidden: true
          }
        ]
      },
      ...authSections({
        startVersion: RestApiIntegrationPluginVersions.V1,
        pluginId: ExtendedIntegrationPluginId.REST_API,
        pluginName: 'REST API',
        enabledMethods: {
          basic: true,
          firebase: true,
          oauth: true,
          bearer: true,
          apiKey: true
        }
      }),
      {
        name: 'tabs',
        layout: FormSectionLayout.TABS,
        items: [
          {
            name: RestApiIntegrationPluginMergedFieldNames.HEADERS,
            label: 'Headers',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.FIELD_LIST,
            secretsNames: ['Authorization']
          },
          {
            name: RestApiIntegrationPluginMergedFieldNames.PARAMS,
            label: 'Params',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.FIELD_LIST
          }
        ]
      }
    ]
  },
  actionTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            name: 'openApiAction',
            label: 'Action',
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.OPENAPI_ACTION_DROPDOWN,
            initialValue: GENERIC_HTTP_REQUEST
          },
          {
            gridCss: {
              gridTemplateColumns: '120px calc(100% - 130px)'
            },
            rowItems: [
              {
                name: RestApiFields.HTTP_METHOD,
                label: '',
                startVersion: RestApiIntegrationPluginVersions.V1,
                componentType: FormComponentType.DROPDOWN,
                initialValue: HttpMethod.GET,
                rules: [{ required: true }],
                renderSelectedOptionWithStyles: true,
                options: [
                  {
                    key: HttpMethod.GET,
                    value: HttpMethod.GET,
                    displayName: HttpMethod.GET,
                    textColor: getMethodColor(HttpMethod.GET)
                  },
                  {
                    key: HttpMethod.POST,
                    value: HttpMethod.POST,
                    displayName: HttpMethod.POST,
                    textColor: getMethodColor(HttpMethod.POST)
                  },
                  {
                    key: HttpMethod.PUT,
                    value: HttpMethod.PUT,
                    displayName: HttpMethod.PUT,
                    textColor: getMethodColor(HttpMethod.PUT)
                  },
                  {
                    key: HttpMethod.DELETE,
                    value: HttpMethod.DELETE,
                    displayName: HttpMethod.DELETE,
                    textColor: getMethodColor(HttpMethod.DELETE)
                  },
                  {
                    key: HttpMethod.PATCH,
                    value: HttpMethod.PATCH,
                    displayName: HttpMethod.PATCH,
                    textColor: getMethodColor(HttpMethod.PATCH)
                  }
                ]
              },
              {
                name: RestApiFields.URL_PATH,
                label: '',
                startVersion: RestApiIntegrationPluginVersions.V1,
                componentType: FormComponentType.URL_INPUT_TEXT,
                placeholder: '/v1/users'
              }
            ]
          }
        ]
      },
      {
        name: 'auth',
        items: [
          {
            name: RestApiFields.AUTH_TYPE,
            label: getRestApiFieldDisplayName(RestApiFields.AUTH_TYPE),
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.DROPDOWN,
            disabled: true,
            hidden: true,
            initialValue: IntegrationAuthType.NONE,
            options: Object.values(IntegrationAuthType).map((authType) => ({
              displayName: getDisplayName(authType),
              value: authType,
              key: authType
            }))
          }
        ]
      },
      {
        name: 'tabs',
        layout: FormSectionLayout.TABS,
        items: [
          {
            name: RestApiIntegrationPluginMergedFieldNames.HEADERS,
            label: 'Headers',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.FIELD_LIST,
            collapseValue: 'Hide auto-generated headers'
          },
          {
            name: RestApiIntegrationPluginMergedFieldNames.PARAMS,
            label: 'Query parameters',
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.FIELD_LIST,
            collapseValue: 'Hide auto-generated parameters'
          },
          {
            name: RestApiFields.BODY,
            label: getRestApiFieldDisplayName(RestApiFields.BODY),
            startVersion: RestApiIntegrationPluginVersions.V1,
            endVersion: RestApiIntegrationPluginVersions.V7,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.JSON
          },
          {
            name: RestApiFields.BODY_TYPE,
            label: getRestApiFieldDisplayName(RestApiFields.BODY_TYPE),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.DROPDOWN,
            initialValue: RestApiBodyDataType.JSON,
            options: Object.values(RestApiBodyDataType).map((bodyType) => ({
              displayName: getRestApiDataTypeDisplayName(bodyType),
              value: bodyType,
              key: bodyType
            }))
          },
          {
            name: RestApiFields.BODY,
            label: getRestApiBodyLabel(RestApiBodyDataType.JSON),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.JSON,
            display: {
              show: {
                bodyType: [RestApiBodyDataType.JSON]
              }
            }
          },
          {
            name: RestApiFields.BODY,
            label: getRestApiBodyLabel(RestApiBodyDataType.RAW),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.TEXT,
            display: {
              show: {
                bodyType: [RestApiBodyDataType.RAW]
              }
            }
          },
          {
            name: RestApiFields.FORM_DATA,
            label: getRestApiBodyLabel(RestApiBodyDataType.FORM),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.FIELD_LIST_FORM,
            display: {
              show: {
                bodyType: [RestApiBodyDataType.FORM]
              }
            }
          },
          {
            name: RestApiFields.FILE_FORM_KEY,
            label: getRestApiFieldDisplayName(RestApiFields.FILE_FORM_KEY),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.INPUT_TEXT,
            initialValue: 'file',
            display: {
              show: {
                bodyType: [RestApiBodyDataType.FILE_FORM]
              }
            }
          },
          {
            name: RestApiFields.FILE_NAME,
            label: getRestApiFieldDisplayName(RestApiFields.FILE_NAME),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.INPUT_TEXT,
            display: {
              show: {
                bodyType: [RestApiBodyDataType.FILE_FORM]
              }
            }
          },
          {
            name: RestApiFields.BODY,
            label: getRestApiBodyLabel(RestApiBodyDataType.FILE_FORM),
            startVersion: RestApiIntegrationPluginVersions.V8,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.TEXT,
            display: {
              show: {
                bodyType: [RestApiBodyDataType.FILE_FORM]
              }
            }
          }
        ]
      },
      {
        name: 'bottom',
        items: [
          {
            name: RestApiFields.RESPONSE_TYPE,
            label: getRestApiFieldDisplayName(RestApiFields.RESPONSE_TYPE),
            startVersion: RestApiIntegrationPluginVersions.V1,
            componentType: FormComponentType.DROPDOWN,
            initialValue: ActionResponseType.AUTO,
            rules: [{ required: true }],
            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'
              },
              {
                key: ActionResponseType.RAW,
                value: ActionResponseType.RAW,
                displayName: 'Raw'
              }
            ]
          }
        ]
      },
      {
        name: 'additionalSettings',
        sectionHeader: 'Additional Settings',
        isCollapsible: true,
        defaultCollapsed: true,
        asTitle: false,
        items: [
          {
            name: RestApiFields.VERBOSE_HTTP_OUTPUT,
            label: getRestApiFieldDisplayName(RestApiFields.VERBOSE_HTTP_OUTPUT),
            lightLabelText: true,
            startVersion: RestApiIntegrationPluginVersions.V14,
            componentType: FormComponentType.SWITCH,
            initialValue: false,
            showConfirm: false,
            renderIconFirst: true
          },
          {
            name: RestApiFields.DO_NOT_FAIL_ON_REQUEST_ERROR,
            label: getRestApiFieldDisplayName(RestApiFields.DO_NOT_FAIL_ON_REQUEST_ERROR),
            lightLabelText: true,
            startVersion: RestApiIntegrationPluginVersions.V14,
            componentType: FormComponentType.SWITCH,
            initialValue: false,
            showConfirm: false,
            renderIconFirst: true,
            inverseValue: true
          }
        ]
      }
    ]
  }
};
