import { inject, Injectable } from "@angular/core";
import { OdataGridHelper } from '../_shared/utils/odata-grid-helper';
import { HttpClient } from "@angular/common/http";
import * as util from '../_shared/utils/util';
import * as models from '../invoice-gas/models';
import { Observable } from "rxjs";

export interface RequiredData {
  hasModifyPermission: boolean;
  hasApprovalPermission: boolean;
  hasDistributePermission: boolean;
  dealNums: dealNums[];
  internalEntities: util.IdName[];
  counterparties: util.IdName[];
  pipelines: util.Pipe[];
  meterOrGroups: models.MeterOrGroup[];
  products: models.InvoiceProduct[];
  states: util.IdName[];
  countries: util.IdName[];
  companies: util.IdName[];
  meters: util.Meter[];
}

export interface dealNums {
  id: number;
  name: string;
  trader: string;
}
export interface Invoice {
  mainInvoice: models.MainInvoice;
  lines: InvoiceLineItem[];
}

export interface InvoiceLineItem {
  id: number;
  lineNum: number;
  dealId: number;
  flowDays: string;
  // number or string here because of [allowCustom]="true" in the fast-combobox
  deliveryPipelineId: number | string;
  // number or string here because of [allowCustom]="true" in the fast-combobox
  meterId: number | string;
  quantity: number;
  price: number;
  adder: number;
  invoicePrice: number;
  amount: number;
  description: string;
  isApproved: boolean;
  isRegenerated: boolean;
  pipelineCustomText?: string;
  meterCustomText?: string;
}

export interface RevisionParams {
  counterpartyId: number;
  internalEntityId: number;
  month: Date;
  existingLines: InvoiceLineItem[];
  lineSelection: number[];
}

export enum SaveType {
  New = 1,
  Draft = 2,
}

// not currently being used
export interface SaveInvoiceResult {
  invoiceId: number;
  invoiceNum: string;
  fileNameOriginal: string;
}

export interface InvoiceSummaryLine {
  invoiceNum: string;
  totalQuantity: number;
  totalAmount: number;
}

export interface InvoiceSummary {
  totalQuantity: number;
  totalAmount: number;
  lines: InvoiceSummaryLine[];
}

@Injectable({
  providedIn: 'root'
})
export class InvoiceGasDetailService extends OdataGridHelper {
  readonly baseUrl = `${window.location.origin}/api/InvoiceNatGasDetail`;
  http = inject(HttpClient);

  getRequiredData(counterpartyId: number, internalEntityId: number, month: Date): Observable<RequiredData> {
    const convertedMonth = month.toISOString().split('T')[0];
    const url = `${this.baseUrl}/GetRequiredData?counterpartyId=${counterpartyId}&internalEntityId=${internalEntityId}&month=${convertedMonth}`;
    return this.http.get<RequiredData>(url);
  }

  getTaxRate(meterId: number, counterpartyId: number, month: Date): Observable<number> {
    const convertedMonth = month.toISOString().split('T')[0];
    const url = `${this.baseUrl}/GetTaxRate?meterId=${meterId}&counterpartyId=${counterpartyId}&month=${convertedMonth}`;
    return this.http.get<number>(url);
  }

  getInvoice(invoiceId: number, counterpartyId: number, internalEntityId: number, month: Date): Observable<Invoice> {
    const convertedMonth = month.toISOString().split('T')[0];
    let url = `${this.baseUrl}/GetInvoice?counterpartyId=${counterpartyId}&internalEntityId=${internalEntityId}&month=${convertedMonth}`;
    if (invoiceId != null) {
      url += `&invoiceId=${invoiceId}`;
    }
    return this.http.get<Invoice>(url);
  }

  getMainInvoice(counterpartyId: number, internalEntityId: number, month: Date): Observable<models.MainInvoice> {
    const convertedMonth = month.toISOString().split('T')[0];
    const url = `${this.baseUrl}/GetMainInvoice?counterpartyId=${counterpartyId}&internalEntityId=${internalEntityId}&month=${convertedMonth}`;
    return this.http.get<models.MainInvoice>(url);
  }

  saveInvoice(saveType: SaveType, invoice: Invoice): Observable<SaveInvoiceResult> {
    const url = `${this.baseUrl}/SaveInvoice?saveType=${saveType}`;
    return this.http.put<SaveInvoiceResult>(url, invoice);
  }

  deleteInvoice(id: number) {
    const url = `${this.baseUrl}/DeleteInvoice/${id}`;
    return this.http.delete(url);
  }

  regenerateLines(counterpartyId: number, internalEntityId: number, month: Date, existingLines: InvoiceLineItem[]): Observable<InvoiceLineItem[]> {
    const convertedMonth = month.toISOString().split('T')[0];
    const url = `${this.baseUrl}/RegenerateLines?counterpartyId=${counterpartyId}&internalEntityId=${internalEntityId}&month=${convertedMonth}`;
    return this.http.put<InvoiceLineItem[]>(url, existingLines);
  }

  reviseInvoice(revisionParams: RevisionParams): Observable<InvoiceLineItem[]> {
    const url = `${this.baseUrl}/ReviseInvoice`;
    revisionParams = util.convertDatesToDateOnlyStrings(revisionParams, ['month']);
    return this.http.put<InvoiceLineItem[]>(url, revisionParams);
  }

  getInvoiceVolAndQuantity(month: Date, internalEntityId: number, counterpartyId: number): Observable<InvoiceSummary> {
    const convertedMonth = month.toISOString().split('T')[0];
    const url = `${this.baseUrl}/GetInvoiceVolAndQuantity?month=${convertedMonth}&internalEntityId=${internalEntityId}&counterpartyId=${counterpartyId}`;
    return this.http.get<InvoiceSummary>(url);
  }
}
