import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { JwtHelperService } from "@auth0/angular-jwt";
import { Buffer } from "buffer";
import { Observable } from "rxjs";
import { HelpersService } from "./helpers.service";

export interface LoginResponse {
  data: any;
  statusCode: number;
  message: string;
  errors: any;
}

export interface LoginPayload {
  username: string;
  password: string;
  remember_me: boolean;
}

export interface LogoutResponse {
  data: any;
  statusCode: number;
  message: string;
}

@Injectable({
  providedIn: "root",
})
export class AuthService {
  protected token = "access_token";
  protected jwtToken = "access_jwt_token";
  protected authURL = "/auth/login";
  protected logoutURL = "/logout";

  constructor(
    private http: HttpClient,
    private router: Router,
    private jwtHelper: JwtHelperService,
    private helpers: HelpersService
  ) {}

  btoa(data: string): string {
    if (typeof window !== "undefined") {
      return this.btoaUtf8(data);
    } else {
      const buffer = Buffer.from(data, "binary");
      return buffer.toString("base64");
    }
  }

  btoaUtf8(data: string): string {
    const utf8Data = encodeURIComponent(data).replace(
      /%([0-9A-F]{2})/g,
      (_, p1) => String.fromCharCode(parseInt(p1, 16))
    );
    return window.btoa(utf8Data);
  }

  login({
    username,
    password,
    remember_me,
  }: LoginPayload): Observable<LoginResponse> {
    const auth = "Basic " + this.btoa(`${username}:${password}`);
    const headers = new HttpHeaders().append("Authorization", auth);
    const url = this.authURL;
    return this.http.post<LoginResponse>(url, { remember_me }, { headers });
  }

  setToken(token: string): void {
    localStorage.setItem(this.token, token);
  }

  getToken(): string {
    return localStorage.getItem(this.token) ?? "";
  }

  setJwtToken(jwtToken: string): void {
    localStorage.setItem(this.jwtToken, jwtToken);
  }

  getJwtToken(): string {
    return localStorage.getItem(this.jwtToken) ?? "";
  }

  removeToken(): void {
    localStorage.removeItem(this.token);
    localStorage.removeItem(this.jwtToken);
  }

  isAuthenticated(): boolean {
    return !this.jwtHelper.isTokenExpired(this.getJwtToken());
  }

  authRedirect() {
    this.removeToken();
    this.router.navigate(["auth"], {
      queryParams: { url: this.router.url },
    });
    this.helpers.toast("error", "Silahkan login terlebih dahulu");
  }

  getLoggedUser(jwt = null): any {
    if (!this.isAuthenticated()) {
      this.authRedirect();
      return null;
    }

    const token = jwt ?? this.getJwtToken();
    const decodedToken = this.jwtHelper.decodeToken<any>(token);
    if (!decodedToken) {
      this.authRedirect();
      return null;
    }

    return decodedToken.user;
  }

  logout(): void {
    this.http
      .post("https://api-roadreport.pisdev.my.id/auth/logout", {})
      .subscribe(() => {
        if (!this.getLoggedUser()) return;
        this.removeToken();
        this.router.navigate(["auth"]);
      });
    console.log("tes");
  }
}
