import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { shareReplay, map } from 'rxjs/operators';
import { IdName, convertDatesToDateOnlyStrings } from '../_shared/utils/util';
import { OdataGridHelper } from '../_shared/utils/odata-grid-helper';
import { Observable, of } from 'rxjs';
import { State } from '@progress/kendo-data-query';
import dayjs from 'dayjs';

export interface RequiredData {
  marketTypes: IdName[],
  commodities: IdName[],
  indexes: Index[]
}

export interface Index {
  fakeId: number,
  id: number,
  name: string,
  synonym: string,
  commodityId: number,
  indexTypeId: number,
  selectedMarketTypeId: number
}

export interface MarketPriceItem {
  id: number,
  indexId: number,
  indexName: string,
  priceDate: Date,
  contractMonth?: Date,
  publishDate?: Date,
  price?: number
}

export interface MarketPriceResult {
  data: MarketPriceItem[],
  total: number,
  marketTypeId: number,
  indexId: number,
  indexSynonym: string,
  state: State,
  loading: boolean,
  fromDate: Date,
  toDate: Date
}

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

  requiredData$ = this.http.get<RequiredData>(`${this.baseUrl}/getRequiredData`).pipe(
    shareReplay(1)
  )

  getMarketPriceItems(index: Index, fromDate: Date, toDate: Date, state: State): Observable<MarketPriceResult> {
    if (index && index.selectedMarketTypeId && index.id) {
      const fromDateStr = dayjs(fromDate).format("YYYY-MM-DD");
      const toDateStr = dayjs(toDate).format("YYYY-MM-DD");
      return this.fetch(`GetMarketPriceItems?marketTypeId=${index.selectedMarketTypeId}&indexId=${index.id}&fromDate=${fromDateStr}&toDate=${toDateStr}`, state, null, false).pipe(
        map(x => {
          const result: MarketPriceResult = {
            data: x.data,
            total: x.total,
            marketTypeId: index.selectedMarketTypeId,
            indexId: index.id,
            indexSynonym: index.synonym,
            state: state,
            loading: false,
            fromDate: fromDate,
            toDate: toDate
          };
          return result;
        })
      );
    }
    else
      return this.fetchEmpty().pipe(
        map(x => {
          const result: MarketPriceResult = { data: x.data, total: x.total, marketTypeId: 99, indexId: null, indexSynonym: null, state: state, loading: false, fromDate: null, toDate: null };
          return result;
        })
      );
  }

  saveMarketPrices(marketTypeId: number, indexId: number, items: MarketPriceItem[]): Observable<number> {
    if (marketTypeId && indexId && items && items.length > 0) {
      const url = `${this.baseUrl}/SaveMarketPrices?marketTypeId=${marketTypeId}&indexId=${indexId}`;
      items = convertDatesToDateOnlyStrings(items, ['priceDate', 'contractMonth', 'publishDate']);
      return this.http.put<number>(url, items)
    } else {
      return of(0);
    }
  }

  exportMarketPrices(indexes: Index[], fromDate: Date, toDate: Date) {
    const fromDateStr = dayjs(fromDate).format("YYYY-MM-DD");
    const toDateStr = dayjs(toDate).format("YYYY-MM-DD");
    return this.http.post(`${this.baseUrl}/Export?fromDate=${fromDateStr}&toDate=${toDateStr}`, indexes, { responseType: 'arraybuffer' }).pipe(
      map(result => {
        const fileBlob = new Blob([result], { type: 'application/octet-stream' });
        return fileBlob;
      })
    );
  }
}
