import { Component, computed, input, output } from '@angular/core';
import { ButtonComponent } from '@shared/ui/button/button.component';
import { AlertComponent } from '@shared/ui/alert/alert.component';
import { ChoiceLinkComponent } from '@shared/ui/choice-link/choice-link.component';
import { Aanvraag, AanvraagType } from '@registratie/domain/aanvraag';
import { blockActions } from '@registratie/domain/block-actions';

const TYPE_LABELS: Record<AanvraagType, string> = {
  registratie: $localize`:@@aanvraagBlock.type.registratie:Inschrijving`,
  herregistratie: $localize`:@@aanvraagBlock.type.herregistratie:Herregistratie`,
  intake: $localize`:@@aanvraagBlock.type.intake:Herregistratie-intake`,
};

/** Organism: one application on the dashboard. A resumable Concept ("lopende
    aanvraag") renders as a CIBG "melding" (warning) with its actions — verwijderen
    as a link, aanvraag openen as a button; a submitted/resolved status renders as a
    plain keuzelijst card. Which actions show is driven by the pure
    `blockActions(status)`; the block only renders. NOTE: the caller places the two
    shapes differently — a Concept melding is a block element, the rest are `<li>`s
    that must sit inside a keuzelijst `<ul>` (see dashboard.page.ts). */
@Component({
  selector: 'app-aanvraag-block',
  imports: [ButtonComponent, AlertComponent, ChoiceLinkComponent],
  styles: [`
    :host{display:contents} /* see choice-link.component.ts (keeps <li> a direct <ul> child) */
    .actions{display:flex;align-items:center;gap:var(--rhc-space-max-md);margin-block-start:var(--rhc-space-max-sm)}
  `],
  template: `
    @if (aanvraag().status.tag === 'Concept') {
      <app-alert type="warning">
        <h3 class="h5">{{ typeLabel() }}</h3>
        <p>{{ conceptText() }}</p>
        <div class="actions">
          @if (actions().includes('cancel')) {
            <app-button variant="subtle" (click)="cancel.emit()" i18n="@@aanvraagBlock.verwijderen">Verwijderen</app-button>
          }
          @if (actions().includes('resume')) {
            <app-button (click)="resume.emit()" i18n="@@aanvraagBlock.openen">Aanvraag openen</app-button>
          }
        </div>
      </app-alert>
    } @else {
      <app-choice-link [heading]="typeLabel()" [instructions]="instructions()" />
    }
  `,
})
export class AanvraagBlockComponent {
  aanvraag = input.required<Aanvraag>();

  resume = output<void>();
  cancel = output<void>();

  protected typeLabel = computed(() => TYPE_LABELS[this.aanvraag().type]);
  protected actions = computed(() => blockActions(this.aanvraag().status));

  // ponytail: display-only deadline derived as createdAt + 30 dagen; move to a
  // server-sent `completeBefore` on the DTO when the expiry rule becomes real.
  private deadline = computed(() => {
    const d = new Date(this.aanvraag().createdAt);
    d.setDate(d.getDate() + 30);
    return d.toISOString();
  });

  /** The melding body for a Concept: wizard not finished + complete-before date. */
  protected conceptText = computed(() => {
    const s = this.aanvraag().status;
    if (s.tag !== 'Concept') return '';
    return $localize`:@@aanvraagBlock.conceptMelding:Deze aanvraag is nog niet volledig afgerond — u bent gebleven bij stap ${s.stepIndex + 1}:stap: van ${s.stepCount}:totaal:. Rond de aanvraag af vóór ${formatNL(this.deadline())}:datum:.`;
  });

  // Status-tag → the choice's description line (the UI's mapping, not a domain rule).
  private statusText = computed(() => {
    const s = this.aanvraag().status;
    switch (s.tag) {
      case 'Concept': return '';
      case 'InBehandeling': return $localize`:@@aanvraagBlock.inBehandeling:Referentie ${s.referentie}:ref: · ingediend op ${formatNL(this.aanvraag().submittedAt)}:datum:`;
      case 'Goedgekeurd': return $localize`:@@aanvraagBlock.goedgekeurd:Referentie ${s.referentie}:ref:`;
      case 'Afgewezen': return $localize`:@@aanvraagBlock.afgewezen:Referentie ${s.referentie}:ref:`;
    }
  });
  // Secondary note appended to the status line, when there's one to show.
  private subtitle = computed(() => {
    const s = this.aanvraag().status;
    if (s.tag === 'InBehandeling' && s.manual) return $localize`:@@aanvraagBlock.manual:Uw aanvraag wordt handmatig beoordeeld in de backoffice.`;
    if (s.tag === 'Afgewezen') return s.reden;
    return '';
  });
  // The keuzelijst has one description paragraph — combine status + secondary note.
  protected instructions = computed(() => {
    const status = this.statusText();
    const sub = this.subtitle();
    return sub ? `${status} ${sub}` : status;
  });
}

function formatNL(iso?: string): string {
  return iso ? new Date(iso).toLocaleDateString('nl-NL', { day: 'numeric', month: 'long', year: 'numeric' }) : '';
}
