import { html, TemplateResult, LitElement, nothing } from 'lit'
import { property } from 'lit/decorators.js'
import { consume } from '@lit/context'
import { userContext, type IUser } from '../../../providers/user.js'

export type OrgCreateReason = 'setup' | 'add'

/**
 * An App screen (HTML Element) allowing the user to create a new organization during the setup process.
 *
 * Note, this element does not handle the actual API logic, it only provides the UI and dispatches events.
 *
 * @fires create - Dispatched when the user submits the form with a valid organization name.
 *                 The event detail contains `{ organization: string }`.
 * @fires cancel - Dispatched when the user cancels the operation (only available when `reason` is 'add').
 *
 * @example
 * ```html
 * <organization-create-screen
 *   reason="setup"
 *   @create="${this.handleCreate}"
 * ></organization-create-screen>
 * ```
 */
export default class OrganizationCreateScreen extends LitElement {
  /**
   * The current user information.
   *
   * This property consumes the `userContext`.
   */
  @property({ type: Object, attribute: false })
  @consume({ context: userContext, subscribe: true })
  accessor user: IUser | undefined

  /**
   * Computed user name for welcome message.
   */
  get userName(): string {
    return this.user?.name || ''
  }

  /**
   * Computed intro message based on the reason for creating the organization.
   */
  get introMessage(): string {
    if (this.reason === 'setup') {
      // eslint-disable-next-line max-len
      return 'Start with adding an organization to your account. Each organization you create has separate billing, teams, and APIs.'
    }
    return 'Each organization you create has separate billing, teams, and APIs.'
  }

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

  /**
   * The user-entered organization name. Can be set to pre-fill the input field.
   * @attribute
   */
  @property({ type: String }) accessor organization: string | undefined
  /**
   * The reason for creating the organization, affecting the welcome message.
   *
   * Possible values are:
   * - 'setup': for initial setup
   * - 'add': for adding an additional organization
   *
   * @attribute
   */
  @property({ type: String }) accessor reason: OrgCreateReason = 'setup'

  protected handleFormSubmit(e: SubmitEvent): void {
    e.preventDefault()
    const form = e.target as HTMLFormElement
    const organization = String(form.organization.value).trim()
    if (!organization) {
      return
    }
    this.setupOrganization(organization)
  }

  setupOrganization(organization: string): void {
    this.organization = organization
    this.dispatchEvent(
      new CustomEvent('create', {
        detail: { organization },
        bubbles: false,
        composed: false,
      })
    )
  }

  protected handleCancel(): void {
    if (this.reason !== 'add') {
      return
    }
    this.dispatchEvent(
      new CustomEvent('cancel', {
        bubbles: false,
        composed: false,
      })
    )
  }

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

  private renderWelcomeMessage(): TemplateResult {
    const tagline = this.reason === 'setup' ? 'Setup your first organization' : 'Add another organization'
    return html`
      <h1 class="display-medium">Welcome ${this.userName}.</h1>
      <p class="title-large">${tagline}.</p>
    `
  }

  protected renderForm(): TemplateResult {
    return html`
      <p class="body-medium">${this.introMessage}</p>
      ${this.renderOrganizationInput()} ${this.renderInvitationInfo()}
    `
  }

  protected renderInvitationInfo(): TemplateResult | typeof nothing {
    if (this.reason !== 'setup') {
      return nothing
    }
    return html`<p class="body-small">
      Expected to join an organization? Click on the registration link in the invitation email to get started.
    </p>`
  }

  protected renderOrganizationInput(): TemplateResult {
    const { organization = '' } = this
    return html`
      <form class="org-name-form" @submit=${this.handleFormSubmit}>
        <ui-outlined-text-field
          label="Organization name"
          name="organization"
          autocomplete="organization"
          required
          class="org-input"
          .value="${organization}"
        ></ui-outlined-text-field>
        <ui-button class="next" color="filled" type="submit">Next</ui-button>
        ${this.renderCancelButton()}
      </form>
    `
  }

  protected renderCancelButton(): TemplateResult | typeof nothing {
    if (this.reason !== 'add') {
      return nothing
    }
    return html`<ui-button class="cancel" color="text" type="button" @click="${this.handleCancel}">Cancel</ui-button>`
  }

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