import { HttpParams } from "@angular/common/http";
import { Injectable } from "@angular/core";
import * as dayjs from "dayjs";
import * as relativeTime from "dayjs/plugin/relativeTime";
import "dayjs/locale/id";
import { ToastrService } from "ngx-toastr";
import { FormGroup } from "@angular/forms";
import { RouterStateSnapshot } from "@angular/router";
import { HTTPQuery } from "../interfaces/http-query";

@Injectable({
  providedIn: "root",
})
export class HelpersService {
  constructor(private toastr: ToastrService) {
    dayjs.locale("id");
  }

  toHttpParams(query: any, params: HttpParams, state: string): HttpParams {
    const attributes = Object.keys(query);

    if (attributes.length) {
      if (state === "filter") {
        attributes.forEach((attribute) => {
          const keys = Object.keys(query[attribute]);

          if (keys.length) {
            keys.forEach((key) => {
              params = params.set(
                `${attribute}[${key}]`,
                query[attribute][key]
              );
            });
          }
        });
      } else {
        params = params.set(`search[${query.fields}]`, query.value);
      }
    }

    if (query.operation) {
      params = params.set("operation", query.operation);
    }

    return params;
  }

  generateParams(query: HTTPQuery): HttpParams {
    const {
      page,
      limit,
      sort,
      fields,
      embed,
      search,
      filter,
      operation,
      embedOptions,
    } = query;

    let params = new HttpParams();

    if (page != null && page > -1) {
      params = params.set("page", page.toString());
    }
    if (limit != null && limit > -1) {
      params = params.set("limit", limit.toString());
    }
    if (sort) {
      params = params.set("sort", sort);
    }
    if (fields) {
      params = params.set("fields", fields);
    }
    if (embed) {
      params = params.set("embed", embed);
    }
    if (search) {
      params = this.toHttpParams(search, params, "search");
    }
    if (filter) {
      params = this.toHttpParams(filter, params, "filter");
    }
    if (operation) {
      params = params.set("operation", operation);
    }
    if (embedOptions && typeof embedOptions === "object") {
      embedOptions.forEach((option: any) => {
        if (option.embed) {
          if (option.fields) {
            params = params.set(`${option.embed}.fields`, option.fields);
          }
          if (option.sort) {
            params = params.set(`${option.embed}.sort`, option.sort);
          }
        }
      });
    }

    return params;
  }

  toast(type: string, message: string) {
    if (type === "success") {
      this.toastr.success(message);
    } else if (type === "error") {
      this.toastr.error(message);
    } else {
      this.toastr.info(message);
    }
  }

  isInvalid(form: FormGroup, control: string): boolean {
    return (
      (form.get(control)?.invalid &&
        (form.get(control)?.dirty || form.get(control)?.touched)) ||
      false
    );
  }

  hasError(form: FormGroup, control: string, error: string): boolean {
    return (
      (form.get(control)?.invalid &&
        (form.get(control)?.dirty || form.get(control)?.touched) &&
        form.get(control)?.hasError(error)) ||
      false
    );
  }

  previousUrl(state: RouterStateSnapshot) {
    const splited = state.url.split("/");
    return splited.splice(0, splited.length - 1).join("/");
  }

  timeAgo(date: Date): string {
    dayjs.extend(relativeTime);
    return dayjs(date).fromNow();
  }
}
