import { Component, ChangeDetectionStrategy, signal, inject, OnInit, input } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { StudentService, NotificationService, ErrorHandlerService } from '@core/services';
import { LoadingSpinnerComponent } from '@shared/index';

@Component({
  selector: 'app-student-form',
  standalone: true,
  imports: [
    RouterLink, ReactiveFormsModule, MatIconModule, MatButtonModule,
    MatFormFieldModule, MatInputModule, LoadingSpinnerComponent
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="page">
      <a routerLink="/students" class="back-link">
        <mat-icon>arrow_back</mat-icon>
        Volver a estudiantes
      </a>

      <header class="page-header">
        <div>
          <h1>{{ isEditing() ? 'Editar Estudiante' : 'Nuevo Estudiante' }}</h1>
          <p class="page-subtitle">
            {{ isEditing() ? 'Modifica los datos del estudiante' : 'Registra un nuevo estudiante en el sistema' }}
          </p>
        </div>
      </header>

      @if (loadingStudent()) {
        <app-loading-spinner message="Cargando datos..." />
      } @else {
        <div class="card form-card">
          <form [formGroup]="form" (ngSubmit)="onSubmit()">
            <div class="form-group">
              <label for="name">Nombre completo</label>
              <input
                id="name"
                type="text"
                class="input"
                formControlName="name"
                placeholder="Ej: Juan Pérez García"
                [class.error]="showError('name')"
                data-testid="input-name"
              >
              @if (showError('name')) {
                <span class="error-message">
                  @if (form.get('name')?.errors?.['required']) {
                    El nombre es requerido
                  } @else if (form.get('name')?.errors?.['minlength']) {
                    El nombre debe tener al menos 3 caracteres
                  }
                </span>
              }
            </div>

            <div class="form-group">
              <label for="email">Correo electrónico</label>
              <input
                id="email"
                type="email"
                class="input"
                formControlName="email"
                placeholder="Ej: juan.perez&#64;ejemplo.com"
                [class.error]="showError('email')"
                data-testid="input-email"
              >
              @if (showError('email')) {
                <span class="error-message">
                  @if (form.get('email')?.errors?.['required']) {
                    El email es requerido
                  } @else if (form.get('email')?.errors?.['email']) {
                    Ingresa un email válido
                  }
                </span>
              }
            </div>

            @if (serverError()) {
              <div class="server-error">
                <mat-icon>error</mat-icon>
                {{ serverError() }}
              </div>
            }

            <div class="form-actions">
              <a routerLink="/students" class="btn btn-secondary">Cancelar</a>
              <button
                type="submit"
                class="btn btn-primary"
                [disabled]="form.invalid || saving()"
                data-testid="btn-submit"
              >
                @if (saving()) {
                  <span class="btn-loading"></span>
                  Guardando...
                } @else {
                  <mat-icon>save</mat-icon>
                  {{ isEditing() ? 'Guardar Cambios' : 'Crear Estudiante' }}
                }
              </button>
            </div>
          </form>
        </div>
      }
    </div>
  `,
  styles: [`
    .page {
      animation: fadeIn 0.3s ease;
      max-width: 560px;
    }

    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }

    .form-card {
      padding: 2rem;
    }

    .form-actions {
      display: flex;
      justify-content: flex-end;
      gap: 0.75rem;
      margin-top: 2rem;
      padding-top: 1.5rem;
      border-top: 1px solid var(--border-light);
    }

    .server-error {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.875rem 1rem;
      background: rgba(255, 59, 48, 0.08);
      border: 1px solid rgba(255, 59, 48, 0.2);
      border-radius: var(--radius-md);
      color: var(--error);
      font-size: 0.875rem;
      margin-bottom: 1rem;

      mat-icon {
        font-size: 1.125rem;
        width: 1.125rem;
        height: 1.125rem;
      }
    }

    .btn-loading {
      width: 16px;
      height: 16px;
      border: 2px solid rgba(255, 255, 255, 0.3);
      border-top-color: white;
      border-radius: 50%;
      animation: spin 0.8s linear infinite;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }
  `],
})
export class StudentFormComponent implements OnInit {
  id = input<string>();

  private fb = inject(FormBuilder);
  private router = inject(Router);
  private studentService = inject(StudentService);
  private notification = inject(NotificationService);
  private errorHandler = inject(ErrorHandlerService);

  form: FormGroup = this.fb.group({
    name: ['', [Validators.required, Validators.minLength(3)]],
    email: ['', [Validators.required, Validators.email]],
  });

  isEditing = signal(false);
  loadingStudent = signal(false);
  saving = signal(false);
  serverError = signal<string | null>(null);

  ngOnInit(): void {
    const studentId = this.id();
    if (studentId) {
      this.isEditing.set(true);
      this.loadStudent(parseInt(studentId, 10));
    }
  }

  private loadStudent(id: number): void {
    this.loadingStudent.set(true);
    this.studentService.getStudent(id).subscribe({
      next: ({ data }) => {
        this.loadingStudent.set(false);
        if (data) {
          this.form.patchValue({ name: data.name, email: data.email });
        } else {
          this.notification.error('Estudiante no encontrado');
          this.router.navigate(['/students']);
        }
      },
      error: (error) => {
        this.loadingStudent.set(false);
        this.errorHandler.handle(error, 'StudentForm.cargar');
        this.router.navigate(['/students']);
      },
    });
  }

  showError(field: string): boolean {
    const control = this.form.get(field);
    return !!(control?.invalid && control?.touched);
  }

  onSubmit(): void {
    if (this.form.invalid) {
      this.form.markAllAsTouched();
      return;
    }

    this.saving.set(true);
    this.serverError.set(null);

    const studentId = this.id();
    const operation = studentId
      ? this.studentService.updateStudent(parseInt(studentId, 10), this.form.value)
      : this.studentService.createStudent(this.form.value);

    const action = studentId ? 'actualizar' : 'crear';

    operation.subscribe({
      next: (result) => {
        this.saving.set(false);
        if (result.student) {
          this.notification.success(
            studentId ? 'Estudiante actualizado correctamente' : 'Estudiante creado correctamente'
          );
          this.router.navigate(['/students']);
        } else if (result.errors?.length) {
          // Errores de validación del backend
          this.serverError.set(result.errors.join('. '));
        } else {
          this.serverError.set(`No se pudo ${action} el estudiante. Intenta nuevamente.`);
        }
      },
      error: (error) => {
        this.saving.set(false);
        const errorInfo = this.errorHandler.handle(error, `StudentForm.${action}`);
        this.serverError.set(errorInfo.userMessage);
      },
    });
  }
}
