import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  Input,
  OnChanges,
  ViewChild
} from '@angular/core';

import * as QRCode from 'qrcode';

type QRCodeErrorCorrectionLevel = 'L' | 'M' | 'Q' | 'H';

@Component({
  selector: 'qrcode',
  standalone: true,
  template: '<canvas #canvas [attr.aria-label]="ariaLabel" role="img"></canvas>',
  styles: [
    `
      :host {
        display: inline-block;
        line-height: 0;
      }

      canvas {
        display: block;
        height: auto;
        max-width: 100%;
      }
    `
  ],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class QRCodeComponent implements AfterViewInit, OnChanges {
  @Input({ required: true }) qrdata = '';
  @Input() width = 200;
  @Input() errorCorrectionLevel: QRCodeErrorCorrectionLevel = 'M';
  @Input() ariaLabel = 'Codigo QR';

  @ViewChild('canvas', { static: true }) private readonly canvas!: ElementRef<HTMLCanvasElement>;

  private viewReady = false;

  ngAfterViewInit(): void {
    this.viewReady = true;
    this.render();
  }

  ngOnChanges(): void {
    this.render();
  }

  private render(): void {
    if (!this.viewReady || !this.qrdata) {
      return;
    }

    void QRCode.toCanvas(this.canvas.nativeElement, this.qrdata, {
      errorCorrectionLevel: this.errorCorrectionLevel,
      margin: 2,
      width: this.width
    }).catch(() => {
      const context = this.canvas.nativeElement.getContext('2d');
      context?.clearRect(0, 0, this.canvas.nativeElement.width, this.canvas.nativeElement.height);
    });
  }
}
