import { LitElement, html, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { event, type EventRef } from '@dh-software/lit-extensions';
import type { EintragMitBefund, LokalerZustand } from '../bruecke';

/** Was der jeweilige Zustand für den Nutzer bedeutet. */
const ZUSTAND_TEXT: Record<LokalerZustand, string> = {
  fehlt: 'nicht auf diesem Rechner',
  aktuell: 'aktuell',
  veraltet: 'veraltet',
  fremd: 'von Hand verändert',
};

const ZUSTAND_KLASSE: Record<LokalerZustand, string> = {
  fehlt: 'zustand-fehlt',
  aktuell: 'zustand-aktuell',
  veraltet: 'zustand-veraltet',
  fremd: 'zustand-fremd',
};

/**
 * Eine Zeile des Katalogs im Client. Anders als in der Weboberfläche steht hier,
 * was auf diesem Rechner liegt — das ist der ganze Unterschied.
 */
@customElement('client-zeile')
export class ClientZeile extends LitElement {
  @property({ attribute: false }) eintrag!: EintragMitBefund;
  @property({ type: Boolean }) laeuft = false;

  @event({ bubbles: true, composed: true }, 'holen')
  private holen!: EventRef<EintragMitBefund>;

  @event({ bubbles: true, composed: true }, 'verknuepfen')
  private verknuepfen!: EventRef<EintragMitBefund>;

  // Light DOM, damit das globale dh-components-Theme greift.
  createRenderRoot() {
    return this;
  }

  render() {
    const eintrag = this.eintrag;
    return html`
      <div class="zeile">
        <div class="zeile-info">
          <span class="zeile-name">
            ${eintrag.name}
            ${eintrag.einstufung === 'lizenzpflichtig'
              ? html`<span class="marke lizenz-marke">lizenzpflichtig</span>`
              : nothing}
            ${eintrag.einstufung === 'intern' ? html`<span class="marke intern-marke">intern</span>` : nothing}
          </span>
          <span class="zeile-meta">${this.rendereStand()}${this.rendereZustand()}</span>
          ${eintrag.hinweis ? html`<span class="zeile-hinweis">${eintrag.hinweis}</span>` : nothing}
        </div>
        <div class="zeile-aktionen">${this.rendereAktion()}${this.rendereVerknuepfung()}</div>
      </div>
    `;
  }

  private rendereStand() {
    const zeitpunkt = this.eintrag.veroeffentlichtAm || this.eintrag.dateiStandVom;
    if (!zeitpunkt) {
      return nothing;
    }
    const datum = new Date(zeitpunkt);
    if (Number.isNaN(datum.getTime())) {
      return nothing;
    }
    return html`Stand ${datum.toLocaleDateString('de-DE')}`;
  }

  /** Nur bei eigenständigen Programmen aussagekräftig — Installer verraten hier nichts. */
  private rendereZustand() {
    const befund = this.eintrag.lokal;
    if (!befund) {
      return nothing;
    }
    return html` &nbsp;·&nbsp;
      <span class=${ZUSTAND_KLASSE[befund.zustand]}>${ZUSTAND_TEXT[befund.zustand]}</span>`;
  }

  /**
   * Ein rundes Symbol wie in der Weboberfläche. Was der Klick bewirkt, steht
   * ohnehin schon als Zustand in der Zeile — die Beschriftung wäre eine
   * Wiederholung. Steht ein Update an, ist der Knopf gefüllt statt flach.
   */
  private rendereAktion() {
    const eintrag = this.eintrag;
    if (!eintrag.dateiname) {
      return html`<span class="zeile-hinweis">keine Datei hinterlegt</span>`;
    }
    const zustand = eintrag.lokal?.zustand;
    const stehtAn = zustand === 'veraltet' || zustand === 'fremd';
    const zweck = stehtAn ? 'aktualisieren' : zustand === 'aktuell' ? 'erneut holen' : 'holen';
    return html`<dh-button
      icon-button
      variant=${stehtAn ? 'filled' : 'standard'}
      title=${`${eintrag.name} ${zweck}`}
      ?disabled=${this.laeuft}
      @click=${this.beiHolen}
    >
      <span slot="img" class="fv-icon-download"></span>
    </dh-button>`;
  }

  private rendereVerknuepfung() {
    const befund = this.eintrag.lokal;
    if (!befund || befund.zustand === 'fehlt') {
      return nothing;
    }
    return html`<dh-button
      icon-button
      variant="standard"
      title="Verknüpfung auf dem Desktop anlegen"
      @click=${this.beiVerknuepfen}
    >
      <span slot="img" class="fv-icon-link"></span>
    </dh-button>`;
  }

  private beiHolen(): void {
    this.holen.dispatch(this.eintrag);
  }

  private beiVerknuepfen(): void {
    this.verknuepfen.dispatch(this.eintrag);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'client-zeile': ClientZeile;
  }
}
