import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { ZardFormModule } from '@shared/components/form/form.module';
import { ZardInputDirective } from '@shared/components/input/input.directive';
import { ZardSelectItemComponent } from '@shared/components/select/select-item.component';
import { ZardSelectComponent } from '@shared/components/select/select.component';
import { User, UserStatus } from 'src/app/core/interfaces/user';
import { Role } from 'src/app/core/interfaces/role';
import { RoleService } from 'src/app/core/services/role';

@Component({
  selector: 'app-user-form',
  standalone: true,
  templateUrl: './user-form.html',
  styleUrls: ['./user-form.css'],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    ZardFormModule,
    ZardInputDirective,
    ZardSelectComponent,
    ZardSelectItemComponent,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UserForm {
  @Output() save = new EventEmitter<User>();
  @Output() cancel = new EventEmitter<void>();

  private _value?: User;
  @Input() set value(v: User | undefined) {
    this._value = v;
    this.hydrateFromValue(v);
  }
  get value(): User | undefined {
    return this._value;
  }

  form: FormGroup;
  submitted = false;

  roles: Role[] = [];

  constructor(private fb: FormBuilder, private roleService: RoleService) {
    this.form = this.fb.group({
      nom: ['', Validators.required],
      prenom: ['', Validators.required],
      identifiant: ['', Validators.required],
      password: ['', [Validators.minLength(8)]],
      matriculeAgent: ['', Validators.required],
      roleId: ['', Validators.required],
      restrictionConnexion: [false],
      restrictionAutomatique: [false],
      nombreIpAutorise: [0, [Validators.required, Validators.min(0)]],
      nombreIpAutoAutorise: [0, [Validators.required, Validators.min(0)]],
      statut: ['ACTIVE' as UserStatus, Validators.required],
    });

    this.roleService.allPermissions(); // warm permissions cache if needed
    // Fetch roles by listing and mapping unique names; use mock store if needed
    // Reuse RoleService through list with default params
    this.roleService
      .list({ page: 1, perPage: 100, search: '', sortKey: 'name', sortDir: 'asc' } as any)
      .subscribe((res) => {
        this.roles = res.content as any;
      });
  }

  isInvalid(control: string): boolean {
    const ctrl = this.form.get(control);
    return !!(ctrl && ctrl.invalid && (ctrl.touched || this.submitted));
  }

  errorMessage(control: string): string | null {
    const c = this.form.get(control);
    if (!c || !c.errors) return null;
    if (c.errors['required']) return 'Ce champ est obligatoire';
    if (c.errors['min']) return `Valeur minimale : ${c.errors['min'].min}`;
    if (c.errors['minlength']) return `Minimum ${c.errors['minlength'].requiredLength} caractères`;
    return null;
  }

  private hydrateFromValue(v?: User) {
    if (v) {
      this.form.reset({
        nom: v.nom,
        prenom: v.prenom,
        identifiant: v.identifiant,
        password: '',
        matriculeAgent: v.matriculeAgent,
        // Utiliser roleId directement si le rôle n'est pas hydraté
        roleId: v.role?.id ?? v.roleId ?? '',
        restrictionConnexion: v.restrictionConnexion,
        restrictionAutomatique: v.restrictionAutomatique,
        nombreIpAutorise: v.nombreIpAutorise,
        nombreIpAutoAutorise: v.nombreIpAutoAutorise,
        statut: v.statut,
      });
    } else {
      this.form.reset({
        nom: '',
        prenom: '',
        identifiant: '',
        password: '',
        matriculeAgent: '',
        roleId: '',
        restrictionConnexion: false,
        restrictionAutomatique: false,
        nombreIpAutorise: 0,
        nombreIpAutoAutorise: 0,
        statut: 'ACTIVE' as UserStatus,
      });
    }
  }

  onSubmit() {
    this.submitted = true;
    if (!this.form.valid) {
      this.form.markAllAsTouched();
      return;
    }
    const raw = this.form.getRawValue() as any;
    const role = this.roles.find((r) => r.id === raw.roleId);
    if (!role) {
      return;
    }
    const payload: User = {
      ...(this.value ?? {}),
      id: this.value?.id ?? '',
      nom: raw.nom,
      prenom: raw.prenom,
      identifiant: raw.identifiant,
      // Only send password if filled (for create or change)
      password: raw.password ? String(raw.password) : undefined,
      matriculeAgent: raw.matriculeAgent,
      roleId: role.id,
      role,
      restrictionConnexion: !!raw.restrictionConnexion,
      restrictionAutomatique: !!raw.restrictionAutomatique,
      nombreIpAutorise: Number(raw.nombreIpAutorise),
      nombreIpAutoAutorise: Number(raw.nombreIpAutoAutorise),
      statut: raw.statut as UserStatus,
      updatedAt: new Date().toISOString(),
    };
    this.save.emit(payload);
  }
}
