import React, { useState, useMemo, useEffect } from 'react';
import { Field, Select, Input, ButtonGroup, ToolbarButton, Text, TextLink, Collapse } from '@grafana/ui';
import { onUpdateDatasourceJsonDataOptionSelect, onUpdateDatasourceJsonDataOption, onUpdateDatasourceResetOption, onUpdateDatasourceSecureJsonDataOption } from '@grafana/data';
import { config } from '@grafana/runtime';
import { standardRegions } from '../regions.js';
import { AwsAuthType } from '../types.js';
import { awsAuthProviderOptions } from '../providers.js';
import { assumeRoleInstructionsStyle } from './ConnectionConfig.styles.js';
import { ConfigSection, ConfigSubSection } from '@grafana/plugin-ui';

const DEFAULT_LABEL_WIDTH = 28;
const DS_TYPES_THAT_SUPPORT_TEMP_CREDS = [
  "cloudwatch",
  "grafana-athena-datasource",
  "grafana-amazonprometheus-datasource"
];
const toOption = (value) => ({ value, label: value });
const isAwsAuthType = (value) => {
  return typeof value === "string" && awsAuthProviderOptions.some((opt) => opt.value === value);
};
const ConnectionConfig = (props) => {
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
  const [isARNInstructionsOpen, setIsARNInstructionsOpen] = useState(false);
  const [regions, setRegions] = useState((props.standardRegions || standardRegions).map(toOption));
  const {
    loadRegions,
    onOptionsChange,
    skipHeader = false,
    skipEndpoint = false,
    options,
    hideAssumeRoleArn = false
  } = props;
  let profile = options.jsonData.profile;
  if (profile === void 0) {
    profile = options.database;
  }
  const tempCredsFeatureEnabled = config.featureToggles.awsDatasourcesTempCredentials && DS_TYPES_THAT_SUPPORT_TEMP_CREDS.includes(options.type);
  const awsAssumeRoleEnabled = (_a = config.awsAssumeRoleEnabled) != null ? _a : true;
  const awsAllowedAuthProviders = useMemo(
    () => config.awsAllowedAuthProviders.filter((provider) => provider === AwsAuthType.GrafanaAssumeRole ? tempCredsFeatureEnabled : true).filter(isAwsAuthType),
    [tempCredsFeatureEnabled]
  );
  if (tempCredsFeatureEnabled && options.jsonData.authType === AwsAuthType.GrafanaAssumeRole) {
    if (config.namespace.startsWith("stacks-")) {
      props.externalId = config.namespace.substring(config.namespace.indexOf("-") + 1);
    }
  }
  const currentProvider = awsAuthProviderOptions.find((p) => p.value === options.jsonData.authType);
  useEffect(() => {
    if (!currentProvider && awsAllowedAuthProviders.length) {
      onOptionsChange({
        ...options,
        jsonData: {
          ...options.jsonData,
          authType: awsAllowedAuthProviders[0]
        }
      });
    }
  }, [currentProvider, options, onOptionsChange, awsAllowedAuthProviders]);
  useEffect(() => {
    if (!loadRegions) {
      return;
    }
    loadRegions().then((regions2) => setRegions(regions2.map(toOption)));
  }, [loadRegions]);
  return /* @__PURE__ */ React.createElement("div", { "data-testid": "connection-config" }, /* @__PURE__ */ React.createElement(ConfigSection, { title: skipHeader ? "" : "Connection Details", "data-testid": "connection-config" }, /* @__PURE__ */ React.createElement(ConfigSubSection, { title: "Authentication" }, /* @__PURE__ */ React.createElement(
    Field,
    {
      label: "Authentication Provider",
      description: "Specify which AWS credentials chain to use.",
      htmlFor: "authProvider"
    },
    /* @__PURE__ */ React.createElement(
      Select,
      {
        "aria-label": "Authentication Provider",
        inputId: "authProvider",
        value: currentProvider,
        options: awsAuthProviderOptions.filter((opt) => awsAllowedAuthProviders.includes(opt.value)),
        defaultValue: options.jsonData.authType,
        onChange: (option) => {
          onUpdateDatasourceJsonDataOptionSelect(props, "authType")(option);
        },
        menuShouldPortal: true
      }
    )
  ), options.jsonData.authType === "credentials" && /* @__PURE__ */ React.createElement(
    Field,
    {
      label: "Credentials Profile Name",
      description: "Credentials profile name, as specified in ~/.aws/credentials, leave blank for default.",
      htmlFor: "credentialsProfileName"
    },
    /* @__PURE__ */ React.createElement(
      Input,
      {
        id: "credentialsProfileName",
        placeholder: "default",
        value: options.jsonData.profile,
        onChange: onUpdateDatasourceJsonDataOption(props, "profile")
      }
    )
  ), options.jsonData.authType === "keys" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Field, { label: "Access Key ID", htmlFor: "accessKeyId" }, ((_b = props.options.secureJsonFields) == null ? void 0 : _b.accessKey) ? /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Input, { disabled: true, placeholder: "Configured", id: "accessKeyId" }), /* @__PURE__ */ React.createElement(
    ToolbarButton,
    {
      icon: "edit",
      tooltip: "Edit Access Key ID",
      type: "button",
      onClick: onUpdateDatasourceResetOption(props, "accessKey")
    }
  )) : /* @__PURE__ */ React.createElement(
    Input,
    {
      id: "accessKeyId",
      value: (_d = (_c = options.secureJsonData) == null ? void 0 : _c.accessKey) != null ? _d : "",
      onChange: onUpdateDatasourceSecureJsonDataOption(props, "accessKey")
    }
  )), /* @__PURE__ */ React.createElement(Field, { label: "Secret Access Key", htmlFor: "secretKey" }, ((_e = props.options.secureJsonFields) == null ? void 0 : _e.secretKey) ? /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Input, { disabled: true, placeholder: "Configured" }), /* @__PURE__ */ React.createElement(
    ToolbarButton,
    {
      id: "secretKey",
      icon: "edit",
      type: "button",
      tooltip: "Edit Secret Access Key",
      onClick: onUpdateDatasourceResetOption(props, "secretKey")
    }
  )) : /* @__PURE__ */ React.createElement(
    Input,
    {
      id: "secretKey",
      value: (_g = (_f = options.secureJsonData) == null ? void 0 : _f.secretKey) != null ? _g : "",
      onChange: onUpdateDatasourceSecureJsonDataOption(props, "secretKey")
    }
  )))), !hideAssumeRoleArn && /* @__PURE__ */ React.createElement(
    ConfigSubSection,
    {
      title: "Assume Role",
      description: options.jsonData.authType === AwsAuthType.GrafanaAssumeRole ? /* @__PURE__ */ React.createElement(Text, null, "Learn more about", " ", /* @__PURE__ */ React.createElement(
        TextLink,
        {
          inline: true,
          external: true,
          variant: "bodySmall",
          href: "https://grafana.com/docs/plugins/cloudwatch/latest/aws-authentication/#use-grafana-assume-role"
        },
        "Grafana Assume Role"
      ), ".") : null
    },
    options.jsonData.authType === AwsAuthType.GrafanaAssumeRole && /* @__PURE__ */ React.createElement("div", { className: assumeRoleInstructionsStyle }, /* @__PURE__ */ React.createElement(
      Collapse,
      {
        label: "How to create an IAM role for grafana to assume:",
        collapsible: true,
        isOpen: isARNInstructionsOpen,
        onToggle: () => setIsARNInstructionsOpen(!isARNInstructionsOpen)
      },
      /* @__PURE__ */ React.createElement("ol", null, /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "1. Create a new IAM role in the AWS console, and select ", /* @__PURE__ */ React.createElement("code", null, "Another AWS account"), " as the", " ", /* @__PURE__ */ React.createElement("code", null, "Trusted entity"), ".")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "2. Enter the account ID of the Grafana account that has permission to assume this role:", /* @__PURE__ */ React.createElement("code", null, " 008923505280 "), " and check the ", /* @__PURE__ */ React.createElement("code", null, "Require external ID"), " box.")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "3. Enter the following external ID:", " ", /* @__PURE__ */ React.createElement("code", null, props.externalId || "External Id is currently unavailable"), " and click", " ", /* @__PURE__ */ React.createElement("code", null, "Next"), ".")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "4. Add any required permissions you would like Grafana to be able to access on your behalf. For more details on our permissions please", " ", /* @__PURE__ */ React.createElement(
        "a",
        {
          href: "https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/",
          target: "_blank",
          rel: "noreferrer"
        },
        "read through our documentation"
      ), ".")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "5. Give the role a name and description, and click ", /* @__PURE__ */ React.createElement("code", null, "Create role"), ".")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("p", null, "6. Copy the ARN of the role you just created and paste it into the ", /* @__PURE__ */ React.createElement("code", null, "Assume Role ARN"), " ", "field below.")))
    )),
    awsAssumeRoleEnabled && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
      Field,
      {
        htmlFor: "assumeRoleArn",
        label: "Assume Role ARN",
        description: "Optional. Specifying the ARN of a role will ensure that the\n                     selected authentication provider is used to assume the role rather than the\n                     credentials directly."
      },
      /* @__PURE__ */ React.createElement(
        Input,
        {
          id: "assumeRoleArn",
          placeholder: "arn:aws:iam:*",
          value: options.jsonData.assumeRoleArn || "",
          onChange: onUpdateDatasourceJsonDataOption(props, "assumeRoleArn")
        }
      )
    ), options.jsonData.authType !== AwsAuthType.GrafanaAssumeRole && /* @__PURE__ */ React.createElement(
      Field,
      {
        htmlFor: "externalId",
        label: "External ID",
        description: "If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
      },
      /* @__PURE__ */ React.createElement(
        Input,
        {
          id: "externalId",
          placeholder: "External ID",
          value: options.jsonData.externalId || "",
          onChange: onUpdateDatasourceJsonDataOption(props, "externalId")
        }
      )
    ))
  ), /* @__PURE__ */ React.createElement(ConfigSubSection, { title: "Additional Settings" }, !skipEndpoint && options.jsonData.authType !== AwsAuthType.GrafanaAssumeRole && /* @__PURE__ */ React.createElement(
    Field,
    {
      label: "Endpoint",
      description: "Optionally, specify a custom endpoint for the service",
      htmlFor: "endpoint"
    },
    /* @__PURE__ */ React.createElement(
      Input,
      {
        id: "endpoint",
        placeholder: (_h = props.defaultEndpoint) != null ? _h : "https://{service}.{region}.amazonaws.com",
        value: options.jsonData.endpoint || "",
        onChange: onUpdateDatasourceJsonDataOption(props, "endpoint")
      }
    )
  ), /* @__PURE__ */ React.createElement(
    Field,
    {
      label: "Default Region",
      description: "Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.",
      htmlFor: "defaultRegion"
    },
    /* @__PURE__ */ React.createElement(
      Select,
      {
        inputId: "defaultRegion",
        value: (_i = regions.find((region) => region.value === options.jsonData.defaultRegion)) != null ? _i : options.jsonData.defaultRegion ? {
          label: options.jsonData.defaultRegion,
          value: options.jsonData.defaultRegion
        } : void 0,
        options: regions,
        defaultValue: options.jsonData.defaultRegion,
        allowCustomValue: true,
        onChange: onUpdateDatasourceJsonDataOptionSelect(props, "defaultRegion"),
        formatCreateLabel: (r) => `Use region: ${r}`,
        menuShouldPortal: true
      }
    )
  )), props.children));
};

export { ConnectionConfig, DEFAULT_LABEL_WIDTH };
//# sourceMappingURL=ConnectionConfig.js.map
