import { AsyncPipe, NgClass } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import {
  ChangeDetectionStrategy,
  Component,
  inject,
  signal,
} from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router, RouterLink } from '@angular/router';
import { TuiButton } from '@taiga-ui/core/components/button';
import { TuiLink } from '@taiga-ui/core/components/link';
import { TuiLoader } from '@taiga-ui/core/components/loader';
import { TuiTitle } from '@taiga-ui/core/components/title';
import { TuiInput } from '@taiga-ui/core/components/input';
import { TuiChip } from '@taiga-ui/kit/components/chip';
import { TuiPagination } from '@taiga-ui/kit/components/pagination';
import { catchError, map, of, startWith, switchMap } from 'rxjs';

import { UserErrorNotifyService } from '../../../core/notifications/user-error-notify.service';
import { SessionStatusChipClassesPipe } from '../../../core/sessions/session-status-chip-classes.pipe';
import { SessionStatusPipe } from '../../../core/sessions/session-status.pipe';
import { SessionsApiService } from '../../../core/services/sessions-api.service';
import { DEFAULT_PAGE_LIMIT } from '../../../core/config/app.tokens';
import { formatTimestamp } from '../../../shared/utils/date-time.util';

@Component({
  selector: 'app-sessions-list',
  imports: [
    AsyncPipe,
    NgClass,
    ReactiveFormsModule,
    RouterLink,
    TuiButton,
    TuiChip,
    ...TuiInput,
    TuiLink,
    TuiLoader,
    TuiPagination,
    TuiTitle,
    SessionStatusChipClassesPipe,
    SessionStatusPipe,
  ],
  templateUrl: './sessions-list.html',
  styleUrl: './sessions-list.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SessionsListComponent {
  private readonly api = inject(SessionsApiService);
  private readonly router = inject(Router);
  private readonly userErrors = inject(UserErrorNotifyService);

  protected readonly limit = inject(DEFAULT_PAGE_LIMIT);
  protected readonly pageIndex = signal(0);

  protected readonly titleControl = new FormControl('', {
    nonNullable: true,
    validators: [Validators.required, Validators.minLength(1)],
  });

  protected readonly creating = signal(false);

  protected readonly listState$ = toObservable(this.pageIndex).pipe(
    switchMap((page) =>
      this.api.listSessions(this.limit, page * this.limit).pipe(
        map((data) => ({ status: 'ok' as const, data })),
        catchError((e: HttpErrorResponse) => {
          this.userErrors.notifyError(e, 'Список сессий');
          return of({ status: 'error' as const });
        }),
        startWith({ status: 'loading' as const }),
      ),
    ),
  );

  protected onPageIndexChange(index: number): void {
    this.pageIndex.set(index);
  }

  protected pageCount(total: number): number {
    return Math.max(1, Math.ceil(total / this.limit));
  }

  protected formatDate(value: string | null | undefined): string {
    return formatTimestamp(value);
  }

  protected createSession(): void {
    if (this.titleControl.invalid || this.creating()) {
      this.titleControl.markAsTouched();
      return;
    }
    const title = this.titleControl.value.trim();
    this.creating.set(true);
    this.api.createSession({ title }).subscribe({
      next: (res) => {
        this.creating.set(false);
        void this.router.navigate(['/sessions', res.id]);
      },
      error: (e: HttpErrorResponse) => {
        this.creating.set(false);
        this.userErrors.notifyError(e, 'Создание сессии');
      },
    });
  }
}
