import { Component, computed, inject } from '@angular/core';
import { Router } from '@angular/router';
import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';
import { HeadingComponent } from '@shared/ui/heading/heading.component';
import { AlertComponent } from '@shared/ui/alert/alert.component';
import { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';
import { DataRowComponent } from '@shared/ui/data-row/data-row.component';
import { DataBlockComponent } from '@shared/ui/data-block/data-block.component';
import { TaskListComponent } from '@shared/ui/task-list/task-list.component';
import { ApplicationListComponent } from '@shared/ui/application-list/application-list.component';
import { ApplicationLinkComponent } from '@shared/ui/application-link/application-link.component';
import { ASYNC } from '@shared/ui/async/async.component';
import { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';
import { RegistrationTableComponent } from '@registratie/ui/registration-table/registration-table.component';
import { AanvraagBlockComponent } from '@registratie/ui/aanvraag-block/aanvraag-block.component';
import { BigProfileStore } from '@registratie/application/big-profile.store';
import { ApplicationsStore } from '@registratie/application/applications.store';
import { Registration } from '@registratie/domain/registration';
import { Aanvraag, AanvraagType } from '@registratie/domain/aanvraag';
import { submittedRow } from '@registratie/domain/aanvraag-view';
import { tasksFromProfile } from '@registratie/domain/tasks';

/** Page:"Mijn overzicht" — the portal home, following the NL Design System
"Mijn omgeving" pattern (side nav +"Wat moet ik regelen" +"Mijn zaken"). */
@Component({
  selector: 'app-dashboard-page',
  imports: [
    PageShellComponent,
    HeadingComponent,
    AlertComponent,
    SkeletonComponent,
    DataRowComponent,
    DataBlockComponent,
    TaskListComponent,
    ApplicationListComponent,
    ApplicationLinkComponent,
    ...ASYNC,
    RegistrationSummaryComponent,
    RegistrationTableComponent,
    AanvraagBlockComponent,
  ],
  template: `
    <app-page-shell
      i18n-heading="@@dashboard.heading"
      heading="Mijn overzicht"
      i18n-intro="@@dashboard.intro"
      intro="Welkom in uw persoonlijke omgeving van het BIG-register. Hier ziet u uw registratie en regelt u uw zaken."
    >
      <div class="app-stack">
        @if (aanvragen().length) {
          <section>
            @for (a of concepten(); track a.id) {
              <app-aanvraag-block
                animate.enter="app-item-enter"
                animate.leave="app-item-leave"
                [aanvraag]="a"
                (resume)="resume(a)"
                (cancel)="cancelAanvraag(a)"
              />
            }
            @if (ingediend().length) {
              <app-heading [level]="2" class="app-section" i18n="@@dashboard.mijnAanvragen"
                >Mijn aanvragen</app-heading
              >
              <app-application-list>
                @for (a of ingediend(); track a.id) {
                  @let row = submittedRow(a);
                  <li
                    app-application-link
                    animate.enter="app-item-enter"
                    animate.leave="app-item-leave"
                    [heading]="row.heading"
                    [subtitle]="row.subtitle"
                    [status]="row.status"
                    [to]="'/aanvraag/' + a.id"
                  ></li>
                }
              </app-application-list>
            }
          </section>
        }

        @if (store.pendingHerregistratie()) {
          <app-alert type="info" i18n="@@dashboard.pendingHerregistratie"
            >Uw herregistratie-aanvraag is in behandeling.</app-alert
          >
        }

        <app-async [data]="store.profile()" (retryClicked)="store.reloadProfile()">
          <ng-template appAsyncLoaded>
            @if (profile(); as p) {
              @let tasks = tasksFor(p.registration);

              <section>
                @if (tasks.length) {
                  <app-task-list
                    class="app-section"
                    i18n-listHeading="@@dashboard.watMoetIkRegelen"
                    listHeading="Wat moet ik regelen"
                    [tasks]="tasks"
                  />
                } @else {
                  <app-heading [level]="2" i18n="@@dashboard.watMoetIkRegelen"
                    >Wat moet ik regelen</app-heading
                  >
                  <p class="app-text-subtle" i18n="@@dashboard.nietsOpenstaan">
                    U heeft op dit moment niets openstaan.
                  </p>
                }
              </section>

              <section>
                <app-heading [level]="2" i18n="@@dashboard.mijnRegistratie"
                  >Mijn registratie</app-heading
                >
                <div class="app-section">
                  <app-registration-summary [reg]="p.registration" />
                </div>
                <app-data-block
                  class="app-section"
                  i18n-heading="@@dashboard.persoonsgegevens"
                  heading="Persoonsgegevens (BRP)"
                >
                  <div
                    app-data-row
                    i18n-key="@@dashboard.straat"
                    key="Straat"
                    [value]="p.person.adres.straat"
                  ></div>
                  <div
                    app-data-row
                    i18n-key="@@dashboard.postcode"
                    key="Postcode"
                    [value]="p.person.adres.postcode"
                  ></div>
                  <div
                    app-data-row
                    i18n-key="@@dashboard.woonplaats"
                    key="Woonplaats"
                    [value]="p.person.adres.woonplaats"
                  ></div>
                </app-data-block>
              </section>
            }
          </ng-template>
          <ng-template appAsyncLoading>
            <app-skeleton height="2.5rem" [count]="6" />
          </ng-template>
        </app-async>

        <section>
          <app-heading [level]="2" i18n="@@dashboard.specialismen"
            >Specialismen en aantekeningen</app-heading
          >
          <div class="app-section">
            <app-async [data]="store.aantekeningen()" (retryClicked)="store.reloadAantekeningen()">
              <ng-template appAsyncLoaded>
                @if (aantekeningen(); as r) {
                  <app-registration-table [rows]="r" />
                }
              </ng-template>
              <ng-template appAsyncLoading>
                <app-skeleton height="2.5rem" [count]="3" />
              </ng-template>
              <ng-template appAsyncEmpty>
                <p class="app-text-subtle" i18n="@@dashboard.geenSpecialismen">
                  U heeft nog geen specialismen of aantekeningen.
                </p>
              </ng-template>
            </app-async>
          </div>
        </section>

        <section>
          <app-heading [level]="2" i18n="@@dashboard.watWiltUDoen">Wat wilt u doen?</app-heading>
          <app-application-list class="app-section">
            @for (a of acties; track a.to) {
              <li
                app-application-link
                [heading]="a.titel"
                [subtitle]="a.tekst"
                [cta]="a.actie"
                [to]="a.to"
              ></li>
            }
          </app-application-list>
        </section>
      </div>
    </app-page-shell>
  `,
})
export class DashboardPage {
  protected store = inject(BigProfileStore);
  private apps = inject(ApplicationsStore);
  private router = inject(Router);

  /** Pure view mapping for a submitted aanvraag → CIBG aanvragen-row fields. */
  protected submittedRow = submittedRow;

  constructor() {
    // Re-fetch on each visit so server-computed auto-approval transitions show up
    // (Concept → In behandeling → Goedgekeurd after the processing window).
    this.apps.reload();
  }

  /** The user's applications, sorted Concept → In behandeling → resolved. Empty →
      the"Mijn aanvragen" section is hidden (see template). */
  protected aanvragen = computed<Aanvraag[]>(() => {
    const rd = this.apps.applications();
    if (rd.tag !== 'Success') return [];
    const order: Record<Aanvraag['status']['tag'], number> = {
      Concept: 0,
      InBehandeling: 1,
      Goedgekeurd: 2,
      Afgewezen: 2,
    };
    return rd.value.slice().sort((a, b) => order[a.status.tag] - order[b.status.tag]);
  });
  /** A Concept ("lopende aanvraag") renders as a melding above the list; the rest
      as keuzelijst items — the two shapes need different HTML contexts. */
  protected concepten = computed(() => this.aanvragen().filter((a) => a.status.tag === 'Concept'));
  protected ingediend = computed(() => this.aanvragen().filter((a) => a.status.tag !== 'Concept'));

  private readonly resumeRoutes: Record<AanvraagType, string> = {
    registratie: '/registreren',
    herregistratie: '/herregistratie',
    intake: '/intake',
  };
  protected resume(a: Aanvraag) {
    void this.router.navigate([this.resumeRoutes[a.type]], { queryParams: { aanvraag: a.id } });
  }
  protected cancelAanvraag(a: Aanvraag) {
    void this.apps.cancel(a.id);
  }

  /** Server-computed eligibility (rendered, not recomputed). */
  private readonly eligible = computed(() => {
    const d = this.store.decisions();
    return d.tag === 'Success' && d.value.eligibleForHerregistratie;
  });

  protected tasksFor(reg: Registration) {
    return tasksFromProfile(reg, this.eligible());
  }

  /** Typed narrowing for the `<app-async>` loaded slot — `<ng-template>`'s own
      context can't inherit a generic from a sibling host input (Angular only infers
      a structural directive's type parameter from an input on that same node), so
      the Success value is unwrapped here instead of through `let-`. */
  protected readonly profile = computed(() => {
    const rd = this.store.profile();
    return rd.tag === 'Success' ? rd.value : undefined;
  });
  protected readonly aantekeningen = computed(() => {
    const rd = this.store.aantekeningen();
    return rd.tag === 'Success' ? rd.value : undefined;
  });

  /** Primary transactional actions, as an "aanvragen" list (see CIBG's
      componenten/aanvragen). The core portal sections live in the header nav now;
      the teaching pages (concepts/brief) are only reachable from here. */
  protected readonly acties = [
    {
      to: '/registreren',
      titel: $localize`:@@dashboard.actie.inschrijven.titel:Inschrijven`,
      tekst: $localize`:@@dashboard.actie.inschrijven.tekst:Schrijf u in in het BIG-register via de registratiewizard.`,
      actie: $localize`:@@dashboard.actie.inschrijven.actie:Start inschrijving`,
    },
    {
      to: '/herregistratie',
      titel: $localize`:@@dashboard.actie.herregistratie.titel:Herregistratie aanvragen`,
      tekst: $localize`:@@dashboard.actie.herregistratie.tekst:Verleng uw registratie voor de komende periode.`,
      actie: $localize`:@@dashboard.actie.herregistratie.actie:Vraag aan`,
    },
    {
      to: '/intake',
      titel: $localize`:@@dashboard.actie.intake.titel:Herregistratie-intake`,
      tekst: $localize`:@@dashboard.actie.intake.tekst:Vragenlijst met vertakkingen.`,
      actie: $localize`:@@dashboard.actie.intake.actie:Start intake`,
    },
    {
      to: '/registratie',
      titel: $localize`:@@dashboard.actie.wijzigen.titel:Gegevens wijzigen`,
      tekst: $localize`:@@dashboard.actie.wijzigen.tekst:Bekijk uw gegevens of geef een wijziging door.`,
      actie: $localize`:@@dashboard.actie.wijzigen.actie:Bekijk gegevens`,
    },
    {
      to: '/concepts',
      titel: $localize`:@@dashboard.actie.concepten.titel:Functionele patronen`,
      tekst: $localize`:@@dashboard.actie.concepten.tekst:Bekijk de FP/TEA-bouwstenen van deze POC.`,
      actie: $localize`:@@dashboard.actie.concepten.actie:Bekijk patronen`,
    },
    {
      to: '/brief',
      titel: $localize`:@@dashboard.actie.brief.titel:Brief opstellen`,
      tekst: $localize`:@@dashboard.actie.brief.tekst:Stel een brief samen uit vaste en vrije onderdelen.`,
      actie: $localize`:@@dashboard.actie.brief.actie:Start brief`,
    },
  ];
}
