import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, map } from 'rxjs';
import { environment } from '../../environments/environment';

export type SortDir = 'asc' | 'desc';
export type TipoCliente = 'PF' | 'PJ';
export type TipoFiltro = 'ALL' | TipoCliente;

export type BillingSortBy =
  | 'tipo'
  | 'item'
  | 'cliente'
  | 'qtdlinhas'
  | 'franquiavivo'
  | 'valorcontratovivo'
  | 'franquialine'
  | 'valorcontratoline'
  | 'lucro'
  | 'aparelho'
  | 'formapagamento';

export interface BillingItem {
  id: string;
  tipo: string;
  item: number;
  cliente: string;

  qtdLinhas?: number | null;
  franquiaVivo?: number | null;
  valorContratoVivo?: number | null;
  franquiaLine?: number | null;
  valorContratoLine?: number | null;
  lucro?: number | null;

  aparelho?: string | null;
  formaPagamento?: string | null;
  createdAt?: string | null;
  updatedAt?: string | null;
}

export interface BillingUpdateRequest {
  tipo?: string;
  item?: number | null;
  cliente?: string | null;
  qtdLinhas?: number | null;
  franquiaVivo?: number | null;
  valorContratoVivo?: number | null;
  franquiaLine?: number | null;
  valorContratoLine?: number | null;
  lucro?: number | null;
  aparelho?: string | null;
  formaPagamento?: string | null;
}

export interface BillingQuery {
  tipo: TipoFiltro;
  page: number;
  pageSize: number;
  sortBy: BillingSortBy;
  sortDir: SortDir;
  search?: string;
  client?: string;
}

export interface ApiPagedResult<T> {
  page: number;
  pageSize: number;
  total: number;
  items: T[];
}

@Injectable({ providedIn: 'root' })
export class BillingService {
  private readonly baseUrl: string;

  constructor(private http: HttpClient) {
    const raw = (environment.apiUrl || '').replace(/\/+$/, '');
    const apiBase = raw.toLowerCase().endsWith('/api') ? raw : `${raw}/api`;
    this.baseUrl = `${apiBase}/billing`;
  }

  getPaged(q: BillingQuery): Observable<ApiPagedResult<BillingItem>> {
    let params = new HttpParams()
      .set('page', String(q.page))
      .set('pageSize', String(q.pageSize))
      .set('sortBy', q.sortBy)
      .set('sortDir', q.sortDir);

    if (q.tipo && q.tipo !== 'ALL') params = params.set('tipo', q.tipo);
    if (q.search) params = params.set('search', q.search);
    if (q.client) params = params.set('client', q.client);

    return this.http.get<ApiPagedResult<BillingItem>>(this.baseUrl, { params });
  }

  getAll(): Observable<BillingItem[]> {
    const q: BillingQuery = {
      tipo: 'ALL',
      page: 1,
      pageSize: 99999,
      sortBy: 'cliente',
      sortDir: 'asc'
    };

    return this.getPaged(q).pipe(map((res) => res.items ?? []));
  }

  getById(id: string): Observable<BillingItem> {
    return this.http.get<BillingItem>(`${this.baseUrl}/${id}`);
  }

  update(id: string, payload: BillingUpdateRequest): Observable<void> {
    return this.http.put<void>(`${this.baseUrl}/${id}`, payload);
  }

  remove(id: string): Observable<void> {
    return this.http.delete<void>(`${this.baseUrl}/${id}`);
  }
}
