/*
 * Copyright (C) 2022 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {Component, OnInit} from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import {SCCatalog, SCSemester} from '@openstapps/core';
import moment from 'moment';
import {CatalogProvider} from './catalog.provider';
import {NGXLogger} from 'ngx-logger';
import {Location} from '@angular/common';
import {DataRoutingService} from '../data/data-routing.service';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-catalog',
  templateUrl: './catalog.component.html',
  styleUrls: ['./catalog.component.scss'],
})
export class CatalogComponent implements OnInit {
  /**
   * SCSemester to show
   */
  activeSemester?: SCSemester;

  /**
   * UID of the selected SCSemester
   */
  selectedSemesterUID = '';

  /**
   * Available SCSemesters
   */
  availableSemesters: SCSemester[] = [];

  /**
   * Catalogs (SCCatalog) to show
   */
  catalogs: SCCatalog[] | undefined;

  /**
   * Supercatalog (SCCatalog) to refer to
   */
  superCatalog: SCCatalog;

  constructor(
    private readonly route: ActivatedRoute,
    private readonly catalogProvider: CatalogProvider,
    private readonly dataRoutingService: DataRoutingService,
    private readonly logger: NGXLogger,
    protected router: Router,
    public location: Location,
  ) {
    this.dataRoutingService
      .itemSelectListener()
      .pipe(takeUntilDestroyed())
      .subscribe(item => {
        void this.router.navigate(['data-detail', item.uid], {state: {item}});
      });
  }

  ngOnInit() {
    this.selectedSemesterUID = this.route.snapshot.paramMap.get('uid') ?? '';
    void this.fetchCatalog();
  }

  async fetchCatalog() {
    try {
      if (this.availableSemesters.length === 0) {
        await this.fetchSemesters();
      }

      const response = await this.catalogProvider.getCatalogsWith(
        0,
        this.superCatalog,
        this.activeSemester?.uid,
      );
      this.catalogs = (response.data as SCCatalog[]).sort((a, b) => {
        return new Intl.Collator('en', {
          numeric: true,
          sensitivity: 'accent',
        }).compare(a.name, b.name);
      });
    } catch (error) {
      this.logger.error((error as Error).message);
      return;
    }
  }

  async fetchSemesters(): Promise<void> {
    const today = moment().startOf('day').toISOString();
    const semesters = await this.catalogProvider.getRelevantSemesters();
    const currentSemester = semesters.find(
      semester => semester.startDate <= today && semester.endDate > today,
    );
    const currentSemesterIndex = semesters.findIndex(semester => semester.uid === currentSemester?.uid);
    this.availableSemesters = semesters
      .slice(Math.max(0, currentSemesterIndex - 1), Math.min(currentSemesterIndex + 2, semesters.length))
      .reverse();
    if (this.activeSemester !== undefined) {
      return;
    }

    this.activeSemester = this.availableSemesters[0];
    this.activeSemester =
      this.selectedSemesterUID === ''
        ? currentSemester
        : this.availableSemesters.find(semester => semester.uid === this.selectedSemesterUID);
    if (this.activeSemester && this.selectedSemesterUID === '') {
      this.selectedSemesterUID = this.activeSemester.uid;
    }
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  segmentChanged(event: any) {
    if (this.activeSemester && this.activeSemester.uid !== (event.detail.value as string)) {
      this.updateLocation(event.detail.value as string);
    }

    this.activeSemester = this.availableSemesters.find(
      semester => semester.uid === (event.detail.value as string),
    );
    delete this.catalogs;
    void this.fetchCatalog();
  }

  updateLocation(semesterUID: string) {
    const url = this.router.createUrlTree(['/catalog/', semesterUID]).toString();
    this.location.go(url);
  }

  /**
   * Emit event that a catalog item was selected
   */
  notifySelect(catalog: SCCatalog) {
    this.dataRoutingService.emitChildEvent(catalog);
  }
}
