import { Injectable, computed, inject, signal } from '@angular/core';
import { RemoteData, fromResource, map } from '@shared/application/remote-data';
import { Aantekening } from '../domain/registration';
import { BigProfile } from '../domain/big-profile';
import { HerregistratieDecisions, DashboardView } from '../contracts/dashboard-view.dto';
import { BigRegisterAdapter } from '../infrastructure/big-register.adapter';
import { DashboardViewAdapter, parseDashboardView } from '../infrastructure/dashboard-view.adapter';

type Err = Error | undefined;

/**
 * The single source of truth for the logged-in professional's profile, shared
 * across pages (providedIn:'root' = one instance). It owns the httpResources
 * (created here, in the required injection context) and exposes them as
 * RemoteData signals.
 *
 * The dashboard data now comes from ONE screen-shaped ("BFF-lite") call that
 * returns registration + person + server-computed `decisions`. One request → one
 * consistent snapshot, instead of stitching three independently loading/erroring
 * resources together client-side. See docs/architecture/0001-bff-lite-decision-dtos.md.
 */
@Injectable({ providedIn: 'root' })
export class BigProfileStore {
  private big = inject(BigRegisterAdapter);
  private viewAdapter = inject(DashboardViewAdapter);

  private viewRes = this.viewAdapter.dashboardViewResource();
  private aantekeningenRes = this.big.aantekeningenResource();

  /** The aggregated view, validated at the trust boundary (DTO → domain). */
  private view = computed<RemoteData<Err, DashboardView>>(() => {
    const rd = fromResource(this.viewRes);
    if (rd.tag !== 'Success') return rd;
    const parsed = parseDashboardView(rd.value);
    return parsed.ok ? { tag: 'Success', value: parsed.value } : { tag: 'Failure', error: new Error(parsed.error) };
  });

  /** Registration + person, from the single aggregated call. */
  readonly profile = computed<RemoteData<Err, BigProfile>>(() => map(this.view(), (v) => v.profile));

  /** Server-computed decisions (e.g. herregistratie eligibility) — rendered, not recomputed. */
  readonly decisions = computed<RemoteData<Err, HerregistratieDecisions>>(() => map(this.view(), (v) => v.decisions));

  /** Specialisms/notes stay a separate stream (they have their own empty state). */
  readonly aantekeningen = computed<RemoteData<Err, Aantekening[]>>(() => {
    const rd = fromResource(this.aantekeningenRes, (v) => !v || v.length === 0);
    return rd.tag === 'Success' ? { tag: 'Success', value: rd.value ?? [] } : rd;
  });

  // --- Optimistic herregistratie state, shared with the dashboard -----------
  private pending = signal(false);
  /** True while a herregistratie submission is in flight or just submitted. */
  readonly pendingHerregistratie = this.pending.asReadonly();

  beginHerregistratie() {
    this.pending.set(true); // optimistic: show it immediately on the dashboard
  }
  confirmHerregistratie() {
    this.pending.set(false);
    this.viewRes.reload(); // invalidate: re-fetch the now-updated view (registration + decisions)
  }
  rollbackHerregistratie() {
    this.pending.set(false); // submission failed — undo the optimistic flag
  }
}
