import { Component, ChangeDetectionStrategy, Input, Injector, Signal, signal, inject, effect, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService, AdminAuthService, AuthSession, MARKETPLACES_AUTH_GATEWAY } from '@marketplaces/auth';
import { LanguageService } from '../../services/language.service';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { QrLoginEngine } from '../../shared/qr-login/qr-login.engine';
import { QrLoginAdapter, QrLoginStatus } from '../../shared/qr-login/qr-login.model';
import { IconComponent } from '../../shared/ui/icon/icon.component';

/**
 * The one QR-login dialog, reused as-is for both customer and admin login.
 * `mode` only decides which session service/storage backs it (AuthService's
 * customer session vs AdminAuthService's admin session) - the QR creation,
 * polling, expiry, and "return from Telegram app" logic (QrLoginEngine) and
 * the API call underneath it (TelegramSessionApiService) are identical for
 * both, by design: there is one Telegram QR/session backend, not two.
 */
@Component({
  selector: 'app-telegram-login',
  imports: [TranslatePipe, IconComponent],
  templateUrl: './telegram-login.component.html',
  styleUrls: ['./telegram-login.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TelegramLoginComponent implements OnInit, OnDestroy {
  @Input() mode: 'customer' | 'admin' = 'customer';

  private readonly customerAuth = inject(AuthService);
  private readonly adminAuth = inject(AdminAuthService);
  private readonly authGateway = inject(MARKETPLACES_AUTH_GATEWAY);
  private readonly injector = inject(Injector);
  private readonly router = inject(Router);
  private readonly languageService = inject(LanguageService);

  private engine!: QrLoginEngine<AuthSession>;

  showDialog = this.customerAuth.showLoginDialog;
  status = this.customerAuth.status;

  loginUrl!: Signal<string>;
  webSessionID!: Signal<string>;
  qrStatus!: Signal<QrLoginStatus>;
  encodedQrUrl!: Signal<string>;

  // Admin-only: password login per docs/backend/BACKEND-INTEGRATION.md §1.2.
  // Backend endpoint isn't live yet, so any failure here (404 today, or a
  // real auth failure once it ships) surfaces as one generic message -
  // never the raw error - per product decision to keep Telegram as the
  // fallback path rather than leak backend state.
  credentialsVisible = signal(false);
  credentialsLogin = signal('');
  credentialsPassword = signal('');
  credentialsBusy = signal(false);
  credentialsError = signal(false);

  ngOnInit(): void {
    const service = this.mode === 'admin' ? this.adminAuth : this.customerAuth;
    this.showDialog = service.showLoginDialog;
    this.status = service.status;

    const adapter: QrLoginAdapter<AuthSession> = this.mode === 'admin'
      ? {
          createSession: () => this.adminAuth.createWebSession(),
          checkSessionOnce: id => this.adminAuth.checkSessionOnce(id),
          isSessionActive: session => !!session?.active,
          getAppLoginUrl: id => this.adminAuth.getAdminAppLoginUrl(id),
          onLoginComplete: () => {
            this.adminAuth.onLoginComplete();
            void this.router.navigate([this.languageService.currentLanguage(), 'backoffice', 'dashboard']);
          },
        }
      : {
          createSession: () => this.customerAuth.createWebSession(),
          checkSessionOnce: id => this.customerAuth.checkSessionOnce(id),
          isSessionActive: session => !!session?.active,
          getAppLoginUrl: id => this.customerAuth.getTelegramAppLoginUrl(id),
          onLoginComplete: () => this.customerAuth.onTelegramLoginComplete(),
        };

    this.engine = new QrLoginEngine<AuthSession>(adapter);
    this.loginUrl = this.engine.loginUrl;
    this.webSessionID = this.engine.webSessionID;
    this.qrStatus = this.engine.qrStatus;
    this.encodedQrUrl = this.engine.encodedQrUrl;

    effect(() => this.engine.setActive(this.showDialog()), { injector: this.injector });
  }

  ngOnDestroy(): void {
    this.engine?.destroy();
  }

  close(): void {
    this.engine.setActive(false);
    (this.mode === 'admin' ? this.adminAuth : this.customerAuth).hideLogin();
    this.resetCredentials();
  }

  openTelegramLogin(): void {
    this.engine.openAppLogin();
  }

  refreshQr(): void {
    this.engine.refresh();
  }

  toggleCredentials(): void {
    this.credentialsVisible.update(visible => !visible);
    this.credentialsError.set(false);
  }

  submitCredentials(event: Event): void {
    event.preventDefault();
    const login = this.credentialsLogin().trim();
    const password = this.credentialsPassword();
    if (!login || !password || this.credentialsBusy()) return;

    this.credentialsBusy.set(true);
    this.credentialsError.set(false);
    this.authGateway.loginWithCredentials('admin', { login, password }).subscribe({
      next: () => {
        this.credentialsBusy.set(false);
        this.adminAuth.onLoginComplete();
        void this.router.navigate([this.languageService.currentLanguage(), 'backoffice', 'dashboard']);
      },
      error: () => {
        this.credentialsBusy.set(false);
        this.credentialsError.set(true);
      },
    });
  }

  private resetCredentials(): void {
    this.credentialsVisible.set(false);
    this.credentialsLogin.set('');
    this.credentialsPassword.set('');
    this.credentialsBusy.set(false);
    this.credentialsError.set(false);
  }
}
