import { CommonModule } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  ViewChild,
  effect,
  signal,
  untracked,
} from '@angular/core';
import { DataTable, SortState, TableColumn } from '@shared/components/data-table/data-table';
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 { Permission, Role } from 'src/app/core/interfaces/role';
import { RoleService } from 'src/app/core/services/role';
import { SortDir } from '@shared/paging/paging';
import { RoleForm } from '@shared/forms/role-form/role-form';
import { PermissionForm } from '@shared/forms/permission-form/permission-form';
import { toast } from 'ngx-sonner';

@Component({
  standalone: true,
  selector: 'app-roles',
  templateUrl: './roles.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    CommonModule,
    DataTable,
    SearchBar,
    Modal,
    ZardButtonComponent,
    RoleForm,
    PermissionForm,
  ],
})
export class RolesPage {
  rows = signal<Role[]>([]);
  total = signal(0);
  loading = signal(false);
  permissions = signal<Permission[]>([]);
  page = signal(1);
  size = signal(10);
  search = signal('');
  sort = signal<SortState>({ key: 'name', dir: 'asc' });

  modalOpen = signal(false);
  modalTitle = signal('Nouveau rôle');
  editingItem = signal<Role | null>(null);

  permissionModalOpen = signal(false);
  permissionModalTitle = signal('Nouvelle permission');
  editingPermission = signal<Permission | null>(null);

  @ViewChild(RoleForm) formComp?: RoleForm;
  @ViewChild(PermissionForm) permFormComp?: PermissionForm;

  cols: TableColumn<Role>[] = [
    { key: 'name', label: 'Rôle', sortable: true },
    { key: 'description', label: 'Description', sortable: true },
    { key: 'permissions', label: 'Permissions', cell: (r) => r.permissions.length },
  ];

  constructor(public api: RoleService) {
    this.api.allPermissions().subscribe((list) => this.permissions.set(list));
    effect(() => {
      const params = {
        page: this.page(),
        size: this.size(),
        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('Nouveau rôle');
    this.editingItem.set(null);
    queueMicrotask(() => this.modalOpen.set(true));
  }
  openEdit(row: Role) {
    this.modalTitle.set('Modifier le rôle');
    this.editingItem.set(row);
    queueMicrotask(() => this.modalOpen.set(true));
  }
  closeModal() {
    this.modalOpen.set(false);
  }
  submitChildForm() {
    this.formComp?.onSubmit();
  }

  submitPermissionForm() {
    this.permFormComp?.onSubmit();
  }

  onFormSave(payload: Partial<Role>) {
    const current = this.editingItem();
    const req$ = current?.id
      ? this.api.update(current.id, payload)
      : this.api.create(payload as Omit<Role, 'id'>);
    req$.subscribe({
      next: (role) => {
        this.closeModal();
        toast.success(
          current?.id
            ? `Le rôle « ${role?.name ?? ''} » a été mis à jour avec succès`
            : `Le rôle « ${role?.name ?? ''} » a été créé avec succès`
        );
        this.fetch({
          page: this.page(),
          size: this.size(),
          search: this.search(),
          sortKey: this.sort().key,
          sortDir: this.sort().dir as SortDir,
        });
      },
      error: () => {
        toast.error(
          current?.id
            ? 'Erreur lors de la mise à jour du rôle'
            : 'Erreur lors de la création du rôle',
          { duration: 5000 }
        );
      },
    });
  }

  remove(row: Role) {
    if (!confirm(`Supprimer le rôle « ${row.name} » ?`)) return;
    this.api.delete(row.id).subscribe((result) => {
      if (result.success) {
        toast.success(`Le rôle « ${row.name} » a été supprimé avec succès`);
        this.fetch({
          page: this.page(),
          size: this.size(),
          search: this.search(),
          sortKey: this.sort().key,
          sortDir: this.sort().dir as SortDir,
        });
      } else {
        toast.error(result.error || 'Erreur lors de la suppression du rôle', {
          duration: 5000,
        });
      }
    });
  }

  // ------- Permissions CRUD -------

  openCreatePermission() {
    this.permissionModalTitle.set('Nouvelle permission');
    this.editingPermission.set(null);
    this.permissionModalOpen.set(true);
  }

  openEditPermission(p: Permission) {
    this.permissionModalTitle.set('Modifier la permission');
    this.editingPermission.set(p);
    this.permissionModalOpen.set(true);
  }

  closePermissionModal() {
    this.permissionModalOpen.set(false);
    this.editingPermission.set(null);
  }

  onPermissionFormSave(payload: Permission) {
    const current = this.editingPermission();
    const isEdit = !!current?.id;
    const req$ = isEdit
      ? this.api.updatePermission(current.id, {
          name: payload.name,
          description: payload.description,
        })
      : this.api.createPermission({ name: payload.name, description: payload.description });

    req$.subscribe({
      next: (perm) => {
        this.closePermissionModal();
        const permName = perm?.name || payload.name;
        toast.success(
          isEdit
            ? `La permission « ${permName} » a été mise à jour avec succès`
            : `La permission « ${permName} » a été créée avec succès`
        );
        this.api.allPermissions().subscribe((list) => this.permissions.set(list));
      },
      error: (err) => {
        const permName = payload.name;
        toast.error(
          isEdit
            ? `Erreur lors de la mise à jour de la permission « ${permName} »`
            : `Erreur lors de la création de la permission « ${permName} »`,
          { duration: 5000 }
        );
      },
    });
  }

  removePermission(p: Permission) {
    if (!confirm(`Supprimer la permission « ${p.name} » ?`)) return;
    this.api.deletePermission(p.id).subscribe((result) => {
      if (result.success) {
        toast.success(`La permission « ${p.name} » a été supprimée avec succès`);
        this.api.allPermissions().subscribe((list) => this.permissions.set(list));
      } else {
        toast.error(result.error || 'Erreur lors de la suppression de la permission', {
          duration: 5000,
        });
      }
    });
  }
}
