import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HttpResponseBase,
} from '@angular/common/http';
import { Inject, Injectable, Optional } from '@angular/core';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { environment } from '@env/environment';
import { EAEnvironmentService, EAUserService } from '@shared';
import { Observable, of } from 'rxjs';
import { catchError, mergeMap } from 'rxjs/operators';

@Injectable()
export class BusinessInterceptor implements HttpInterceptor {
  constructor(
    private envSrv: EAEnvironmentService,
    private eaUserSrv: EAUserService,
    @Optional()
    @Inject(DA_SERVICE_TOKEN)
    private tokenSrv: ITokenService,
  ) {}
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // 构造新的请求URL
    req = this.constructNewRequestUrl(req);
    // 附加额外的请求头
    req = this.attachAdditionalHeaders(req);
    // 后续操作
    return next.handle(req).pipe(
      mergeMap((ev) => this.handlingBussinessResponseData(ev)),
      catchError((err: HttpErrorResponse) => this.handlingBusinessErrors(err)),
    );
  }

  /**
   * 构造新的请求URL
   */
  private constructNewRequestUrl(req: HttpRequest<any>): HttpRequest<any> {
    let url = req.url;
    if (!url.startsWith('https://') && !url.startsWith('http://')) {
      if (!url.startsWith('assets')) {
        url = environment.api.baseUrl + url;
      }
    }
    return req.clone({ url });
  }

  /**
   * 附加额外的请求头
   */
  private attachAdditionalHeaders(req: HttpRequest<any>): HttpRequest<any> {
    // 附加环境变量
    const header: any = {
      appId: this.envSrv.env.appId,
      tenantId: this.envSrv.env.tenantId,
    };

    // 附加授权声明
    const token = this.tokenSrv.get()?.token;
    if (token) {
      header.Authorization = `Bearer ${token}`;
    }
    return req.clone({ setHeaders: header });
  }

  /**
   * 处理业务数据
   */
  private handlingBussinessResponseData(ev: HttpEvent<any>): Observable<any> {
    if (ev instanceof HttpResponseBase) {
      const body = (ev as HttpResponse<any>).body;
      if (body) {
        switch (body.status) {
          case 505001:
          case 505002:
            this.eaUserSrv.logout();
            break;
          default:
            break;
        }
      }
    }
    if (ev instanceof HttpErrorResponse) {
      return this.handlingBusinessErrors(ev);
    }
    return of(ev);
  }

  /**
   * 处理响应错误
   */
  private handlingBusinessErrors(err: HttpErrorResponse): Observable<any> {
    /** Http响应异常已在默认拦截器处理完成 ，该处不再处理 */

    return of(err);
  }
}
