<script>
import Loading from '@shell/components/Loading';
import CreateEditView from '@shell/mixins/create-edit-view';
import AuthConfig from '@shell/mixins/auth-config';
import CruResource from '@shell/components/CruResource';
import { LabeledInput } from '@components/Form/LabeledInput';
import { Banner } from '@components/Banner';
import AllowedPrincipals from '@shell/components/auth/AllowedPrincipals';
import FileSelector from '@shell/components/form/FileSelector';
import AuthBanner from '@shell/components/auth/AuthBanner';
import { RadioGroup } from '@components/Form/Radio';

export default {
  components: {
    Loading,
    CruResource,
    LabeledInput,
    Banner,
    AllowedPrincipals,
    FileSelector,
    AuthBanner,
    RadioGroup
  },

  mixins: [CreateEditView, AuthConfig],
  data() {
    return {
      customEndpoint: {
        value:  false,
        labels: [
          this.t('authConfig.oidc.customEndpoint.standard'),
          this.t('authConfig.oidc.customEndpoint.custom'),
        ],
        options: [
          false,
          true
        ]
      },
      keycloakUrls: {
        url:   null,
        realm: null
      }
    };
  },

  computed: {
    tArgs() {
      return {
        baseUrl:  this.serverSetting,
        provider: this.displayName,
        username: this.principal.loginName || this.principal.name,
      };
    },

    toSave() {
      return {
        enabled:    true,
        oidcConfig: this.model
      };
    },

  },
  watch: {
    'keycloakUrls.url'() {
      this.updateIssuerEndpoint();
    },
    'keycloakUrls.realm'() {
      this.updateIssuerEndpoint();
    },
    'model.enabled'(neu) {
      // Cover case where oidc gets disabled and we return to the edit screen with a reset model
      if (!neu) {
        this.keycloakUrls = {
          url:   null,
          realm: null
        };
        this.customEndpoint.value = false;
      }
    },
    editConfig(neu, old) {
      // Cover use case where user edits existing oidc (keycloakUrls aren't persisted, so if we have issuer & authEndpoint set custom endpoints to true)
      if (!old && neu) {
        this.customEndpoint.value = (!this.keycloakUrls.url && !this.keycloakUrls.authEndpoint) && (!!this.model.issuer && !!this.model.authEndpoint);
      }
    }
  },

  methods: {
    updateIssuerEndpoint() {
      if (!this.keycloakUrls.url) {
        return;
      }
      const url = this.keycloakUrls.url.replaceAll(' ', '');

      this.model.issuer = `${ url }/auth/realms/${ this.keycloakUrls.realm || '' }`;
      this.model.authEndpoint = `${ this.model.issuer || '' }/protocol/openid-connect/auth`;
    },
  }
};
</script>

<template>
  <Loading v-if="$fetchState.pending" />
  <div v-else>
    <CruResource
      :cancel-event="true"
      :done-route="doneRoute"
      :mode="mode"
      :resource="model"
      :subtypes="[]"
      :validation-passed="true"
      :finish-button-mode="model.enabled ? 'edit' : 'enable'"
      :can-yaml="false"
      :errors="errors"
      :show-cancel="showCancel"
      @error="e=>errors = e"
      @finish="save"
      @cancel="cancel"
    >
      <template v-if="model.enabled && !isEnabling && !editConfig">
        <AuthBanner
          :t-args="tArgs"
          :disable="disable"
          :edit="goToEdit"
        >
          <template slot="rows">
            <tr><td>{{ t(`authConfig.oidc.rancherUrl`) }}: </td><td>{{ model.rancherUrl }}</td></tr>
            <tr><td>{{ t(`authConfig.oidc.clientId`) }}: </td><td>{{ model.clientId }}</td></tr>
            <tr><td>{{ t(`authConfig.oidc.issuer`) }}: </td><td>{{ model.issuer }}</td></tr>
            <tr><td>{{ t(`authConfig.oidc.authEndpoint`) }}: </td><td>{{ model.authEndpoint }}</td></tr>
          </template>
        </AuthBanner>

        <hr>

        <AllowedPrincipals
          :provider="NAME"
          :auth-config="model"
          :mode="mode"
        />
      </template>

      <template v-else>
        <Banner
          v-if="!model.enabled"
          :label="t('authConfig.stateBanner.disabled', tArgs)"
          color="warning"
        />

        <h3>{{ t(`authConfig.oidc.${NAME}`) }}</h3>

        <div class="row mb-20">
          <div class="col span-6">
            <LabeledInput
              v-model="model.clientId"
              :label="t(`authConfig.oidc.clientId`)"
              :mode="mode"
              required
            />
          </div>
          <div class="col span-6">
            <LabeledInput
              v-model="model.clientSecret"
              :label="t(`authConfig.oidc.clientSecret`)"
              :mode="mode"
              required
            />
          </div>
        </div>

        <div class="row mb-20">
          <div class="col span-6">
            <LabeledInput
              v-model="model.privateKey"
              :label="t(`authConfig.oidc.key.label`)"
              :placeholder="t(`authConfig.oidc.key.placeholder`)"
              :mode="mode"
              type="multiline"
            />
            <FileSelector
              class="role-tertiary add mt-5"
              :label="t('generic.readFromFile')"
              :mode="mode"
              @selected="$set(model, 'privateKey', $event)"
            />
          </div>
          <div class="col span-6">
            <LabeledInput
              v-model="model.certificate"
              :label="t(`authConfig.oidc.cert.label`)"
              :placeholder="t(`authConfig.oidc.cert.placeholder`)"
              :mode="mode"
              type="multiline"
            />
            <FileSelector
              class="role-tertiary add mt-5"
              :label="t('generic.readFromFile')"
              :mode="mode"
              @selected="$set(model, 'certificate', $event)"
            />
          </div>
        </div>

        <div class="row mb-20">
          <div class="col span-6">
            <RadioGroup
              v-model="customEndpoint.value"
              name="customEndpoint"
              label-key="authConfig.oidc.customEndpoint.label"
              :labels="customEndpoint.labels"
              :options="customEndpoint.options"
            >
              <template #label>
                <h4>{{ t('authConfig.oidc.customEndpoint.label') }}</h4>
              </template>
            </RadioGroup>
          </div>
        </div>

        <div class="row mb-20">
          <div class="col span-6">
            <LabeledInput
              v-model="keycloakUrls.url"
              :label="t(`authConfig.oidc.keycloak.url`)"
              :mode="mode"
              :required="!customEndpoint.value"
              :disabled="customEndpoint.value"
            />
          </div>
          <div class="col span-6">
            <LabeledInput
              v-model="keycloakUrls.realm"
              :label="t(`authConfig.oidc.keycloak.realm`)"
              :mode="mode"
              :required="!customEndpoint.value"
              :disabled="customEndpoint.value"
            />
          </div>
        </div>

        <div class="row mb-20">
          <div class="col span-6">
            <LabeledInput
              v-model="model.rancherUrl"
              :label="t(`authConfig.oidc.rancherUrl`)"
              :mode="mode"
              required
              :disabled="!customEndpoint.value"
            />
          </div>
        </div>

        <div class="row mb-20">
          <div class="col span-6">
            <LabeledInput
              v-model="model.issuer"
              :label="t(`authConfig.oidc.issuer`)"
              :mode="mode"
              required
              :disabled="!customEndpoint.value"
            />
          </div>
          <div class="col span-6">
            <LabeledInput
              v-model="model.authEndpoint"
              :label="t(`authConfig.oidc.authEndpoint`)"
              :mode="mode"
              required
              :disabled="!customEndpoint.value"
            />
          </div>
        </div>
      </template>
      <div
        v-if="!model.enabled"
        class="row"
      >
        <div class="col span-12">
          <Banner
            v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
            color="info"
          />
        </div>
      </div>
    </CruResource>
  </div>
</template>
<style lang="scss" scoped>
  .banner {
    display: block;

    &::v-deep code {
      padding: 0 3px;
      margin: 0 3px;
    }
  }
</style>
