/* eslint-disable @typescript-eslint/member-ordering */
import {
  Component,
  computed,
  inject,
  OnInit,
  signal
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { Store } from '@ngrx/store';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowLeft } from '@ng-icons/lucide';

import { AppI18nService, APP_TRANSLATE_IMPORTS } from '../../../../core/i18n';
import { ServerBrowserComponent, type ServerDiscoverySection } from '../server-browser/server-browser.component';
import { ServerDirectoryFacade } from '../../application/facades/server-directory.facade';
import { selectSavedRooms } from '../../../../store/rooms/rooms.selectors';
import type { Room } from '../../../../shared-kernel';
import type { ServerInfo } from '../../domain/models/server-directory.model';

/** Number of recently-joined servers surfaced as the "Recently active" section. */
const RECENT_SERVER_LIMIT = 6;

/**
 * Dedicated server-discovery page. Hosts the reusable {@link ServerBrowserComponent}
 * and feeds it featured, trending, and recently-active discovery sections. On mobile the
 * global app-shell servers rail stays visible beside this page.
 */
@Component({
  selector: 'app-find-servers',
  standalone: true,
  imports: [
    CommonModule,
    RouterLink,
    NgIcon,
    ServerBrowserComponent,
    ...APP_TRANSLATE_IMPORTS
  ],
  viewProviders: [provideIcons({ lucideArrowLeft })],
  templateUrl: './find-servers.component.html',
  host: {
    class: 'block h-full min-h-0 min-w-0 w-full overflow-hidden'
  }
})
export class FindServersComponent implements OnInit {
  private store = inject(Store);
  private serverDirectory = inject(ServerDirectoryFacade);
  private readonly i18n = inject(AppI18nService);
  featured = signal<ServerInfo[]>([]);
  trending = signal<ServerInfo[]>([]);
  savedRooms = this.store.selectSignal(selectSavedRooms);

  readonly searchPlaceholder = this.i18n.instant('servers.find.searchPlaceholder');
  readonly emptyStateTitle = this.i18n.instant('servers.find.emptyTitle');
  readonly emptyStateMessage = this.i18n.instant('servers.find.emptyMessage');

  /** Discovery sections shown when the user is not actively searching. */
  discoverySections = computed<ServerDiscoverySection[]>(() => {
    const sections: ServerDiscoverySection[] = [];
    const recent = this.savedRooms()
      .slice(0, RECENT_SERVER_LIMIT)
      .map((room) => this.toServerInfo(room));

    if (recent.length > 0) {
      sections.push({
        id: 'recent',
        title: this.i18n.instant('servers.discovery.recentTitle'),
        subtitle: this.i18n.instant('servers.discovery.recentSubtitle'),
        servers: recent
      });
    }

    if (this.featured().length > 0) {
      sections.push({
        id: 'featured',
        title: this.i18n.instant('servers.discovery.featuredTitle'),
        subtitle: this.i18n.instant('servers.discovery.featuredSubtitle'),
        servers: this.featured()
      });
    }

    if (this.trending().length > 0) {
      sections.push({
        id: 'trending',
        title: this.i18n.instant('servers.discovery.trendingTitle'),
        subtitle: this.i18n.instant('servers.discovery.trendingSubtitle'),
        servers: this.trending()
      });
    }

    return sections;
  });

  /** True when there is nothing to recommend (a brand-new account). */
  isNewUser = computed(() => this.discoverySections().length === 0);

  ngOnInit(): void {
    this.serverDirectory.getFeaturedServers().subscribe((servers) => this.featured.set(servers));
    this.serverDirectory.getTrendingServers().subscribe((servers) => this.trending.set(servers));
  }

  private toServerInfo(room: Room): ServerInfo {
    return {
      id: room.id,
      name: room.name,
      description: room.description,
      hostName: room.hostId || this.i18n.instant('common.labels.unknown'),
      userCount: room.userCount ?? 0,
      maxUsers: room.maxUsers ?? 50,
      icon: room.icon,
      iconUpdatedAt: room.iconUpdatedAt,
      hasPassword: typeof room.hasPassword === 'boolean' ? room.hasPassword : !!room.password,
      isPrivate: room.isPrivate,
      channels: room.channels,
      createdAt: room.createdAt,
      ownerId: room.hostId,
      sourceId: room.sourceId,
      sourceName: room.sourceName,
      sourceUrl: room.sourceUrl
    };
  }
}
