// src/app/modules/auth/sign-in/sign-in.ts
import { Component, inject, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, NgForm } from '@angular/forms';
import { Router, RouterLink } from '@angular/router';
import { Subject, takeUntil } from 'rxjs';
import { AuthService, LoginDto } from '@core/services/auth.service';
import { RoleService } from '@core/services/role.service';
import { AppLogo } from '@app/components/app-logo';
import { PasswordStrengthBar } from '@app/components/password-strength-bar';
import { appName, credits, currentYear } from '@/app/constants';

@Component({
  selector: 'app-sign-in',
  standalone: true,
  imports: [FormsModule, CommonModule, RouterLink, AppLogo, PasswordStrengthBar],
  template: `
    <div class="auth-box overflow-hidden align-items-center d-flex">
      <div class="container">
        <div class="row justify-content-center">
          <div class="col-xxl-4 col-md-6 col-sm-8">
            <div class="card">
              <div class="card-body">
                <div class="auth-brand mb-4">
                  <app-app-logo />
                  <p class="text-muted w-lg-75 mt-3">
                    Let's get you signed in. Enter your username and password to continue.
                  </p>
                </div>

                <form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)" novalidate autocomplete="on">
                  <div class="mb-3">
                    <label for="username" class="form-label">
                      Username <span class="text-danger">*</span>
                    </label>
                    <input
                      type="text"
                      id="username"
                      name="username"
                      class="form-control"
                      placeholder="Enter your Username"
                      required
                      username
                      [(ngModel)]="credentials.username"
                      #usernameCtrl="ngModel"
                      [class.is-invalid]="usernameCtrl.invalid && usernameCtrl.touched"
                      [attr.aria-describedby]="usernameCtrl.invalid && usernameCtrl.touched ? 'username-error' : null"
                      autocomplete="username"
                    />
                    <div *ngIf="usernameCtrl.invalid && usernameCtrl.touched" 
                         id="username-error" 
                         class="invalid-feedback">
                      <span *ngIf="usernameCtrl.errors?.['required']">Username is required</span>
                      <span *ngIf="usernameCtrl.errors?.['username']">Please enter a valid email address</span>
                    </div>
                  </div>

                  <div class="mb-3">
                    <label for="password" class="form-label">
                      Password <span class="text-danger">*</span>
                    </label>
                    <input
                      type="password"
                      id="password"
                      name="password"
                      class="form-control"
                      placeholder="••••••••"
                      required
                      minlength="6"
                      [(ngModel)]="credentials.password"
                      #passwordCtrl="ngModel"
                      [class.is-invalid]="passwordCtrl.invalid && passwordCtrl.touched"
                      [attr.aria-describedby]="passwordCtrl.invalid && passwordCtrl.touched ? 'password-error' : null"
                      autocomplete="current-password"
                    />
                    <div *ngIf="passwordCtrl.invalid && passwordCtrl.touched" 
                         id="password-error" 
                         class="invalid-feedback">
                      <span *ngIf="passwordCtrl.errors?.['required']">Password is required</span>
                      <span *ngIf="passwordCtrl.errors?.['minlength']">
                        Password must be at least 6 characters
                      </span>
                    </div>

                    <!-- Password strength bar -->
                    <app-password-strength-bar 
                      [password]="credentials.password || ''"
                      class="mt-2"
                    ></app-password-strength-bar>
                  </div>
                  
                  <!-- Server-side error message -->
                  <div *ngIf="errorMessage" 
                       id="error-message"
                       class="alert alert-danger mt-3" 
                       role="alert"
                       aria-live="polite"
                       tabindex="-1">
                    <i class="ri-error-warning-line me-2"></i>
                    {{ errorMessage }}
                  </div>

                  <div class="d-flex justify-content-between align-items-center mb-3">
                    <div class="form-check">
                      <input
                        type="checkbox"
                        id="rememberMe"
                        class="form-check-input"
                        [(ngModel)]="rememberMe"
                        name="rememberMe"
                      />
                      <label class="form-check-label" for="rememberMe">
                        Keep me signed in
                      </label>
                    </div>
                    <a
                      routerLink="/auth/reset-password"
                      class="text-decoration-underline link-offset-3 text-muted"
                    >
                      Forgot Password?
                    </a>
                  </div>

                  <div class="d-grid">
                    <button
                      type="submit"
                      class="btn btn-primary fw-semibold py-2"
                      [disabled]="loginForm.invalid || loading"
                      [attr.aria-busy]="loading"
                    >
                      <span *ngIf="loading" class="spinner-border spinner-border-sm me-2" role="status"></span>
                      {{ loading ? 'Signing In...' : 'Sign In' }}
                    </button>
                  </div>

                </form>

              </div>
            </div>

            <p class="text-center text-muted mt-4 mb-0">
              © {{ currentYear }} {{ appName }}. Tous droits réservés. — Développé par
              <span class="fw-semibold">{{ credits.name }}</span>
            </p>
          </div>
        </div>
      </div>
    </div>
  `,
  styles: []
})
export class SignIn implements OnInit, OnDestroy {
  protected readonly appName = appName;
  protected readonly currentYear = currentYear;
  protected readonly credits = credits;

  private authService = inject(AuthService);
  private roleService = inject(RoleService);
  private router = inject(Router);
  private cdRef = inject(ChangeDetectorRef);
  private destroy$ = new Subject<void>();

  credentials: LoginDto = {
    username: '',
    password: ''
  };
  
  rememberMe: boolean = false;
  loading: boolean = false;
  errorMessage: string | null = null;

  ngOnInit(): void {
    // Vérifier si l'utilisateur est déjà connecté
    this.checkExistingAuth();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  /**
   * Vérifie si l'utilisateur a déjà une session valide
   */
  private checkExistingAuth(): void {
    if (this.authService.isAuthenticated()) {
      this.redirectBasedOnRoles();
    }
  }

  /**
   * Soumission du formulaire de connexion
   */
  onSubmit(form: NgForm): void {
    // Marquer tous les champs comme touchés pour afficher les erreurs
    if (form.invalid) {
      this.markFormGroupTouched(form);
      this.focusFirstInvalidField();
      return;
    }

    this.loading = true;
    this.errorMessage = null;

    this.authService.login(this.credentials)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: () => {
          this.handleLoginSuccess();
        },
        error: (error) => {
          this.handleLoginError(error);
        }
      });
  }

  /**
   * Gestion de la connexion réussie
   */
  private handleLoginSuccess(): void {
    this.loading = false;
    
    // Rafraîchir les rôles après connexion
    this.roleService.refreshRoles();
    
    // Rediriger en fonction des rôles
    this.redirectBasedOnRoles();
  }

  /**
   * Gestion des erreurs de connexion
   */
  private handleLoginError(error: any): void {
    this.loading = false;
    
    // Messages d'erreur spécifiques selon le type d'erreur
    if (error.status === 401) {
      this.errorMessage = 'Invalid email or password. Please try again.';
    } else if (error.status === 403) {
      this.errorMessage = 'Your account is disabled or not fully set up. Please contact support.';
    } else if (error.status === 0 || error.status === 500) {
      this.errorMessage = 'Server is unavailable. Please try again later.';
    } else {
      this.errorMessage = error.message || 'An unexpected error occurred. Please try again.';
    }

    // Forcer la mise à jour de la vue
    this.cdRef.detectChanges();
    
    // Scroll et focus sur l'erreur
    this.scrollToError();
  }

  /**
   * Redirection basée sur les rôles de l'utilisateur
   */
  private redirectBasedOnRoles(): void {
    const userRoles = this.roleService.getCurrentUserRoles();
    
    // Logique de redirection selon les rôles
    if (userRoles.includes('dcb-admin')) {
      this.router.navigate(['/admin/dcb-dashboard']);
    } else if (userRoles.includes('dcb-partner-admin')) {
      this.router.navigate(['/partner/dcb-dashboard']);
    } else if (userRoles.includes('dcb-support')) {
      this.router.navigate(['/support/dcb-dashboard']);
    } else {
      // Route par défaut
      this.router.navigate(['/dcb-dashboard']);
    }
  }

  /**
   * Marque tous les champs du formulaire comme touchés
   */
  private markFormGroupTouched(form: NgForm): void {
    Object.keys(form.controls).forEach(key => {
      const control = form.controls[key];
      control.markAsTouched();
    });
  }

  /**
   * Focus sur le premier champ invalide
   */
  private focusFirstInvalidField(): void {
    setTimeout(() => {
      const firstInvalidElement = document.querySelector('.is-invalid') as HTMLElement;
      if (firstInvalidElement) {
        firstInvalidElement.focus();
      }
    }, 100);
  }

  /**
   * Scroll vers le message d'erreur
   */
  private scrollToError(): void {
    setTimeout(() => {
      const errorElement = document.getElementById('error-message');
      if (errorElement) {
        errorElement.scrollIntoView({ 
          behavior: 'smooth', 
          block: 'center' 
        });
        errorElement.focus();
      }
    }, 100);
  }

  /**
   * Réinitialise le formulaire
   */
  resetForm(form: NgForm): void {
    form.resetForm();
    this.credentials = { username: '', password: '' };
    this.errorMessage = null;
    this.rememberMe = false;
  }
}