import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { DialogsModule } from '@progress/kendo-angular-dialog';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { LabelModule } from '@progress/kendo-angular-label';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { IndicatorsModule } from '@progress/kendo-angular-indicators';
import { MemberListItemDto, memberDisplayName } from '../../models/member.model';
import { InvitationApiService } from '../../services/invitation-api.service';
import { ToastService } from '../../../../core/services/toast.service';

type Step = 'needEmail' | 'generating' | 'ready';

@Component({
  selector: 'app-invitation-dialog',
  standalone: true,
  imports: [
    CommonModule, ReactiveFormsModule, DialogsModule, InputsModule,
    LabelModule, ButtonsModule, IndicatorsModule,
  ],
  templateUrl: './invitation-dialog.component.html',
})
export class InvitationDialogComponent implements OnInit {
  @Input({ required: true }) member!: MemberListItemDto;
  @Output() cancelled = new EventEmitter<void>();

  step: Step = 'generating';
  emailForm!: FormGroup;

  link = '';
  expiresAt: string | null = null;
  copied = false;
  isSending = false;
  errorMessage = '';

  get memberName(): string { return memberDisplayName(this.member); }

  constructor(
    private fb: FormBuilder,
    private invitationApi: InvitationApiService,
    private toast: ToastService,
  ) {}

  ngOnInit(): void {
    this.emailForm = this.fb.group({
      email: [this.member.email ?? '', [Validators.required, Validators.email]],
    });

    // Auto-generate when the member already has an email; otherwise ask for one first.
    if (this.member.email) {
      this.generate();
    } else {
      this.step = 'needEmail';
    }
  }

  /** Generate (or re-issue) the link. Uses the form email when the member has none on file. */
  generate(): void {
    if (this.step === 'needEmail') {
      if (this.emailForm.invalid) { this.emailForm.markAllAsTouched(); return; }
    }

    const email = this.member.email ? undefined : this.emailForm.value.email;
    this.step = 'generating';
    this.errorMessage = '';

    this.invitationApi.create(this.member.id, email).subscribe({
      next: (result) => {
        this.link      = `${window.location.origin}/accept-invitation?token=${result.token}`;
        this.expiresAt = result.expiresAt;
        this.step      = 'ready';
      },
      error: (err) => {
        this.errorMessage = err.error?.message ?? 'Failed to create the invitation link.';
        // Fall back to the email step so the admin can supply/correct an address.
        this.step = 'needEmail';
      },
    });
  }

  copyLink(): void {
    navigator.clipboard.writeText(this.link).then(() => {
      this.copied = true;
      setTimeout(() => (this.copied = false), 2000);
    });
  }

  sendEmail(): void {
    this.isSending = true;
    this.invitationApi.sendEmail(this.member.id, this.link).subscribe({
      next: () => {
        this.toast.success(`Invitation emailed to ${this.memberName}.`);
        this.isSending = false;
      },
      error: (err) => {
        this.toast.error(err.error?.message ?? 'Failed to send the email.');
        this.isSending = false;
      },
    });
  }

  onClose(): void {
    this.cancelled.emit();
  }
}
