import { Component, HostListener, Inject, ElementRef, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';
import { RouterLink, Router, NavigationEnd } from '@angular/router';
import { CommonModule, isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { filter } from 'rxjs/operators';
import { AuthService } from '../../services/auth.service';
import { NotificationsService, NotificationDto } from '../../services/notifications.service';
import { UsersService, CreateUserPayload, ApiFieldError } from '../../services/users.service';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators, AbstractControl, ValidationErrors, FormsModule } from '@angular/forms';
import { HttpErrorResponse } from '@angular/common/http';
import { CustomSelectComponent } from '../custom-select/custom-select';
import { Subscription } from 'rxjs';
import { environment } from '../../../environments/environment';
import { confirmActionModal, confirmDeletionWithTyping, showDeletionWarning } from '../../utils/destructive-confirmation';

@Component({
  selector: 'app-header',
  standalone: true,
  imports: [RouterLink, CommonModule, ReactiveFormsModule, FormsModule, CustomSelectComponent],
  templateUrl: './header.html',
  styleUrls: ['./header.scss'],
})
export class Header implements AfterViewInit, OnDestroy {
  isScrolled = false;
  private headerResizeObserver?: ResizeObserver;
  private headerTransitionEndCleanup?: (() => void) | null = null;

  menuOpen = false;
  optionsOpen = false;
  notificationsOpen = false;
  createUserOpen = false;
  manageUsersOpen = false;
  isLoggedHeader = false;
  isHome = false;
  isSysAdmin = false;
  canViewAll = false;
  clientTenantDisplayName = '';
  private clientTenantNameTenantId: string | null = null;
  private readonly baseApi: string;
  notifications: NotificationDto[] = [];
  notificationsLoading = false;
  notificationsError = false;
  notificationsView: 'pendentes' | 'lidas' = 'pendentes';
  notificationsBulkReadLoading = false;
  notificationsBulkUnreadLoading = false;
  private notificationsLoaded = false;
  private pendingToastCheck = false;
  private lastNotificationsLoadAt = 0;
  private readonly notificationsRefreshMs = 60_000;
  readonly notificationsPreviewLimit = 40;
  @ViewChild('notifToast') notifToast?: ElementRef;
  private readonly subs = new Subscription();

  createUserForm: FormGroup;
  createUserSubmitting = false;
  createUserErrors: ApiFieldError[] = [];
  createUserForbidden = false;
  createUserSuccess = '';
  readonly permissionOptions = [
    { value: 'sysadmin', label: 'SysAdmin' },
    { value: 'gestor', label: 'Gestor' },
    { value: 'cliente', label: 'Cliente' },
  ];

  manageUsersLoading = false;
  manageUsersErrors: ApiFieldError[] = [];
  manageUsersSuccess = '';
  private manageUsersFeedbackTimer: ReturnType<typeof setTimeout> | null = null;
  manageMode: 'users' | 'clients' = 'users';
  manageUsers: any[] = [];
  manageSearch = '';
  managePage = 1;
  managePageSize = 10;
  manageTotal = 0;

  editUserForm: FormGroup;
  editUserSubmitting = false;
  editUserErrors: ApiFieldError[] = [];
  editUserSuccess = '';
  editUserTarget: any | null = null;

  private readonly loggedPrefixes = [
    '/geral',
    '/mureg',
    '/faturamento',
    '/dadosusuarios',
    '/vigencia',
    '/trocanumero',
    '/dashboard',
    '/notificacoes',
    '/chips-controle-recebidos',
    '/resumo',
    '/parcelamentos',
    '/historico',
    '/perfil',
    '/system',
  ];

  constructor(
    private router: Router,
    private authService: AuthService,
    private notificationsService: NotificationsService,
    private usersService: UsersService,
    private http: HttpClient,
    private fb: FormBuilder,
    private hostElement: ElementRef<HTMLElement>,
    @Inject(PLATFORM_ID) private platformId: object
  ) {
    const raw = (environment.apiUrl || '').replace(/\/+$/, '');
    this.baseApi = raw.toLowerCase().endsWith('/api') ? raw : `${raw}/api`;

    this.createUserForm = this.fb.group(
      {
        nome: ['', [Validators.required, Validators.minLength(2)]],
        email: ['', [Validators.required, Validators.email]],
        senha: ['', [Validators.required, Validators.minLength(6)]],
        confirmarSenha: ['', [Validators.required, Validators.minLength(6)]],
        permissao: ['', [Validators.required]],
      },
      { validators: this.passwordsMatchValidator }
    );

    this.editUserForm = this.fb.group({
      nome: [''],
      email: [''],
      senha: [''],
      confirmarSenha: [''],
      permissao: [''],
      ativo: [true],
    });

    this.syncHeaderState(this.router.url);
    this.syncPermissions();

    this.router.events
      .pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd))
      .subscribe((event) => {
        const rawUrl = event.urlAfterRedirects || event.url;
        this.syncHeaderState(rawUrl);
        this.syncPermissions();
        this.menuOpen = false;
        this.optionsOpen = false;
        this.notificationsOpen = false;
        if (this.isLoggedHeader) {
          this.ensureNotificationsLoaded();
        }
      });
    if (this.isLoggedHeader) {
      this.ensureNotificationsLoaded();
    }

    this.subs.add(
      this.notificationsService.events$.subscribe((ev) => {
        if (ev.type === 'read') {
          const byId = new Set(ev.ids);
          this.notifications.forEach((n) => {
            if (byId.has(n.id)) {
              n.lida = true;
              n.lidaEm = ev.readAtIso;
            }
          });
          return;
        }
        if (ev.type === 'unread') {
          const byId = new Set(ev.ids);
          this.notifications.forEach((n) => {
            if (byId.has(n.id)) {
              n.lida = false;
              n.lidaEm = null;
            }
          });
          return;
        }
        if (ev.type === 'readAll') {
          this.notifications.forEach((n) => {
            if (!n.lida) {
              n.lida = true;
              n.lidaEm = ev.readAtIso;
            }
          });
          return;
        }
        if (ev.type === 'unreadAll') {
          this.notifications.forEach((n) => {
            if (n.lida) {
              n.lida = false;
              n.lidaEm = null;
            }
          });
          return;
        }
        if (ev.type === 'reload') {
          // Para mudanças de escopo desconhecido, recarrega em background.
          if (this.isLoggedHeader) setTimeout(() => this.loadNotifications(false), 0);
        }
      })
    );
  }

  private syncHeaderState(rawUrl: string) {
    let url = (rawUrl || '').split('?')[0].split('#')[0];
    if (url && !url.startsWith('/')) url = `/${url}`;
    url = url.replace(/\/+$/, '');

    this.isHome = (url === '/' || url === '');

    this.isLoggedHeader = this.loggedPrefixes.some((p) =>
      url === p || url.startsWith(p + '/')
    );
  }

  private syncPermissions() {
    if (!isPlatformBrowser(this.platformId)) {
      this.isSysAdmin = false;
      this.canViewAll = false;
      this.clientTenantDisplayName = '';
      this.clientTenantNameTenantId = null;
      return;
    }
    const isSysAdmin = this.authService.hasRole('sysadmin');
    const isGestor = this.authService.hasRole('gestor');
    this.isSysAdmin = isSysAdmin;
    this.canViewAll = isSysAdmin || isGestor;

    if (!this.isClientHeader) {
      this.clientTenantDisplayName = '';
      this.clientTenantNameTenantId = null;
      return;
    }

    this.ensureClientTenantName();
  }

  toggleMenu() {
    this.menuOpen = !this.menuOpen;
  }

  closeMenu() {
    this.menuOpen = false;
  }

  toggleOptions() {
    this.optionsOpen = !this.optionsOpen;
    if (this.optionsOpen) this.notificationsOpen = false;
  }

  closeOptions() {
    this.optionsOpen = false;
  }

  goToProfile() {
    this.closeOptions();
    this.router.navigate(['/perfil']);
  }

  goToSystemProvisionUser() {
    if (!this.isSysAdmin) return;
    this.closeOptions();
    this.router.navigate(['/system/fornecer-usuario']);
  }

  openCreateUserModal() {
    if (!this.isSysAdmin) return;
    this.createUserOpen = true;
    this.closeOptions();
    this.resetCreateUserState();
  }

  closeCreateUserModal() {
    this.createUserOpen = false;
    this.resetCreateUserState();
  }

  openManageUsersModal() {
    if (!this.isSysAdmin) return;
    this.manageMode = 'users';
    this.manageUsersOpen = true;
    this.closeOptions();
    this.resetManageUsersState();
    this.fetchManageUsers(1);
  }

  openManageClientCredentialsModal() {
    if (!this.isSysAdmin) return;
    this.manageMode = 'clients';
    this.manageUsersOpen = true;
    this.closeOptions();
    this.resetManageUsersState();
    this.fetchManageUsers(1);
  }

  closeManageUsersModal() {
    this.manageUsersOpen = false;
    this.resetManageUsersState();
    this.manageMode = 'users';
  }

  toggleNotifications() {
    this.notificationsOpen = !this.notificationsOpen;
    if (this.notificationsOpen) {
      this.notificationsView = 'pendentes';
      this.optionsOpen = false;
      if (!this.notificationsLoaded) {
        this.loadNotifications(false);
        return;
      }

      if (Date.now() - this.lastNotificationsLoadAt > this.notificationsRefreshMs) {
        // Atualiza em background para não bloquear a abertura visual do dropdown.
        setTimeout(() => this.loadNotifications(false), 0);
      }
    }
  }

  closeNotifications() {
    this.notificationsOpen = false;
  }

  markNotificationRead(notification: NotificationDto) {
    if (notification.lida) return;
    this.notificationsService.markAsRead(notification.id).subscribe({
      next: () => {
        notification.lida = true;
        notification.lidaEm = new Date().toISOString();
        // Evita que o toast volte a aparecer para a mesma notificação.
        this.acknowledgeNotification(notification);
      },
    });
  }

  markNotificationUnread(notification: NotificationDto) {
    if (!notification.lida) return;
    this.notificationsService.markAsUnread(notification.id).subscribe({
      next: () => {
        notification.lida = false;
        notification.lidaEm = null;
      }
    });
  }

  setNotificationsView(view: 'pendentes' | 'lidas') {
    this.notificationsView = view;
  }

  markAllNotificationsRead() {
    if (this.notificationsView === 'lidas') return;
    if (this.unreadCount === 0 || this.notificationsBulkReadLoading) return;
    this.notificationsBulkReadLoading = true;
    this.notificationsService.markAllAsRead().subscribe({
      next: () => {
        // Evento do service já sincroniza o estado; aqui só finalizamos loading e acknowledge.
        const unreadIds = this.notifications.filter(n => !n.lida).map(n => n.id);
        if (unreadIds.length && isPlatformBrowser(this.platformId)) {
          const acknowledged = this.getAcknowledgedIds();
          unreadIds.forEach(id => acknowledged.add(id));
          localStorage.setItem('vigenciaAcknowledgedIds', JSON.stringify(Array.from(acknowledged)));
        }
        this.notificationsBulkReadLoading = false;
      },
      error: () => {
        this.notificationsBulkReadLoading = false;
      }
    });
  }

  markAllNotificationsUnread() {
    if (this.notificationsView !== 'lidas') return;
    if (this.notificationsVisibleCount === 0 || this.notificationsBulkUnreadLoading) return;
    this.notificationsBulkUnreadLoading = true;
    this.notificationsService.markAllAsUnread().subscribe({
      next: () => {
        this.notificationsBulkUnreadLoading = false;
      },
      error: () => {
        this.notificationsBulkUnreadLoading = false;
      }
    });
  }

  onNotificationItemClick(notification: NotificationDto) {
    if (this.notificationsView === 'lidas') {
      this.markNotificationUnread(notification);
      return;
    }
    this.markNotificationRead(notification);
  }

  getVigenciaLabel(notification: NotificationDto): string {
    const tipo = this.getNotificationTipo(notification);
    if (tipo === 'Vencido') return 'Venceu em';
    if (tipo === 'AVencer') return 'Vence em';
    return 'Atualizado em';
  }

  getVigenciaDate(notification: NotificationDto): string {
    const raw =
      notification.dtTerminoFidelizacao ??
      notification.referenciaData ??
      notification.data;
    if (!raw) return '-';
    const parsed = this.parseDateOnly(raw);
    if (!parsed) return '-';
    return parsed.toLocaleDateString('pt-BR');
  }

  getNotificationTipo(notification: NotificationDto): string {
    if (notification.tipo === 'RenovacaoAutomatica') {
      return 'RenovacaoAutomatica';
    }

    const reference = notification.dtTerminoFidelizacao ?? notification.referenciaData;
    const parsed = this.parseDateOnly(reference);
    if (!parsed) return notification.tipo;

    const today = this.startOfDay(new Date());
    return parsed < today ? 'Vencido' : 'AVencer';
  }

  getNotificationDaysToExpire(notification: NotificationDto): number | null {
    const reference = notification.dtTerminoFidelizacao ?? notification.referenciaData;
    const parsed = this.parseDateOnly(reference);
    if (!parsed) {
      return notification.diasParaVencer ?? null;
    }

    const today = this.startOfDay(new Date());
    const msPerDay = 24 * 60 * 60 * 1000;
    return Math.round((parsed.getTime() - today.getTime()) / msPerDay);
  }

  abbreviateName(value?: string | null): string {
    const name = (value ?? '').trim();
    if (!name) return '-';
    const parts = name.split(/\s+/).filter(Boolean);
    if (parts.length === 1) return parts[0];

    const maxLen = 18;
    const full = parts.join(' ');
    if (full.length <= maxLen) return full;

    if (parts.length >= 3) {
      const candidate = `${parts[0]} ${parts[1]} ${parts[2][0]}.`;
      if (candidate.length <= maxLen) return candidate;
      return `${parts[0]} ${parts[1][0]}.`;
    }

    const two = `${parts[0]} ${parts[1]}`;
    if (two.length <= maxLen) return two;
    return `${parts[0]} ${parts[1][0]}.`;
  }

  get unreadCount() {
    return this.notifications.filter(n => !n.lida).length;
  }

  get isClientHeader(): boolean {
    return this.isLoggedHeader && !this.canViewAll;
  }

  get headerLogoSubtitle(): string {
    return this.isClientHeader ? 'Gestão Empresas' : 'Gestão';
  }

  get headerLogoAriaLabel(): string {
    return `Line ${this.headerLogoSubtitle}`;
  }

  get clientTenantDisplayNameAbbrev(): string {
    return this.abbreviateClientTenantName(this.clientTenantDisplayName);
  }

  get notificationsVisible() {
    return this.notificationsView === 'lidas'
      ? this.notifications.filter(n => n.lida)
      : this.notifications.filter(n => !n.lida);
  }

  get notificationsVisibleCount() {
    return this.notificationsVisible.length;
  }

  get notificationsPreview() {
    return this.notificationsVisible.slice(0, this.notificationsPreviewLimit);
  }

  get hasNotificationsTruncated() {
    return this.notificationsVisibleCount > this.notificationsPreviewLimit;
  }

  trackByNotificationId(_: number, notification: NotificationDto) {
    return notification.id;
  }

  logout() {
    this.authService.logout();
    this.optionsOpen = false;
    this.notificationsOpen = false;
    this.isSysAdmin = false;
    this.canViewAll = false;
    this.router.navigate(['/']);
  }

  @HostListener('window:scroll', [])
  onWindowScroll() {
    if (!isPlatformBrowser(this.platformId)) return;
    this.isScrolled = window.scrollY > 10;
    this.scheduleHeaderOffsetSync();
  }

  @HostListener('window:resize', [])
  onWindowResize() {
    if (!isPlatformBrowser(this.platformId)) return;
    this.scheduleHeaderOffsetSync();
  }

  @HostListener('document:click', [])
  onDocumentClick() {
    this.optionsOpen = false;
    this.notificationsOpen = false;
  }

  @HostListener('document:keydown.escape', [])
  onEsc() {
    if (!isPlatformBrowser(this.platformId)) return;
    this.closeMenu();
    this.closeOptions();
    this.closeNotifications();
    this.closeCreateUserModal();
    this.closeManageUsersModal();
  }

  acknowledgeNotification(notification: NotificationDto) {
    if (!isPlatformBrowser(this.platformId)) return;
    const acknowledged = this.getAcknowledgedIds();
    acknowledged.add(notification.id);
    localStorage.setItem('vigenciaAcknowledgedIds', JSON.stringify(Array.from(acknowledged)));
  }

  acknowledgeCurrentToast() {
    const current = this.toastNotification;
    if (!current) return;
    this.acknowledgeNotification(current);
  }

  ngAfterViewInit() {
    this.setupHeaderOffsetTracking();
    if (this.pendingToastCheck) {
      this.pendingToastCheck = false;
      void this.maybeShowVigenciaToast();
    }
  }

  private ensureNotificationsLoaded() {
    if (this.notificationsLoaded || this.notificationsLoading) return;
    this.loadNotifications(true);
  }

  private loadNotifications(showToast = true) {
    if (!isPlatformBrowser(this.platformId)) return;
    if (this.notificationsLoading) return;
    this.notificationsLoading = true;
    this.notificationsError = false;
    this.notificationsService.list().subscribe({
      next: (data) => {
        this.notifications = data || [];
        this.notificationsLoaded = true;
        this.notificationsLoading = false;
        this.lastNotificationsLoadAt = Date.now();
        if (showToast) {
          void this.maybeShowVigenciaToast();
        }
      },
      error: () => {
        this.notificationsError = true;
        this.notificationsLoading = false;
      },
    });
  }

  private async maybeShowVigenciaToast() {
    if (!isPlatformBrowser(this.platformId)) return;
    if (!this.notifToast) {
      this.pendingToastCheck = true;
      return;
    }

    const pending = this.getPendingVigenciaToast();
    if (!pending) return;

    const bs = await import('bootstrap');
    const toast = bs.Toast.getOrCreateInstance(this.notifToast.nativeElement, { autohide: false });
    toast.show();
  }

  get toastNotification() {
    return this.getPendingVigenciaToast();
  }

  private getPendingVigenciaToast() {
    const acknowledged = this.getAcknowledgedIds();
    return this.notifications.find(
      n =>
        !n.lida &&
        this.getNotificationTipo(n) === 'AVencer' &&
        this.getNotificationDaysToExpire(n) === 5 &&
        !acknowledged.has(n.id)
    );
  }

  ngOnDestroy(): void {
    this.headerResizeObserver?.disconnect();
    this.headerResizeObserver = undefined;
    this.headerTransitionEndCleanup?.();
    this.headerTransitionEndCleanup = null;
    if (this.manageUsersFeedbackTimer) {
      clearTimeout(this.manageUsersFeedbackTimer);
      this.manageUsersFeedbackTimer = null;
    }
    this.subs.unsubscribe();
  }

  private parseDateOnly(raw?: string | null): Date | null {
    if (!raw) return null;
    const datePart = raw.split('T')[0];
    const parts = datePart.split('-');
    if (parts.length === 3) {
      const year = Number(parts[0]);
      const month = Number(parts[1]);
      const day = Number(parts[2]);
      if (Number.isFinite(year) && Number.isFinite(month) && Number.isFinite(day)) {
        return new Date(year, month - 1, day);
      }
    }

    const fallback = new Date(raw);
    if (Number.isNaN(fallback.getTime())) return null;
    return this.startOfDay(fallback);
  }

  private startOfDay(date: Date): Date {
    return new Date(date.getFullYear(), date.getMonth(), date.getDate());
  }

  private getAcknowledgedIds() {
    if (!isPlatformBrowser(this.platformId)) return new Set<string>();
    try {
      const raw = localStorage.getItem('vigenciaAcknowledgedIds');
      const ids = raw ? (JSON.parse(raw) as string[]) : [];
      return new Set(ids);
    } catch {
      return new Set<string>();
    }
  }

  submitCreateUser() {
    if (this.createUserSubmitting) return;
    if (this.createUserForm.invalid) {
      this.createUserForm.markAllAsTouched();
      return;
    }
    if (!this.isSysAdmin) {
      this.createUserForbidden = true;
      return;
    }

    this.createUserSubmitting = true;
    this.setCreateFormDisabled(true);
    this.createUserErrors = [];
    this.createUserForbidden = false;
    this.createUserSuccess = '';

    const payload = this.createUserForm.value as CreateUserPayload;
    this.usersService.create(payload).subscribe({
      next: (created) => {
        this.createUserSubmitting = false;
        this.setCreateFormDisabled(false);
        this.createUserSuccess = `Usuario ${created.nome} criado com sucesso.`;
        this.createUserForm.reset({ permissao: '' });
      },
      error: (err: HttpErrorResponse) => {
        this.createUserSubmitting = false;
        this.setCreateFormDisabled(false);
        if (err.status === 401 || err.status === 403) {
          this.createUserForbidden = true;
          return;
        }
        const apiErrors = err?.error?.errors;
        if (Array.isArray(apiErrors)) {
          this.createUserErrors = apiErrors.map((e: any) => ({
            field: e?.field,
            message: e?.message || 'Erro ao criar usuario.',
          }));
        } else {
          this.createUserErrors = [{ message: 'Erro ao criar usuario.' }];
        }
      },
    });
  }

  fetchManageUsers(goToPage?: number) {
    if (goToPage) this.managePage = goToPage;
    this.manageUsersLoading = true;
    this.manageUsersErrors = [];
    this.manageUsersSuccess = '';

    this.usersService
      .list({
        search: this.manageSearch?.trim() || undefined,
        permissao: this.isManageClientsMode ? 'cliente' : undefined,
        page: this.managePage,
        pageSize: this.managePageSize,
      })
      .subscribe({
        next: (res) => {
          this.manageUsers = res.items || [];
          this.manageTotal = res.total || 0;
          this.manageUsersLoading = false;
        },
        error: () => {
          this.manageUsers = [];
          this.manageTotal = 0;
          this.manageUsersLoading = false;
        },
      });
  }

  onManageSearch() {
    this.managePage = 1;
    this.fetchManageUsers();
  }

  clearManageSearch() {
    this.manageSearch = '';
    this.managePage = 1;
    this.fetchManageUsers();
  }

  manageGoToPage(p: number) {
    this.managePage = p;
    this.fetchManageUsers();
  }

  get manageTotalPages(): number {
    return Math.max(1, Math.ceil((this.manageTotal || 0) / (this.managePageSize || 10)));
  }

  get managePageNumbers(): number[] {
    const total = this.manageTotalPages;
    const current = this.managePage;
    const max = 5;
    let start = Math.max(1, current - 2);
    let end = Math.min(total, start + (max - 1));
    start = Math.max(1, end - (max - 1));
    const pages: number[] = [];
    for (let i = start; i <= end; i++) pages.push(i);
    return pages;
  }

  openEditUser(user: any) {
    this.editUserTarget = null;
    this.editUserErrors = [];
    this.editUserSuccess = '';
    this.editUserSubmitting = false;
    this.setEditFormDisabled(false);
    this.editUserForm.reset({ nome: '', email: '', senha: '', confirmarSenha: '', permissao: '', ativo: true });

    this.usersService.getById(user.id).subscribe({
      next: (full) => {
        this.editUserTarget = full;
        const permissao = this.isManageClientsMode ? 'cliente' : (full.permissao ?? '');
        this.editUserForm.reset({
          nome: full.nome ?? '',
          email: full.email ?? '',
          senha: '',
          confirmarSenha: '',
          permissao,
          ativo: full.ativo ?? true,
        });
        if (this.isManageClientsMode) {
          this.editUserForm.get('permissao')?.disable({ emitEvent: false });
        } else {
          this.editUserForm.get('permissao')?.enable({ emitEvent: false });
        }
      },
      error: () => {
        this.editUserErrors = [{ message: this.isManageClientsMode ? 'Erro ao carregar credencial do cliente.' : 'Erro ao carregar usuário.' }];
      },
    });
  }

  cancelEditUser() {
    this.editUserTarget = null;
    this.editUserErrors = [];
    this.editUserSuccess = '';
    this.editUserSubmitting = false;
    this.setEditFormDisabled(false);
    this.editUserForm.reset({ nome: '', email: '', senha: '', confirmarSenha: '', permissao: '', ativo: true });
  }

  submitEditUser() {
    if (this.editUserSubmitting || !this.editUserTarget) return;

    const payload: any = {};
    const nome = (this.editUserForm.get('nome')?.value || '').toString().trim();
    const email = (this.editUserForm.get('email')?.value || '').toString().trim();
    const permissao = this.isManageClientsMode
      ? 'cliente'
      : (this.editUserForm.get('permissao')?.value || '').toString().trim();
    const ativo = !!this.editUserForm.get('ativo')?.value;

    if (nome && nome !== (this.editUserTarget.nome || '').trim()) payload.nome = nome;
    if (email && email !== (this.editUserTarget.email || '').trim()) payload.email = email;
    if (this.isManageClientsMode) {
      const targetPermissao = String(this.editUserTarget.permissao || '').trim().toLowerCase();
      if (targetPermissao !== 'cliente') {
        payload.permissao = 'cliente';
      }
    } else if (permissao && permissao !== (this.editUserTarget.permissao || '').trim()) {
      payload.permissao = permissao;
    }
    if ((this.editUserTarget.ativo ?? true) !== ativo) payload.ativo = ativo;

    const senha = (this.editUserForm.get('senha')?.value || '').toString();
    const confirmar = (this.editUserForm.get('confirmarSenha')?.value || '').toString();
    if (senha || confirmar) {
      if (!senha || !confirmar) {
        this.editUserErrors = [{ message: 'Para alterar a senha, preencha senha e confirmacao.' }];
        return;
      }
      if (senha.length < 6) {
        this.editUserErrors = [{ message: 'Senha deve ter no minimo 6 caracteres.' }];
        return;
      }
      if (senha !== confirmar) {
        this.editUserErrors = [{ message: 'As senhas nao conferem.' }];
        return;
      }
      payload.senha = senha;
      payload.confirmarSenha = confirmar;
    }

    if (Object.keys(payload).length === 0) {
      this.editUserErrors = [{ message: 'Nenhuma alteracao detectada.' }];
      return;
    }

    this.editUserSubmitting = true;
    this.setEditFormDisabled(true);
    this.editUserErrors = [];
    this.editUserSuccess = '';

    const currentTarget = { ...this.editUserTarget };

    this.usersService.update(this.editUserTarget.id, payload).subscribe({
      next: () => {
        const merged = this.mergeUserUpdate(currentTarget, payload);
        this.editUserSubmitting = false;
        this.setEditFormDisabled(false);
        this.editUserSuccess = this.isManageClientsMode
          ? `Credencial de ${merged.nome} atualizada com sucesso.`
          : `Usuario ${merged.nome} atualizado com sucesso.`;
        this.editUserTarget = merged;
        this.editUserForm.patchValue({
          nome: merged.nome ?? '',
          email: merged.email ?? '',
          permissao: this.isManageClientsMode ? 'cliente' : (merged.permissao ?? ''),
          ativo: merged.ativo ?? true,
          senha: '',
          confirmarSenha: '',
        });
        this.upsertManageUser(merged);
        this.showManageUsersFeedback(
          this.isManageClientsMode
            ? `Credencial de ${merged.nome} atualizada com sucesso.`
            : `Usuario ${merged.nome} atualizado com sucesso.`,
          'success'
        );
      },
      error: (err: HttpErrorResponse) => {
        this.editUserSubmitting = false;
        this.setEditFormDisabled(false);
        const apiErrors = err?.error?.errors;
        if (Array.isArray(apiErrors)) {
          this.editUserErrors = apiErrors.map((e: any) => ({
            field: e?.field,
              message: e?.message || (this.isManageClientsMode ? 'Erro ao atualizar credencial do cliente.' : 'Erro ao atualizar usuario.'),
          }));
        } else {
          this.editUserErrors = [{
            message: err?.error?.message || (this.isManageClientsMode ? 'Erro ao atualizar credencial do cliente.' : 'Erro ao atualizar usuario.')
          }];
        }
        this.showManageUsersFeedback(
          this.editUserErrors[0]?.message || (this.isManageClientsMode ? 'Erro ao atualizar credencial do cliente.' : 'Erro ao atualizar usuario.'),
          'error'
        );
      },
    });
  }

  async confirmToggleUserStatus(user: any) {
    const nextActive = user.ativo === false;
    const actionLabel = nextActive ? 'reativar' : 'inativar';
    const entity = this.isManageClientsMode ? 'Credencial do Cliente' : 'Usuário';
    const entityLower = this.isManageClientsMode ? 'credencial do cliente' : 'usuário';
    const confirmed = await confirmActionModal({
      title: nextActive ? `Reativar ${entity}` : `Inativar ${entity}`,
      message: nextActive
        ? `Deseja reativar ${entityLower} ${user.nome}? O acesso ao sistema será liberado novamente.`
        : `Deseja inativar ${entityLower} ${user.nome}? O acesso ao sistema ficará bloqueado até reativação.`,
      confirmLabel: nextActive ? 'Reativar' : 'Inativar',
      tone: nextActive ? 'neutral' : 'warning',
    });
    if (!confirmed) return;

    this.usersService.update(user.id, { ativo: nextActive }).subscribe({
      next: () => {
        const updated = this.mergeUserUpdate(user, { ativo: nextActive });
        this.upsertManageUser(updated);
        if (this.editUserTarget?.id === user.id) {
          this.editUserTarget = { ...this.editUserTarget, ativo: nextActive };
          this.editUserForm.patchValue({ ativo: nextActive, senha: '', confirmarSenha: '' });
          this.editUserErrors = [];
          this.editUserSuccess = this.isManageClientsMode
            ? `Credencial de ${user.nome} ${nextActive ? 'reativada' : 'inativada'} com sucesso.`
            : `Usuario ${user.nome} ${nextActive ? 'reativado' : 'inativado'} com sucesso.`;
        }
      },
      error: (err: HttpErrorResponse) => {
        const message = err?.error?.message || `Erro ao ${actionLabel} ${this.isManageClientsMode ? 'credencial do cliente' : 'usuario'}.`;
        if (this.editUserTarget?.id === user.id) {
          this.editUserSuccess = '';
          this.editUserErrors = [{ message }];
        }
      },
    });
  }

  async confirmPermanentDeleteUser(user: any) {
    if (user?.ativo !== false) {
      const message = this.isManageClientsMode
        ? 'Inative a credencial antes de excluir permanentemente.'
        : 'Inative a conta antes de excluir permanentemente.';
      if (this.editUserTarget?.id === user?.id) {
        this.editUserSuccess = '';
        this.editUserErrors = [{ message }];
      } else {
        await showDeletionWarning(message, 'Exclusão não permitida');
      }
      return;
    }

    const confirmed = await confirmDeletionWithTyping(
      this.isManageClientsMode ? `a credencial do cliente ${user.nome}` : `o usuário ${user.nome}`
    );
    if (!confirmed) return;

    this.usersService.delete(user.id).subscribe({
      next: () => {
        this.removeManageUser(user.id);
        if (this.editUserTarget?.id === user.id) {
          this.cancelEditUser();
        }
      },
      error: (err: HttpErrorResponse) => {
        const apiErrors = err?.error?.errors;
        const message = Array.isArray(apiErrors)
          ? (apiErrors[0]?.message || (this.isManageClientsMode ? 'Erro ao excluir credencial do cliente.' : 'Erro ao excluir usuario.'))
          : (err?.error?.message || (this.isManageClientsMode ? 'Erro ao excluir credencial do cliente.' : 'Erro ao excluir usuario.'));

        if (this.editUserTarget?.id === user.id) {
          this.editUserSuccess = '';
          this.editUserErrors = [{ message }];
          return;
        }

        void showDeletionWarning(message, 'Falha na exclusão');
      },
    });
  }

  hasFieldError(field: string): boolean {
    return this.getFieldErrors(field).length > 0;
  }

  getFieldErrors(field: string): string[] {
    const key = this.normalizeField(field);
    return this.createUserErrors
      .filter((e) => this.normalizeField(e.field) === key)
      .map((e) => e.message);
  }

  get passwordMismatch(): boolean {
    return !!this.createUserForm.errors?.['passwordsMismatch'];
  }

  private resetCreateUserState() {
    this.createUserErrors = [];
    this.createUserForbidden = false;
    this.createUserSuccess = '';
    this.createUserSubmitting = false;
    this.setCreateFormDisabled(false);
    this.createUserForm.reset({ permissao: '' });
  }

  private resetManageUsersState() {
    if (this.manageUsersFeedbackTimer) {
      clearTimeout(this.manageUsersFeedbackTimer);
      this.manageUsersFeedbackTimer = null;
    }
    this.manageUsersErrors = [];
    this.manageUsersSuccess = '';
    this.manageUsersLoading = false;
    this.manageUsers = [];
    this.manageSearch = '';
    this.managePage = 1;
    this.manageTotal = 0;
    this.cancelEditUser();
  }

  get isManageClientsMode(): boolean {
    return this.manageMode === 'clients';
  }

  get manageModalTitle(): string {
    return this.isManageClientsMode ? 'Credenciais de Clientes' : 'Gestão de Usuários';
  }

  get manageListTitle(): string {
    return this.isManageClientsMode ? 'Credenciais de Cliente' : 'Usuários';
  }

  get manageSearchPlaceholder(): string {
    return this.isManageClientsMode
      ? 'Buscar por cliente, nome ou email...'
      : 'Buscar por nome ou email...';
  }

  get editPermissionOptions() {
    return this.isManageClientsMode
      ? [{ value: 'cliente', label: 'Cliente' }]
      : this.permissionOptions;
  }

  private normalizeField(field?: string | null): string {
    return (field || '').trim().toLowerCase();
  }

  private setCreateFormDisabled(disabled: boolean) {
    if (disabled) this.createUserForm.disable({ emitEvent: false });
    else this.createUserForm.enable({ emitEvent: false });
  }

  private setEditFormDisabled(disabled: boolean) {
    if (disabled) this.editUserForm.disable({ emitEvent: false });
    else {
      this.editUserForm.enable({ emitEvent: false });
      if (this.isManageClientsMode) {
        this.editUserForm.get('permissao')?.disable({ emitEvent: false });
      }
    }
  }

  private upsertManageUser(user: any) {
    this.manageUsers = this.manageUsers.map((item) =>
      item.id === user.id ? { ...item, ...user } : item
    );
  }

  private removeManageUser(userId: string) {
    const prevLength = this.manageUsers.length;
    this.manageUsers = this.manageUsers.filter((item) => item.id !== userId);

    if (this.manageUsers.length !== prevLength && this.manageTotal > 0) {
      this.manageTotal = Math.max(0, this.manageTotal - 1);
    }

    if (!this.manageUsers.length && this.managePage > 1) {
      this.fetchManageUsers(this.managePage - 1);
    }
  }

  private mergeUserUpdate(current: any, payload: any) {
    return {
      ...current,
      nome: payload.nome ?? current.nome,
      email: payload.email ? String(payload.email).trim().toLowerCase() : current.email,
      permissao: payload.permissao ?? current.permissao,
      ativo: payload.ativo ?? current.ativo,
    };
  }

  private showManageUsersFeedback(message: string, type: 'success' | 'error') {
    if (this.manageUsersFeedbackTimer) {
      clearTimeout(this.manageUsersFeedbackTimer);
      this.manageUsersFeedbackTimer = null;
    }

    if (type === 'success') {
      this.manageUsersErrors = [];
      this.manageUsersSuccess = message;
    } else {
      this.manageUsersSuccess = '';
      this.manageUsersErrors = [{ message }];
    }

    this.manageUsersFeedbackTimer = setTimeout(() => {
      this.manageUsersSuccess = '';
      this.manageUsersErrors = [];
      this.manageUsersFeedbackTimer = null;
    }, 3000);
  }

  private passwordsMatchValidator(group: AbstractControl): ValidationErrors | null {
    const senha = group.get('senha')?.value;
    const confirmar = group.get('confirmarSenha')?.value;
    if (!senha || !confirmar) return null;
    return senha === confirmar ? null : { passwordsMismatch: true };
  }

  private setupHeaderOffsetTracking() {
    if (!isPlatformBrowser(this.platformId)) return;

    this.syncHeaderOffsetCssVar();

    const headerEl = this.getHeaderElement();
    if (!headerEl || typeof ResizeObserver === 'undefined') return;

    this.headerResizeObserver?.disconnect();
    this.headerResizeObserver = new ResizeObserver(() => {
      this.syncHeaderOffsetCssVar();
    });
    this.headerResizeObserver.observe(headerEl);

    // Garante sincronismo do offset após a animação de "scrolled" do header.
    this.headerTransitionEndCleanup?.();
    const onTransitionEnd = (ev: TransitionEvent) => {
      if (ev.target !== headerEl) return;
      if (ev.propertyName && ev.propertyName !== 'padding-top' && ev.propertyName !== 'padding-bottom') {
        return;
      }
      this.syncHeaderOffsetCssVar();
    };
    headerEl.addEventListener('transitionend', onTransitionEnd);
    this.headerTransitionEndCleanup = () => headerEl.removeEventListener('transitionend', onTransitionEnd);
  }

  private scheduleHeaderOffsetSync() {
    if (!isPlatformBrowser(this.platformId)) return;
    requestAnimationFrame(() => this.syncHeaderOffsetCssVar());
  }

  private syncHeaderOffsetCssVar() {
    if (!isPlatformBrowser(this.platformId)) return;
    const headerEl = this.getHeaderElement();
    if (!headerEl) return;

    const height = Math.ceil(headerEl.getBoundingClientRect().height || headerEl.offsetHeight || 0);
    if (height > 0) {
      document.documentElement.style.setProperty('--app-header-offset', `${height}px`);
    }
  }

  private getHeaderElement(): HTMLElement | null {
    return this.hostElement.nativeElement.querySelector('.app-header');
  }

  private ensureClientTenantName() {
    const profile = this.authService.currentUserProfile;
    const tenantId = String(profile?.tenantId || '').trim();

    if (!tenantId) {
      this.clientTenantDisplayName = '';
      this.clientTenantNameTenantId = null;
      return;
    }

    if (this.clientTenantNameTenantId === tenantId && this.clientTenantDisplayName) {
      return;
    }

    this.clientTenantNameTenantId = tenantId;
    this.clientTenantDisplayName = '';

    this.http.get<string[]>(`${this.baseApi}/lines/clients`).subscribe({
      next: (clients) => {
        const list = (clients || [])
          .map((x) => String(x ?? '').trim())
          .filter((x) => !!x && x.localeCompare('RESERVA', 'pt-BR', { sensitivity: 'base' }) !== 0);

        this.clientTenantDisplayName = list[0] || this.resolveFallbackClientTenantName();
      },
      error: () => {
        this.clientTenantDisplayName = this.resolveFallbackClientTenantName();
      },
    });
  }

  private resolveFallbackClientTenantName(): string {
    const profileName = String(this.authService.currentUserProfile?.nome || '').trim();
    if (profileName) return profileName;
    return 'Cliente';
  }

  private abbreviateClientTenantName(value: string): string {
    const name = (value || '').trim();
    if (!name) return 'Cliente';

    const maxLen = 30;
    if (name.length <= maxLen) return name;

    const parts = name.split(/\s+/).filter(Boolean);
    if (parts.length === 1) {
      return `${parts[0].slice(0, maxLen - 1)}…`;
    }

    const first = parts[0];
    const last = parts[parts.length - 1];
    let candidate = `${first} ${last}`;

    if (candidate.length <= maxLen) return candidate;

    const shortFirst = `${first.slice(0, Math.max(3, maxLen - (last.length + 3)))}.`;
    candidate = `${shortFirst} ${last}`;
    if (candidate.length <= maxLen) return candidate;

    return `${name.slice(0, maxLen - 1)}…`;
  }
}
