import { html, TemplateResult, LitElement } from 'lit'
import type { IOrganization } from '@api-client/core/models/store/Organization.js'
import { property } from 'lit/decorators.js'
import { repeat } from 'lit/directives/repeat.js'
import { consume } from '@lit/context'
import { organizationsContext } from '../../../providers/organizations.js'

/**
 * An App screen (HTML Element) allowing the user to select an organization.
 * Primary use-case is during the initial setup when no organization is selected yet.
 *
 * Note, this element does not handle the actual API logic, it only provides the UI and dispatches events.
 */
export default class OrganizationSelectionScreen extends LitElement {
  /**
   * The list of organizations to select from.
   *
   * This property consumes the `organizationsContext`.
   */
  @property({ type: Array, attribute: false })
  @consume({ context: organizationsContext, subscribe: true })
  accessor organizations: IOrganization[] | undefined

  /**
   * Indicates whether the screen is in the loading state.
   * @attribute
   */
  @property({ type: Boolean }) accessor loading = false

  /**
   * The currently selected organization key, if any. Can be used to pre-select an organization in the list.
   * When the user makes a selection, an `organization-selected` event is dispatched and this property is updated.
   * @attribute
   */
  @property({ type: String }) accessor selected: string | undefined

  /**
   * Handles the organization selection form submission.
   * @param e The submit event
   */
  protected async handleOrgSelection(e: SubmitEvent): Promise<void> {
    e.preventDefault()
    const form = e.target as HTMLFormElement
    const organization = String(form.org.value).trim()
    if (!organization) {
      return
    }
    this.selectOrganization(organization)
  }

  /**
   * Selects the organization and persists the state.
   * @param organization The organization key to select
   */
  protected selectOrganization(organization: string): void {
    this.selected = organization
    this.dispatchEvent(
      new CustomEvent('organization-selected', {
        detail: { organization },
        bubbles: true,
        composed: true,
      })
    )
  }

  override render(): TemplateResult {
    return html`
      <div class="content">
        <div class="slide account-setup-slide">
          <h1 class="display-medium">Select your organization.</h1>
          ${this.loading ? this.renderLoader() : this.renderForm()}
        </div>
      </div>
    `
  }

  protected renderForm(): TemplateResult {
    const { organizations = [], selected } = this
    return html`
      <form class="org-name-form" @submit=${this.handleOrgSelection}>
        <ui-select name="org" class="org-input" required .value="${selected}">
          ${repeat(
            organizations,
            (i) => i.key,
            (i) =>
              html`<ui-option value="${i.key}"
                >${i.name}
                <div slot="supporting-text">${i.key}</div></ui-option
              >`
          )}
        </ui-select>
        <ui-button color="filled" type="submit">Continue</ui-button>
      </form>
    `
  }

  protected renderLoader(): TemplateResult {
    return html` <ui-progress indeterminate class="login-progress" aria-label="Setting up organization"></ui-progress> `
  }
}
