import { Component, computed, input, output } from '@angular/core';
import { HeadingComponent } from '@shared/ui/heading/heading.component';
import { StatusBadgeComponent } from '@shared/ui/status-badge/status-badge.component';
import { ButtonComponent } from '@shared/ui/button/button.component';
import { AlertComponent } from '@shared/ui/alert/alert.component';
import { PlaceholderOption } from '@shared/ui/rich-text-editor/rich-text-editor.component';
import { Brief, LibraryPassage } from '@brief/domain/brief';
import { Diagnostic } from '@brief/domain/placeholders';
import { BriefMsg } from '@brief/domain/brief.machine';
import { LetterSectionComponent } from '@brief/ui/letter-section/letter-section.component';
import { LetterPreviewComponent } from '@brief/ui/letter-preview/letter-preview.component';
import { DiagnosticsPanelComponent } from '@brief/ui/diagnostics-panel/diagnostics-panel.component';
import { RejectionCommentsComponent } from '@brief/ui/rejection-comments/rejection-comments.component';

/** Organism: the whole letter — status badge, the editable sections (drafter) or a
    read-only preview (approver / locked), the diagnostics panel, and the action bar
    appropriate to status × permission. Presentational: emits edit + transition
    intents; the canEdit/canApprove/canReject/canSend inputs are server-computed
    decision flags (PRD-0002 phase P1) — this component never derives them. */
@Component({
  selector: 'app-letter-composer',
  imports: [
    HeadingComponent,
    StatusBadgeComponent,
    ButtonComponent,
    AlertComponent,
    LetterSectionComponent,
    LetterPreviewComponent,
    DiagnosticsPanelComponent,
    RejectionCommentsComponent,
  ],
  styles: [
    `
      :host {
        display: block;
      }
      .head {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: var(--rhc-space-max-md);
        flex-wrap: wrap;
        margin-block-end: var(--rhc-space-max-lg);
      }
      .sections {
        display: grid;
        gap: var(--rhc-space-max-2xl);
      }
      .panel {
        margin-block: var(--rhc-space-max-xl);
      }
      .bar {
        display: flex;
        flex-wrap: wrap;
        gap: var(--rhc-space-max-md);
        align-items: center;
        margin-block-start: var(--rhc-space-max-xl);
      }
    `,
  ],
  template: `
    <div class="head">
      <app-heading [level]="2">{{ title() }}</app-heading>
      <app-status-badge [label]="statusLabel()" [color]="statusColor()" />
    </div>

    @if (status() === 'rejected') {
      <app-rejection-comments mode="show" [comments]="rejectComments()" />
    }

    @if (canEdit()) {
      <div class="sections">
        @for (section of brief().sections; track section.sectionKey) {
          <app-letter-section
            [section]="section"
            [availablePassages]="availablePassages()"
            [placeholders]="menu()"
            [editable]="!section.locked"
            (edit)="edit.emit($event)"
          />
        }
      </div>
    } @else {
      <app-letter-preview [brief]="brief()" [diagnostics]="diagnostics()" />
    }

    <div class="panel">
      <app-diagnostics-panel [diagnostics]="diagnostics()" (locate)="locate.emit($event)" />
    </div>

    <div class="bar">
      @switch (status()) {
        @case ('draft') {
          @if (canEdit()) {
            <app-button
              variant="primary"
              [disabled]="!canSubmit() || busy()"
              (click)="submit.emit()"
              >{{ submitLabel() }}</app-button
            >
            @if (!canSubmit()) {
              <span class="app-text-subtle">{{ submitHint() }}</span>
            }
          }
        }
        @case ('rejected') {
          @if (canEdit()) {
            <app-button
              variant="primary"
              [disabled]="!canSubmit() || busy()"
              (click)="submit.emit()"
              >{{ resubmitLabel() }}</app-button
            >
          }
        }
        @case ('submitted') {
          @if (canApprove() || canReject()) {
            <app-button variant="primary" [disabled]="busy()" (click)="approve.emit()">{{
              approveLabel()
            }}</app-button>
            <app-rejection-comments mode="entry" [busy]="busy()" (reject)="reject.emit($event)" />
          } @else {
            <app-alert type="info">{{ awaitingText() }}</app-alert>
          }
        }
        @case ('approved') {
          @if (canSend()) {
            <app-button variant="primary" [disabled]="busy()" (click)="send.emit()">{{
              sendLabel()
            }}</app-button>
          }
        }
        @case ('sent') {
          <app-alert type="ok">{{ sentText() }}</app-alert>
        }
      }
    </div>
  `,
})
export class LetterComposerComponent {
  brief = input.required<Brief>();
  availablePassages = input<readonly LibraryPassage[]>([]);
  diagnostics = input<readonly Diagnostic[]>([]);
  canEdit = input(false);
  canApprove = input(false);
  canReject = input(false);
  canSend = input(false);
  canSubmit = input(false);
  busy = input(false);

  edit = output<BriefMsg>();
  submit = output<void>();
  approve = output<void>();
  reject = output<string>();
  send = output<void>();
  locate = output<Diagnostic>();

  title = input($localize`:@@brief.title:Brief aan de zorgverlener`);
  submitLabel = input($localize`:@@brief.submit:Indienen ter beoordeling`);
  resubmitLabel = input($localize`:@@brief.resubmit:Opnieuw indienen`);
  submitHint = input(
    $localize`:@@brief.submitHint:Vul eerst alle verplichte secties en los fouten op.`,
  );
  approveLabel = input($localize`:@@brief.approve:Goedkeuren`);
  sendLabel = input($localize`:@@brief.send:Versturen`);
  awaitingText = input(
    $localize`:@@brief.awaiting:De brief wacht op beoordeling door een collega.`,
  );
  sentText = input($localize`:@@brief.sent:De brief is verzonden.`);

  protected status = computed(() => this.brief().status.tag);
  protected rejectComments = computed(() => {
    const s = this.brief().status;
    return s.tag === 'rejected' ? s.comments : '';
  });

  // The insert menu offers only valid, fillable, non-deprecated fields — inserting an
  // unknown/retired key is structurally impossible.
  protected menu = computed<PlaceholderOption[]>(() =>
    this.brief()
      .placeholders.filter((p) => p.fillable !== false && !p.deprecated)
      .map((p) => ({ key: p.key, label: p.label, autoResolvable: p.autoResolvable })),
  );

  protected statusLabel = computed(() => {
    switch (this.status()) {
      case 'draft':
        return $localize`:@@brief.status.draft:Concept`;
      case 'submitted':
        return $localize`:@@brief.status.submitted:Ter beoordeling`;
      case 'approved':
        return $localize`:@@brief.status.approved:Goedgekeurd`;
      case 'rejected':
        return $localize`:@@brief.status.rejected:Afgewezen`;
      case 'sent':
        return $localize`:@@brief.status.sent:Verzonden`;
    }
  });

  protected statusColor = computed(() => {
    switch (this.status()) {
      case 'draft':
        return 'var(--rhc-color-border-strong)';
      case 'submitted':
        return 'var(--rhc-color-oranje-500)';
      case 'approved':
      case 'sent':
        return 'var(--rhc-color-groen-500)';
      case 'rejected':
        return 'var(--rhc-color-rood-500)';
    }
  });
}
