import { EditorLanguage, FormComponentType, InputDataType, Plugin, PluginResponseType, PluginType, FormItem } from '../../types/index.js';
import {
  PARAMETERIZED_SQL_DESCRIPTION,
  SERVICE_ACCOUNT_GHOST_TEXT,
  SQL_INITIAL_TEXT,
  PUBLIC_INTEGRATIONS_LOGO_URL,
  DOCS_BASE_URL
} from './constants.js';
import { makeDropdownItem } from './shared/db.js';

const BigQueryPluginVersions = {
  V1: '0.0.1',
  V2: '0.0.2',
  V6: '0.0.6',
  V7: '0.0.7',
  V8: '0.0.8',
  V9: '0.0.9'
};

enum ConnectionType {
  SERVICE_ACCOUNT_KEY = 'service-account-key',
  WORKFORCE_IDENTITY_FEDERATION = 'oauth-token-exchange'
}

const CONNECTION_METHODS_AND_DISPLAY_NAMES = {
  [ConnectionType.SERVICE_ACCOUNT_KEY]: 'Service Account Key',
  [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]: 'Workforce Identity Federation'
};

const BASE_SUBJECT_TOKEN_SOURCE = {
  label: 'Subject token source',
  name: 'authConfig.subjectTokenSource',
  componentType: FormComponentType.DROPDOWN,
  initialValue: 'SUBJECT_TOKEN_SOURCE_LOGIN_IDENTITY_PROVIDER',
  rules: [{ required: true, message: 'Subject token source is required' }],
  options: [
    makeDropdownItem('SUBJECT_TOKEN_SOURCE_LOGIN_IDENTITY_PROVIDER', 'Login Identity Provider'),
    makeDropdownItem('SUBJECT_TOKEN_SOURCE_STATIC_TOKEN', 'Static Token')
  ]
};

const BASE_STATIC_TOKEN = {
  label: 'Subject token',
  name: 'authConfig.subjectTokenSourceStaticToken',
  componentType: FormComponentType.INPUT_TEXT,
  dataType: InputDataType.PASSWORD,
  rules: [{ required: true, message: 'Static token is required when using static token source' }]
};

const BASE_WORKFORCE_POOL_ID = {
  label: 'Workforce Pool ID',
  name: 'authConfig.workforcePoolId',
  componentType: FormComponentType.INPUT_TEXT,
  placeholder: 'my-workforce-pool',
  rules: [{ required: true, message: 'Workforce Pool ID is required' }],
  tooltip: {
    markdownText: 'The workforce identity pool ID (POOL_ID)'
  }
};

const BASE_WORKFORCE_PROVIDER_ID = {
  label: 'Workforce Provider ID',
  name: 'authConfig.workforceProviderId',
  componentType: FormComponentType.INPUT_TEXT,
  placeholder: 'my-provider',
  rules: [{ required: true, message: 'Workforce Provider ID is required' }],
  tooltip: {
    markdownText: 'The workforce identity pool provider ID (PROVIDER_ID)'
  }
};

const BASE_PROJECT_ID = {
  label: 'Project ID',
  name: 'authConfig.projectId',
  componentType: FormComponentType.INPUT_TEXT,
  placeholder: 'my-gcp-project',
  rules: [{ required: true, message: 'Project ID is required' }],
  tooltip: {
    markdownText: 'The GCP project ID where BigQuery queries will run'
  }
};

const BASE_BILLING_PROJECT_NUMBER = {
  label: 'Billing Project Number',
  name: 'authConfig.billingProjectNumber',
  componentType: FormComponentType.INPUT_TEXT,
  placeholder: '123456789012',
  rules: [{ required: false }],
  tooltip: {
    markdownText: 'Optional. The project number used for quota attribution during token exchange'
  }
};

const HIDDEN_TOKEN_URL = {
  label: 'Token URL',
  name: 'authConfig.tokenUrl',
  componentType: FormComponentType.INPUT_TEXT,
  hidden: true,
  initialValue: 'https://sts.googleapis.com/v1/token',
  rules: [{ required: false }]
};

const HIDDEN_SCOPE = {
  label: 'Scope',
  name: 'authConfig.scope',
  componentType: FormComponentType.INPUT_TEXT,
  hidden: true,
  initialValue: 'https://www.googleapis.com/auth/bigquery',
  rules: [{ required: false }]
};

const HIDDEN_SUBJECT_TOKEN_TYPE = {
  label: 'Subject token type',
  name: 'authConfig.subjectTokenType',
  componentType: FormComponentType.INPUT_TEXT,
  hidden: true,
  initialValue: 'urn:ietf:params:oauth:token-type:id_token',
  rules: [{ required: false }]
};

const COMPUTED_AUDIENCE = {
  label: 'Audience',
  name: 'authConfig.audience',
  componentType: FormComponentType.INPUT_TEXT,
  hidden: true,
  rules: [{ required: false }]
};

export const BigQueryPlugin: Plugin = {
  id: 'bigquery',
  name: 'Google BigQuery',
  moduleName: 'BigqueryPlugin',
  modulePath: 'plugins/bigquery/BigqueryPlugin',
  iconLocation: `${PUBLIC_INTEGRATIONS_LOGO_URL}/bigquery.png`,
  docsUrl: `${DOCS_BASE_URL}/google-bigquery`,
  type: PluginType.DB,
  responseType: PluginResponseType.TABLE,
  hasRawRequest: true,
  hasMetadata: true,
  rawRequestName: 'Executed SQL',
  datasourceTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            label: 'Display name',
            name: 'name',
            startVersion: BigQueryPluginVersions.V1,
            componentType: FormComponentType.INPUT_TEXT,
            placeholder: 'BigQuery Production',
            rules: [{ required: true, message: 'Display name is required' }]
          },
          {
            label: 'Auth Type Field',
            name: 'authTypeField',
            hidden: true,
            componentType: FormComponentType.INPUT_TEXT,
            startVersion: BigQueryPluginVersions.V9,
            initialValue: 'connectionType',
            rules: [{ required: false }]
          },
          {
            label: 'Authentication method',
            name: 'connectionType',
            startVersion: BigQueryPluginVersions.V9,
            componentType: FormComponentType.DROPDOWN,
            initialValue: ConnectionType.SERVICE_ACCOUNT_KEY,
            rules: [{ required: true }],
            options: Object.entries(CONNECTION_METHODS_AND_DISPLAY_NAMES).map(([value, displayName]) =>
              makeDropdownItem(value, displayName)
            )
          } as FormItem,
          {
            label: 'Service account key',
            name: 'authentication.custom.googleServiceAccount.value',
            startVersion: BigQueryPluginVersions.V1,
            endVersion: BigQueryPluginVersions.V8,
            // INPUT_AREA is broken (cannot be udpated after unfocus). Using
            // code editor for now.
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.JSON,
            placeholder: SERVICE_ACCOUNT_GHOST_TEXT,
            rules: [{ required: true, message: 'Service account key is required' }]
          } as FormItem,
          {
            label: 'Service account key',
            name: 'authentication.custom.googleServiceAccount.value',
            startVersion: BigQueryPluginVersions.V9,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.JSON,
            placeholder: SERVICE_ACCOUNT_GHOST_TEXT,
            rules: [{ required: true, message: 'Service account key is required' }],
            display: {
              show: {
                connectionType: [ConnectionType.SERVICE_ACCOUNT_KEY]
              }
            }
          } as FormItem,
          {
            ...BASE_SUBJECT_TOKEN_SOURCE,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...BASE_STATIC_TOKEN,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION],
                'authConfig.subjectTokenSource': ['SUBJECT_TOKEN_SOURCE_STATIC_TOKEN']
              }
            }
          } as FormItem,
          {
            ...BASE_WORKFORCE_POOL_ID,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...BASE_WORKFORCE_PROVIDER_ID,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...BASE_PROJECT_ID,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...BASE_BILLING_PROJECT_NUMBER,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...HIDDEN_TOKEN_URL,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...HIDDEN_SCOPE,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...HIDDEN_SUBJECT_TOKEN_TYPE,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem,
          {
            ...COMPUTED_AUDIENCE,
            startVersion: BigQueryPluginVersions.V9,
            display: {
              show: {
                connectionType: [ConnectionType.WORKFORCE_IDENTITY_FEDERATION]
              }
            }
          } as FormItem
        ]
      }
    ]
  },
  actionTemplate: {
    sections: [
      {
        name: 'main',
        items: [
          {
            label: 'Parameters (?, ?, ...)',
            name: 'parameters',
            startVersion: BigQueryPluginVersions.V8,
            ldFlag: 'clark.parameterized-apis.v2.enabled',
            componentType: FormComponentType.DYNAMIC_INPUT_TEXT,
            placeholder: '[param1, param2, ...]',
            tooltip: {
              markdownText:
                'JavaScript expression that evaluates to an array of parameter values. Use `?` placeholders in your SQL query to reference these parameters positionally.'
            }
          },
          {
            label: '', // Query
            name: 'body',
            startVersion: BigQueryPluginVersions.V1,
            componentType: FormComponentType.CODE_EDITOR,
            language: EditorLanguage.SQL,
            initialValue: SQL_INITIAL_TEXT
          }
        ]
      },
      {
        name: 'advanced:main',
        items: [
          {
            label: 'Use parameterized SQL',
            name: 'usePreparedSql',
            startVersion: BigQueryPluginVersions.V6,
            endVersion: BigQueryPluginVersions.V7,
            componentType: FormComponentType.SWITCH,
            initialValue: true,
            tooltip: {
              markdownText: PARAMETERIZED_SQL_DESCRIPTION
            }
          },
          {
            label: 'Use parameterized SQL',
            name: 'usePreparedSql',
            startVersion: BigQueryPluginVersions.V8,
            componentType: FormComponentType.SWITCH,
            initialValue: true,
            tooltip: {
              markdownText: PARAMETERIZED_SQL_DESCRIPTION
            },
            display: {
              show: {
                parameters: ['undefined']
              }
            }
          }
        ]
      }
    ]
  }
};
