import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';

import { WEB_SERVICE_CONFIG } from './provider-name-token';
import { WebServiceConfig } from './web-service-config';

@Injectable({
  providedIn: 'root',
})
export class FileService {

  private readonly filePathParameter = 'APP_FILE_PATH';
  private readonly fileIdParameter = 'APP_FILE_ID';
  private readonly fileListParameter = 'APP_FILE_LIST';

  private baseUrl = '';

  constructor(
    private http: HttpClient,
    @Inject(WEB_SERVICE_CONFIG) private webServiceConfig: WebServiceConfig
  ) {
    this.baseUrl = `${this.webServiceConfig.webServiceUrl}/${this.webServiceConfig.appFilePath}`;
  }

  /**
   * อัพโหลดไฟล์ หากต้องการอัพโหลดไฟล์ไปยังโฟล์เดอร์ที่ต้องการ
   * ให้ระบุพารามิเตอร์ APP_FILE_PATH ด้วย เช่น ต้องการเก็บไฟล์
   * ไว้ในโฟล์เดอร์ MyFile/Work1 ให้กำหนด APP_FILE_PATH
   * เป็นค่า MyFile/Work1 มาในพารามิเตอร์
   *
   * @param fileParams พารามิเตอร์ของไฟล์
   * @param filePath พาทโฟลเดอร์ของไฟล์
   */
  public upload(fileParams: { [key: string]: File }, filePath: string = ''): Observable<UploadResponse> {
    const url = `${this.baseUrl}/upload`;

    const formData = new FormData();
    for (const key in fileParams) {
      if (fileParams.hasOwnProperty(key)) {
        if (fileParams[key] instanceof File) {
          formData.append(key, fileParams[key], fileParams[key].name);
        }
      }
    }

    if (filePath) {
      formData.append(this.filePathParameter, filePath);
    }

    return this.http.post<UploadResponse>(url, formData);
  }

  /**
   * สร้าง URL สำหรับดาวน์โหลดไฟล์ โดย URL จะบังคับ
   * ให้โปรแกรมเว็บบราวเซอร์ดาวน์โหลดไฟล์เสมอ
   *
   * @param fileId Id ของไฟล์
   * @param filePath พาทโฟลเดอร์ของไฟล์
   */
  public download(fileId: string, filePath: string = ''): string {
    const url = new URL(`${this.baseUrl}/download`);

    if (!!filePath) {
      url.searchParams.append(this.filePathParameter, filePath);
    }
    url.searchParams.append(this.fileIdParameter, fileId);

    return url.toString();
  }

  /**
   * สร้าง URL สำหรับแสดงไฟล์บนเว็บบราวเซอร์
   * หากเว็บบราวเซอร์ไม่สามารถแสดงผลได้จะทำการ
   * ดาวน์โหลดไฟล์
   *
   * @param fileId Id ของไฟล์
   * @param filePath พาทโฟลเดอร์ของไฟล์
   */
  public preview(fileId: string, filePath: string = ''): string {
    const url = new URL(`${this.baseUrl}/preview`);

    if (!!filePath) {
      url.searchParams.append(this.filePathParameter, filePath);
    }
    url.searchParams.append(this.fileIdParameter, fileId);

    return url.toString();
  }

  /**
   * ลบไฟล์จากเซิร์ฟเวอร์ หากต้องการลบทั้งโฟล์เดอร์ ให้กำหนด
   * fileId เป็นค่า null และระบุชื่อโฟลเดอร์ที่ filePath
   *
   * @param fileIds Array Id ของไฟล์
   * @param filePath พาทโฟลเดอร์ของไฟล์
   */
  public remove(fileIds: string[], filePath: string = ''): Observable<DeleteResponse> {
    const url = new URL(`${this.baseUrl}/remove`);

    if (fileIds.length === 0 && !filePath) {
      throw new Error(`Both fileIds and filePath can't be empty.`);
    }

    if (!!fileIds) {
      url.searchParams.append(this.filePathParameter, filePath);
    }

    if (fileIds.length > 0) {
      url.searchParams.append(this.fileListParameter, fileIds.join(';'));
    }

    return this.http.delete<DeleteResponse>(url.toString());
  }

}


export interface UploadResponse {
  success: boolean;
  total: number;
  message: string;
  data: {
    PARAMETER_NAME: string;
    FILE_PATH: string;
    FILE_ID: string;
    FILE_NAME: string;
    CONTENT_TYPE: string;
    STATUS: boolean;
    DESCRIPTION: string;
  }[];
}

export interface DeleteResponse {
  success: boolean;
  total: number;
  message: string;
  data: {
    NAME: string;
    STATUS: boolean;
    DESCRIPTION: string;
  }[];
}
