import { CommonModule } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  ViewChild,
  signal,
  effect,
  untracked,
} from '@angular/core';
import { DataTable, TableColumn, SortState } from '@shared/components/data-table/data-table';
import { Paginator } from '@shared/components/paginator/paginator';
import { SearchBar } from '@shared/components/search-bar/search-bar';
import { Modal } from '@shared/components/modal/modal';
import { ZardButtonComponent } from '@shared/components/button/button.component';
import { SortDir } from '@shared/paging/paging';
import { User } from 'src/app/core/interfaces/user';
import { UserService } from 'src/app/core/services/user';
import { Role } from 'src/app/core/interfaces/role';
import { RoleService } from 'src/app/core/services/role';
import { UserForm } from '@shared/forms/user-form/user-form';
import { toast } from 'ngx-sonner';

@Component({
  standalone: true,
  selector: 'app-users',
  templateUrl: './users.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [CommonModule, DataTable, Paginator, SearchBar, Modal, ZardButtonComponent, UserForm],
})
export class UsersPage {
  rows = signal<User[]>([]);
  total = signal(0);
  loading = signal(false);
  roleMap = new Map<string, string>();

  page = signal(1);
  perPage = signal(10);
  search = signal('');
  sort = signal<SortState>({ key: 'nom', dir: 'asc' });

  modalOpen = signal(false);
  modalTitle = signal('Nouvel utilisateur');
  editingItem = signal<User | null>(null);

  @ViewChild(UserForm) formComp?: UserForm;

  cols: TableColumn<User>[] = [
    { key: 'nom', label: 'Nom', sortable: true },
    { key: 'prenom', label: 'Prénom', sortable: true },
    { key: 'identifiant', label: 'Identifiant', sortable: true },
    { key: 'matriculeAgent', label: 'Matricule', sortable: true },
    {
      key: 'role.name',
      label: 'Rôle',
      sortable: true,
      cell: (u) => this.roleMap.get(u.roleId) ?? u.role?.name ?? '—',
    },
    { key: 'statut', label: 'Statut', sortable: true },
    {
      key: 'derniereConnexion',
      label: 'Dernière connexion',
      cell: (u) =>
        u.derniereConnexion ? new Date(u.derniereConnexion).toLocaleDateString('fr-FR') : '—',
    },
    {
      key: 'restrictionConnexion',
      label: 'Restr. Conn.',
      cell: (u) => String(u.restrictionConnexion),
    },
    {
      key: 'restrictionAutomatique',
      label: 'Restr. Auto',
      cell: (u) => String(u.restrictionAutomatique),
    },
    { key: 'nombreIpAutorise', label: 'IP Autorisé' },
    { key: 'nombreIpAutoAutorise', label: 'IP Auto' },
  ];

  constructor(private api: UserService, private roleService: RoleService) {
    this.roleService
      .list({ page: 1, perPage: 100, search: '', sortKey: 'name', sortDir: 'asc' } as any)
      .subscribe((res) => (res.content as Role[]).forEach((r) => this.roleMap.set(r.id, r.name)));
    effect(() => {
      const params = {
        page: this.page(),
        size: this.perPage(),
        search: this.search(),
        sortKey: this.sort().key,
        sortDir: this.sort().dir as SortDir,
      };
      untracked(() => this.fetch(params));
    });
  }

  private fetch(params: {
    page: number;
    size: number;
    search: string;
    sortKey: string;
    sortDir: SortDir;
  }) {
    this.loading.set(true);
    this.api.list(params).subscribe({
      next: (res) => {
        this.rows.set(res.content);
        this.total.set(res.pageable.total);
        this.loading.set(false);
      },
      error: () => {
        this.rows.set([]);
        this.total.set(0);
        this.loading.set(false);
      },
    });
  }

  onSearch(q: string) {
    this.search.set(q);
    this.page.set(1);
  }

  openCreate() {
    this.modalTitle.set('Nouvel utilisateur');
    this.editingItem.set(null);
    queueMicrotask(() => this.modalOpen.set(true));
  }

  openEdit(row: User) {
    this.modalTitle.set("Modifier l'utilisateur");
    this.editingItem.set(row);
    queueMicrotask(() => this.modalOpen.set(true));
  }

  closeModal() {
    this.modalOpen.set(false);
  }

  submitChildForm() {
    this.formComp?.onSubmit();
  }

  onFormSave(payload: Partial<User>) {
    const current = this.editingItem();
    const req$ = current?.id
      ? this.api.update(current.id, payload)
      : this.api.create(payload as Omit<User, 'id'>);
    req$.subscribe({
      next: (user) => {
        this.closeModal();
        toast.success(
          current?.id
            ? `L'utilisateur « ${user?.nom ?? ''} ${
                user?.prenom ?? ''
              } » a été mis à jour avec succès`
            : `L'utilisateur « ${user?.nom ?? ''} ${user?.prenom ?? ''} » a été créé avec succès`
        );
        this.fetch({
          page: this.page(),
          size: this.perPage(),
          search: this.search(),
          sortKey: this.sort().key,
          sortDir: this.sort().dir as SortDir,
        });
      },
      error: () => {
        toast.error(
          current?.id
            ? "Erreur lors de la mise à jour de l'utilisateur"
            : "Erreur lors de la création de l'utilisateur",
          { duration: 5000 }
        );
      },
    });
  }

  remove(row: User) {
    if (!confirm(`Supprimer l\'utilisateur « ${row.nom} ${row.prenom} » ?`)) return;
    this.api.delete(row.id).subscribe({
      next: (ok) => {
        if (ok) {
          toast.success(`L'utilisateur « ${row.nom} ${row.prenom} » a été supprimé avec succès`);
          this.fetch({
            page: this.page(),
            size: this.perPage(),
            search: this.search(),
            sortKey: this.sort().key,
            sortDir: this.sort().dir as SortDir,
          });
        } else {
          toast.error("Erreur lors de la suppression de l'utilisateur", { duration: 5000 });
        }
      },
      error: () => {
        toast.error("Erreur lors de la suppression de l'utilisateur", { duration: 5000 });
      },
    });
  }
}
