import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Resolve,
  Router,
  RouterStateSnapshot,
} from '@angular/router';
import { MemberService } from 'app/modules/polyglot/member/services/member.service';
import {
  ListMembersRequest,
  ListMembersResponse,
} from 'app/modules/protobuf/c2se/backend/member_pb';
import { Pagination } from 'app/modules/protobuf/protobuf/pagination/pagination_pb';
import { catchError, Observable, throwError } from 'rxjs';

import { Partner } from '../models/partner';
import { PartnerPagination } from '../models/partner-pagination';
import { PartnerService } from '../services/partner.service';

@Injectable({
  providedIn: 'root',
})
export class PartnerResolver implements Resolve<any> {
  /**
   * Constructor
   */
  constructor(
    private _partnerServiceService: PartnerService,
    private _router: Router
  ) {}

  // -----------------------------------------------------------------------------------------------------
  // @ Public methods
  // -----------------------------------------------------------------------------------------------------

  /**
   * Resolver
   *
   * @param route
   * @param state
   */
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<Partner | undefined> {
    return this._partnerServiceService
      .getPartnerById(route.paramMap.get('id'))
      .pipe(
        // Error here means the requested product is not available
        catchError((error) => {
          // Log the error
          console.error(error);

          // Get the parent url
          const parentUrl = state.url.split('/').slice(0, -1).join('/');

          // Navigate to there
          this._router.navigateByUrl(parentUrl);

          // Throw an error
          return throwError(error);
        })
      );
  }
}

@Injectable({
  providedIn: 'root',
})
export class PartnersResolver implements Resolve<any> {
  /**
   * Constructor
   */
  constructor(private _partnerService: PartnerService) {}

  // -----------------------------------------------------------------------------------------------------
  // @ Public methods
  // -----------------------------------------------------------------------------------------------------

  /**
   * Resolver
   *
   * @param route
   * @param state
   */
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<{
    pagination: PartnerPagination;
    partners: Partner[];
  }> {
    return this._partnerService.getPartners();
  }
}

@Injectable({
  providedIn: 'root',
})
export class PartnerListResolver implements Resolve<any> {
  /**
   * Constructor
   */
  constructor(private __memberService: MemberService) {}

  // -----------------------------------------------------------------------------------------------------
  // @ Public methods
  // -----------------------------------------------------------------------------------------------------

  /**
   * Resolver
   *
   * @param route
   * @param state
   */
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<ListMembersResponse.Result>
    | Promise<ListMembersResponse.Result>
    | ListMembersResponse.Result {
    let req = new ListMembersRequest();

    req.setMemberClassId('4b014ef5-3bab-4413-aaf9-b0040a70ec77');

    return this.__memberService.listMembers(req);
  }
}
