import {Injectable} from '@angular/core';
import {SCIdCard, SCThingOriginType, SCThingType, SCUserConfiguration} from '@openstapps/core';
import {from, Observable, of} from 'rxjs';
import {AuthHelperService} from '../auth/auth-helper.service';
import {mergeMap, filter, map, startWith} from 'rxjs/operators';
import {ConfigProvider} from '../config/config.provider';
import {HttpClient} from '@angular/common/http';

@Injectable({providedIn: 'root'})
export class IdCardsProvider {
  constructor(
    private authHelper: AuthHelperService,
    private config: ConfigProvider,
    private httpClient: HttpClient,
  ) {}

  getIdCards(): Observable<SCIdCard[]> {
    const feature = this.config.config.app.features.extern?.['idCards'];
    const auth = this.authHelper.getProvider(feature?.authProvider ?? 'default');

    return auth.isAuthenticated$.pipe(
      mergeMap(isAuthenticated =>
        isAuthenticated
          ? feature
            ? from(auth.getValidToken()).pipe(
                mergeMap(token => this.fetchIdCards(feature.url, token.accessToken)),
              )
            : auth.user$.pipe(
                filter(user => user !== undefined),
                map(userInfo => this.authHelper.getUserFromUserInfo(userInfo as object)),
                mergeMap(user => this.fetchFallbackIdCards(user)),
                startWith([]),
              )
          : // TODO: find a better solution here (async pipe stuff...)
            of([]),
      ),
    );
  }

  private fetchIdCards(url: string, token: string): Observable<SCIdCard[]> {
    return this.httpClient.get<SCIdCard[]>(url, {
      headers: {
        Authorization: `Bearer ${token}`,
      },
      responseType: 'json',
    });
  }

  private fetchFallbackIdCards(user: SCUserConfiguration): Observable<SCIdCard[]> {
    return this.httpClient.get('/assets/examples/student-id.sample.svg', {responseType: 'text'}).pipe(
      map(svg => {
        let result = svg;
        for (const key in user) {
          result = result.replaceAll(`{{${key}}}`, (user as unknown as Record<string, string>)[key]);
        }
        return `data:image/svg+xml;utf8,${encodeURIComponent(result)}`;
      }),
      map(image => [
        {
          name: 'Student ID',
          image,
          type: SCThingType.IdCard,
          uid: '1234',
          origin: {
            name: 'Sample Origin',
            type: SCThingOriginType.Remote,
            indexed: new Date().toISOString(),
          },
        },
      ]),
    );
  }
}
