import {
  Component,
  ElementRef,
  EventEmitter,
  OnDestroy,
  Output,
  ViewChild,
} from '@angular/core';
import { FormsModule } from '@angular/forms';
import SignaturePad from 'signature_pad';

/** Police manuscrite proposée pour la signature dactylographiée. */
interface PoliceSignature {
  nom: string;
  /** Famille seule (avec guillemets), ex. "'Dancing Script'" — pour la Font Loading API. */
  famille: string;
  /** Pile complète avec repli, ex. "'Dancing Script', cursive" — pour le rendu CSS/canvas. */
  css: string;
}

/**
 * Boîte de dialogue de signature, avec deux modes :
 *  - « Dessiner » : tracé à main levée (librairie signature_pad) ;
 *  - « Écrire »   : saisie d'un texte rendu dans une police manuscrite,
 *                   converti en image PNG transparente.
 *
 * Dans les deux cas, la signature est émise en data URL PNG via `valide`
 * (l'éditeur la pose ensuite comme une image), ou `annule` à la fermeture.
 */
@Component({
  selector: 'app-signature-dialog',
  standalone: true,
  imports: [FormsModule],
  template: `
    <div class="overlay" (click)="annuler()">
      <div class="modale" (click)="$event.stopPropagation()">
        <div class="onglets">
          <button
            class="onglet"
            [class.actif]="mode === 'dessin'"
            (click)="mode = 'dessin'"
          >
            ✍ Dessiner
          </button>
          <button
            class="onglet"
            [class.actif]="mode === 'texte'"
            (click)="mode = 'texte'"
          >
            ⌨ Écrire
          </button>
        </div>

        <!-- Mode dessin (le canvas reste dans le DOM pour conserver le tracé) -->
        <div class="panneau" [style.display]="mode === 'dessin' ? 'block' : 'none'">
          <div class="zone-signature">
            <canvas #canvas width="500" height="200"></canvas>
          </div>
          <div class="actions">
            <button class="btn" (click)="effacer()">Effacer</button>
          </div>
        </div>

        <!-- Mode texte stylisé -->
        <div class="panneau" [style.display]="mode === 'texte' ? 'block' : 'none'">
          <input
            class="champ-texte"
            type="text"
            placeholder="Tapez votre nom…"
            [(ngModel)]="texteSignature"
            name="signature"
          />
          <div class="polices">
            @for (p of polices; track p.nom) {
              <button
                class="choix-police"
                [class.actif]="police === p"
                [style.fontFamily]="p.css"
                (click)="police = p"
              >
                {{ texteSignature || 'Signature' }}
              </button>
            }
          </div>
          <div class="apercu">
            <span [style.fontFamily]="police.css">{{ texteSignature || 'Aperçu de la signature' }}</span>
          </div>
        </div>

        <div class="actions pied">
          <span class="espace"></span>
          <button class="btn" (click)="annuler()">Annuler</button>
          <button class="btn btn-primaire" (click)="valider()">
            Insérer la signature
          </button>
        </div>
      </div>
    </div>
  `,
  styles: [
    `
      .overlay {
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.55);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 1000;
      }
      .modale {
        background: #fff;
        border-radius: 10px;
        padding: 22px;
        box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
        width: 540px;
        max-width: 92vw;
      }
      .onglets {
        display: flex;
        gap: 6px;
        margin-bottom: 16px;
      }
      .onglet {
        flex: 1;
        padding: 9px 12px;
        border: 1px solid var(--couleur-bordure, #d0d0d0);
        background: #f7f7f7;
        border-radius: 8px;
        cursor: pointer;
        font: inherit;
      }
      .onglet.actif {
        background: var(--couleur-primaire);
        color: #fff;
        border-color: var(--couleur-primaire);
      }
      .zone-signature {
        border: 2px dashed var(--couleur-bordure);
        border-radius: 8px;
        background: #fff;
      }
      canvas {
        display: block;
        touch-action: none;
        cursor: crosshair;
        width: 100%;
      }
      .champ-texte {
        width: 100%;
        box-sizing: border-box;
        padding: 10px 12px;
        font-size: 16px;
        border: 1px solid var(--couleur-bordure, #d0d0d0);
        border-radius: 8px;
      }
      .polices {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
        margin-top: 12px;
      }
      .choix-police {
        padding: 10px;
        border: 1px solid var(--couleur-bordure, #d0d0d0);
        border-radius: 8px;
        background: #fff;
        cursor: pointer;
        font-size: 26px;
        color: #0a2540;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .choix-police.actif {
        border-color: var(--couleur-primaire);
        box-shadow: 0 0 0 2px var(--couleur-primaire) inset;
      }
      .apercu {
        margin-top: 14px;
        min-height: 70px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--couleur-bordure, #eee);
        border-radius: 8px;
        background: #fafafa;
        font-size: 44px;
        color: #0a2540;
        overflow: hidden;
      }
      .actions {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-top: 14px;
      }
      .actions.pied {
        margin-top: 18px;
      }
      .espace {
        flex: 1;
      }
    `,
  ],
})
export class SignatureDialogComponent implements OnDestroy {
  @Output() valide = new EventEmitter<string>();
  @Output() annule = new EventEmitter<void>();

  mode: 'dessin' | 'texte' = 'dessin';

  // --- Mode texte ---
  texteSignature = '';
  readonly polices: PoliceSignature[] = [
    { nom: 'Dancing Script', famille: "'Dancing Script'", css: "'Dancing Script', cursive" },
    { nom: 'Great Vibes', famille: "'Great Vibes'", css: "'Great Vibes', cursive" },
    { nom: 'Sacramento', famille: "'Sacramento'", css: "'Sacramento', cursive" },
    { nom: 'Satisfy', famille: "'Satisfy'", css: "'Satisfy', cursive" },
    { nom: 'Caveat', famille: "'Caveat'", css: "'Caveat', cursive" },
    { nom: 'Allura', famille: "'Allura'", css: "'Allura', cursive" },
  ];
  police: PoliceSignature = this.polices[0];

  // --- Mode dessin ---
  private pad?: SignaturePad;

  /**
   * ViewChild via setter : le canvas n'apparaît qu'en mode dessin (display),
   * mais reste dans le DOM, donc le setter est appelé une fois à l'init.
   */
  @ViewChild('canvas')
  set canvasRef(ref: ElementRef<HTMLCanvasElement> | undefined) {
    if (ref && !this.pad) {
      this.pad = new SignaturePad(ref.nativeElement, {
        penColor: '#0a2540',
        backgroundColor: 'rgba(0,0,0,0)', // fond transparent
      });
    }
  }

  ngOnDestroy(): void {
    this.pad?.off();
  }

  effacer(): void {
    this.pad?.clear();
  }

  annuler(): void {
    this.annule.emit();
  }

  async valider(): Promise<void> {
    if (this.mode === 'dessin') {
      if (!this.pad || this.pad.isEmpty()) {
        return;
      }
      this.valide.emit(this.pad.toDataURL('image/png'));
    } else {
      const dataUrl = await this.genererTexteSignature();
      if (dataUrl) {
        this.valide.emit(dataUrl);
      }
    }
  }

  /** Rend le texte saisi dans la police choisie sur un canvas PNG transparent. */
  private async genererTexteSignature(): Promise<string | null> {
    const texte = this.texteSignature.trim();
    if (!texte) {
      return null;
    }
    const taille = 96;
    const marge = 40;
    // Le canvas n'utilise une police que si elle est déjà chargée par le navigateur :
    // on l'attend explicitement via la Font Loading API avant de mesurer/dessiner.
    await document.fonts.load(`${taille}px ${this.police.famille}`);
    const mesure = document.createElement('canvas').getContext('2d')!;
    const fontCss = `${taille}px ${this.police.css}`;
    mesure.font = fontCss;
    const largeur = Math.ceil(mesure.measureText(texte).width + marge * 2);
    const hauteur = Math.ceil(taille * 1.6);

    const canvas = document.createElement('canvas');
    canvas.width = largeur;
    canvas.height = hauteur;
    const ctx = canvas.getContext('2d')!;
    ctx.clearRect(0, 0, largeur, hauteur);
    ctx.font = fontCss;
    ctx.fillStyle = '#0a2540';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(texte, largeur / 2, hauteur / 2);
    return canvas.toDataURL('image/png');
  }
}
