interface SalesBldrConfig {
  apiUrl: string;
  apiKey: string;
}

interface QuoteItem {
  id: string;
  category?: object;
  cost?: number;
  mpn?: string;
  markup?: number;
  deliveryDate?: string;
  discount?: number;
  unit?: string;
  term?: string;
  name: string;
  price?: number;
  quantity: number;
  shortDescription?: string;
}

interface Quote {
  id: string;
  title: string;
  number: string;
  status: string;
  createdAt: string;
  sentAt?: string;
  expiresAt?: string;
  approvedAt?: string;
  company?: {
    id: string;
    name: string;
    externalIdentifier?: string;
  };
  contact?: object;
  owner?: object;
  items?: QuoteItem[];
  opportunity?: {
    id: string;
    name: string;
    description?: string;
  };
}

interface QuoteSearchResponse {
  results: Quote[];
  total: number;
  filters?: any[];
  sortOptions?: any[];
}

export class SalesBldrClient {
  private config: SalesBldrConfig;

  constructor(config?: SalesBldrConfig) {
    this.config = config || {
      apiUrl: process.env.SALESBLDR_API_URL || '',
      apiKey: process.env.SALESBLDR_API_KEY || ''
    };
  }

  private ensureConfig() {
    if (!this.config.apiUrl || !this.config.apiKey) {
      throw new Error('SalesBldr API URL and API Key are required');
    }
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    this.ensureConfig();
    const url = `${this.config.apiUrl}${endpoint}`;
    
    const headers: HeadersInit = {
      'api-key': this.config.apiKey,
      'Content-Type': 'application/json',
      ...options.headers,
    };

    const response = await fetch(url, {
      ...options,
      headers,
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(
        `SalesBldr API error: ${response.status} ${response.statusText} - ${errorText}`
      );
    }

    return response.json();
  }

  async getQuotes(params?: {
    sort?: string;
    filters?: string;
    query?: string;
    size?: number;
    from?: number;
  }): Promise<QuoteSearchResponse> {
    const queryParams = new URLSearchParams();
    
    if (params?.sort) queryParams.append('sort', params.sort);
    if (params?.filters) queryParams.append('filters', params.filters);
    if (params?.query) queryParams.append('query', params.query);
    if (params?.size !== undefined) queryParams.append('size', params.size.toString());
    if (params?.from !== undefined) queryParams.append('from', params.from.toString());

    const endpoint = `/public-api/quote${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    return this.request<QuoteSearchResponse>(endpoint);
  }

  async getOpenQuotes(size: number = 10): Promise<QuoteSearchResponse> {
    return this.getQuotes({
      filters: 'status:sent|draft',
      sort: '-createdAt',
      size
    });
  }

  async getApprovedQuotes(size: number = 10): Promise<Quote[]> {
    const endpoint = `/public-api/quote/approved`;
    return this.request<Quote[]>(endpoint);
  }

  async getOpportunities(params?: {
    sort?: string;
    filters?: string;
    query?: string;
    size?: number;
    from?: number;
  }): Promise<any> {
    const queryParams = new URLSearchParams();
    
    if (params?.sort) queryParams.append('sort', params.sort);
    if (params?.filters) queryParams.append('filters', params.filters);
    if (params?.query) queryParams.append('query', params.query);
    if (params?.size !== undefined) queryParams.append('size', params.size.toString());
    if (params?.from !== undefined) queryParams.append('from', params.from.toString());

    const endpoint = `/public-api/opportunity${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    return this.request(endpoint);
  }

  async getProducts(params?: {
    includeBundles?: boolean;
    sort?: string;
    filters?: string;
    query?: string;
    size?: number;
    from?: number;
  }): Promise<any> {
    const queryParams = new URLSearchParams();
    
    if (params?.includeBundles !== undefined) queryParams.append('includeBundles', params.includeBundles.toString());
    if (params?.sort) queryParams.append('sort', params.sort);
    if (params?.filters) queryParams.append('filters', params.filters);
    if (params?.query) queryParams.append('query', params.query);
    if (params?.size !== undefined) queryParams.append('size', params.size.toString());
    if (params?.from !== undefined) queryParams.append('from', params.from.toString());

    const endpoint = `/public-api/product${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    return this.request(endpoint);
  }

  async getCompanies(params?: {
    sort?: string;
    filters?: string;
    query?: string;
    size?: number;
    from?: number;
  }): Promise<any> {
    const queryParams = new URLSearchParams();
    
    if (params?.sort) queryParams.append('sort', params.sort);
    if (params?.filters) queryParams.append('filters', params.filters);
    if (params?.query) queryParams.append('query', params.query);
    if (params?.size !== undefined) queryParams.append('size', params.size.toString());
    if (params?.from !== undefined) queryParams.append('from', params.from.toString());

    const endpoint = `/public-api/company${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    return this.request(endpoint);
  }

  async getContacts(params?: {
    sort?: string;
    filters?: string;
    query?: string;
    size?: number;
    from?: number;
  }): Promise<any> {
    const queryParams = new URLSearchParams();
    
    if (params?.sort) queryParams.append('sort', params.sort);
    if (params?.filters) queryParams.append('filters', params.filters);
    if (params?.query) queryParams.append('query', params.query);
    if (params?.size !== undefined) queryParams.append('size', params.size.toString());
    if (params?.from !== undefined) queryParams.append('from', params.from.toString());

    const endpoint = `/public-api/contact${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    return this.request(endpoint);
  }
}

export const salesBldrClient = new SalesBldrClient();
