import { css, html, LitElement, unsafeCSS } from "lit";
import { property } from "lit/decorators.js";
import { pdfViwerEvents } from "../../../../src/api/pdf-viewer-manager/events";
import { lazyInject } from "../../../../src/infrastructure/ioc/container";
import { TYPES } from "../../../../src/infrastructure/ioc/types";
import { translate } from "../../../../src/locales";
import { PrimariaApi } from "../../../api/api";
import { BrokerDisposableHandler } from "../../../api/broker/primaria-broker";
import { IPdfDocument } from "../../../api/pdf-viewer-manager/pdf-viewer-manager";
import styles from "./styles.css?inline";
import { createUrlFromBase64 } from "./utils";

export class PdfVisor extends LitElement {
  static styles = css`${unsafeCSS(styles)}`;

  @lazyInject(TYPES.primaryApi)
  api: PrimariaApi;

  @property({ type: Array })
  pdfList: IPdfDocument[] = [];

  @property({ type: Array })
  activePdfs: IPdfDocument[] = [];

  private subscriptions: BrokerDisposableHandler[] = [];

  async connectedCallback() {
    super.connectedCallback();
    this._initializePdfState();
    this._subscribeEvents();
  }

  disconnectedCallback(): void {
    super.disconnectedCallback();
    this._unsubscribeEvents();
  }

  private _initializePdfState() {
    const initialPdfs = this.api.pdfViewerManager.getPdfs?.() || [];
    this.pdfList = [...initialPdfs];

    if (initialPdfs.length === 1) {
      this.activePdfs = [initialPdfs[0] as IPdfDocument];
    } else if (initialPdfs.length >= 2) {
      this.activePdfs = initialPdfs.slice(-2);
    }
  }

  private _getPdfSrc(pdf: IPdfDocument): string {
    const src = pdf.data.url || (pdf.data.b64 ? createUrlFromBase64(pdf.data.b64) : "") || "";
    if (!src) return "";

    const separator = src.includes("#") ? "&" : "#";
    return `${src}${separator}navpanes=0`;
  }

  private _subscribeEvents() {
    const subscriptions = [
      this.api.broker.subscribe(pdfViwerEvents.added, (pdf: IPdfDocument) => this._onPdfAdded(pdf)),
      this.api.broker.subscribe(pdfViwerEvents.deleted, ({ id }) => this._onPdfDeleted({ id })),
    ];
    subscriptions.forEach((s) => this.subscriptions.push(s));
  }

  private _unsubscribeEvents() {
    this.subscriptions.forEach((s) => s.dispose());
  }

  private _onPdfAdded(pdf: IPdfDocument) {
    this.pdfList = [...this.pdfList, pdf];
    this._updateActivePdfs(pdf.id);
  }

  private _onPdfDeleted({ id }) {
    this.pdfList = this.pdfList.filter((pdf) => pdf.id !== id);
    this.activePdfs = this.activePdfs.filter((pdf) => pdf.id !== id);
    this.requestUpdate();
  }

  private _removePdf(id: string) {
    this.api.pdfViewerManager.delete(id);
    this.activePdfs = this.activePdfs.filter((pdf) => pdf.id !== id);
  }

  private _updateActivePdfs(id: string) {
    const isAlreadyActive = this.activePdfs.some((pdf) => pdf.id === id);
    if (isAlreadyActive) {
      this.activePdfs = this.activePdfs.filter((pdf) => pdf.id !== id);
    } else {
      const newPdf = this.pdfList.find((pdf) => pdf.id === id);
      if (!newPdf) return;
      if (this.activePdfs.length === 2) {
        this.activePdfs = [this.activePdfs[1] as IPdfDocument, newPdf];
      } else {
        this.activePdfs = [...this.activePdfs, newPdf];
      }
    }
    this.requestUpdate();
  }

  render() {
    return html`
      <div class="pdf-container">
        ${
          this.activePdfs.length > 0
            ? this.activePdfs.map((pdf) => html`<iframe height="100%" src=${this._getPdfSrc(pdf)} frameborder="0"></iframe>`)
            : html`
                <div class="no-pdf">
                  <p>${translate("pdfVisor.noPdfSelected")}</p>
                </div>
              `
        }
      </div>
      <pdf-selector
        .pdfList=${this.pdfList}
        .activePdfs=${this.activePdfs}
        @pdf-removed=${(e: CustomEvent) => this._removePdf(e.detail)}
        @active-pdf-changed=${(e: CustomEvent) => this._updateActivePdfs(e.detail)}
      ></pdf-selector>
    `;
  }
}
