import { Component, computed, inject } from '@angular/core';
import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';
import { AlertComponent } from '@shared/ui/alert/alert.component';
import { ButtonComponent } from '@shared/ui/button/button.component';
import { ASYNC } from '@shared/ui/async/async.component';
import { BriefStore } from '@brief/application/brief.store';
import { LetterComposerComponent } from '@brief/ui/letter-composer/letter-composer.component';

/** Page: thin container. Injects the root store, kicks off the load, and passes its
    derived read-model to the composer. Business/UI logic lives below in pure pieces;
    this just wires signals to the organism and events back to store commands. */
@Component({
  selector: 'app-brief-page',
  imports: [PageShellComponent, AlertComponent, ButtonComponent, ...ASYNC, LetterComposerComponent],
  styles: [
    `
      .brief-toolbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: var(--rhc-space-max-md);
        margin-block-end: var(--rhc-space-max-lg);
      }
      .save {
        color: var(--rhc-color-foreground-subtle);
        font-size: 0.9em;
      }
    `,
  ],
  template: `
    <app-page-shell [heading]="heading" [intro]="intro" backLink="/dashboard">
      @if (lastError(); as err) {
        <app-alert type="error">{{ err }}</app-alert>
      }

      <app-async [data]="store.remoteData()">
        <ng-template appAsyncError>
          <app-alert type="error">{{ failedText }}</app-alert>
          <app-button variant="secondary" (click)="reload()">{{ retryText }}</app-button>
        </ng-template>
        <ng-template appAsyncLoaded>
          @if (loaded(); as s) {
            <div class="brief-toolbar">
              <span class="save" role="status" aria-live="polite">{{ saveText() }}</span>
              <app-button variant="subtle" [disabled]="store.busy()" (click)="resetDemo()">{{
                resetLabel
              }}</app-button>
            </div>
            <app-letter-composer
              [brief]="s.brief"
              [availablePassages]="s.availablePassages"
              [diagnostics]="store.diagnostics()"
              [canEdit]="store.canEdit()"
              [canApprove]="store.canApprove()"
              [canReject]="store.canReject()"
              [canSend]="store.canSend()"
              [canSubmit]="store.canSubmit()"
              [busy]="store.busy()"
              (edit)="store.edit($event)"
              (submit)="store.submit()"
              (approve)="store.approve()"
              (reject)="store.reject($event)"
              (send)="store.send()"
            />
          }
        </ng-template>
      </app-async>
    </app-page-shell>
  `,
})
export class BriefPage {
  protected store = inject(BriefStore);
  protected model = this.store.model;
  protected lastError = this.store.lastError;

  protected heading = $localize`:@@brief.page.heading:Brief opstellen`;
  protected intro = $localize`:@@brief.page.intro:Stel de brief aan de zorgverlener samen uit standaardteksten en vrije tekst.`;
  protected failedText = $localize`:@@brief.page.failed:De brief kon niet worden geladen.`;
  protected retryText = $localize`:@@brief.page.retry:Opnieuw proberen`;
  protected resetLabel = $localize`:@@brief.page.reset:Opnieuw beginnen (demo)`;

  private savingText = $localize`:@@brief.page.saving:Concept opslaan…`;
  private savedText = $localize`:@@brief.page.saved:Concept opgeslagen`;
  private saveErrorText = $localize`:@@brief.page.saveError:Opslaan mislukt`;

  /** Debounced-save state, surfaced in a polite live region. */
  protected saveText = computed(() => {
    switch (this.store.saveState().tag) {
      case 'Saving':
        return this.savingText;
      case 'Saved':
        return this.savedText;
      case 'Error':
        return this.saveErrorText;
      default:
        return '';
    }
  });

  constructor() {
    void this.store.load();
  }

  protected resetDemo() {
    void this.store.resetDemo();
  }

  /** Typed narrowing for the `<app-async>` loaded slot — see WP-06: a structural
      directive's context can't inherit a generic from a sibling host input, so the
      Success value is unwrapped here instead of through `let-`. */
  protected readonly loaded = computed(() => {
    const s = this.model();
    return s.tag === 'loaded' ? s : undefined;
  });

  protected reload() {
    void this.store.load();
  }
}
