import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable} from 'rxjs';
import {Author} from '../models/author';
import {Post} from '../models/post';
import {ConfigurationService} from '../configuration.service';

@Injectable({
  providedIn: 'root'
})
export class AuthorService {
  apiUrl: string = '';

  constructor(private httpClient: HttpClient,
              private configurationService: ConfigurationService) {
    this.apiUrl = `${this.configurationService.getApiUrl()}/authors`
  }

  list(): Observable<Author[]> {
    return this.httpClient.get<Author[]>(this.apiUrl);
  }

  login(name: string, password: string) {
    return this.httpClient.post<any>(`${this.apiUrl}/login`, {name: name, password: password})
  }

  me(token: string): Observable<Author> {
    const headers = new HttpHeaders().set("Authorization", "Bearer " + token);
    return this.httpClient.get<Author>(`${this.apiUrl}/me`, {'headers': headers});
  }

  attributePost(authorId: string | undefined, postId: bigint, token: string) {
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': `Bearer ${token}`
      })
    };
    return this.httpClient.put<any>(`${this.apiUrl}/${authorId}/posts`, postId, httpOptions);
  }

  updateAuthor(authorId: string, token: string, username: string, password: string): Observable<Author> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': `Bearer ${token}`
      })
    }
    return this.httpClient.put<Author>(`${this.apiUrl}/${authorId}`, {name: username, password: password}, httpOptions);
  }

  changeAvatar(id: string | undefined, image: File | undefined, token: string) {
    if (image) {
      const formData: FormData = new FormData();
      formData.append('avatar', image);
      const httpOptions = {
        headers: new HttpHeaders({
          'Authorization': `Bearer ${token}`
        })
      };
      return this.httpClient.put<Author>(`${this.apiUrl}/${id}/avatar`, formData, httpOptions);
    } else {
      throw new Error('Image doesn\'t exist');
    }
  }

  getAvatar(id: string): Observable<string> {
    return this.httpClient.get(`${this.apiUrl}/${id}/avatar`, { responseType: 'text' });
  }


  getAuthor(id: string | null): Observable<Author> {
    if (id) {
      return this.httpClient.get<Author>(`${this.apiUrl}/${id}`);
    } else {
      throw new Error("Not Found");
    }
  }

  getAuthorsPosts(id: string | undefined, token: string): Observable<Post[]> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': `Bearer ${token}`
      })
    };
    return this.httpClient.get<Post[]>(`${this.apiUrl}/${id}/posts`, httpOptions);
  }

  createAccount(username: string, password: string): Observable<Author> {
    return this.httpClient.post<Author>(`${this.apiUrl}/register`, {name: username, password: password})
  }

  createAccountAdmin(username: string, password: string, role: string, token: string): Observable<Author> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': `Bearer ${token}`
      })
    }
    return this.httpClient.post<Author>(`${this.apiUrl}/register/admin`, {
      name: username,
      password: password,
      role: role
    }, httpOptions);
  }

  getAuthorAvatar(id: string) {
    return this.httpClient.get<string>(`${this.apiUrl}/${id}/avatar`);
  }
}
