import API_CONFIG from '../config/api';
import { toFrappeFilterArray } from '../utils/listFilterUtils';

export interface SfdaDeviceEntry {
  name?: string;
  ncmdr_ref?: string;
  manufacturer?: string;
  detail_pdf?: string;
  ade_detail_url?: string;
  material?: string;
  material_description?: string;
  catalog_number?: string;
  udi?: string;
  serial_no?: string;
  serial_no_matching?: string;
  gstn?: string;
  batch?: string;
  idx?: number;
}

export interface SfdaEntry {
  name: string;
  title?: string;
  date?: string;
  device_list?: SfdaDeviceEntry[];
  passed_date?: string;
  passed?: number | boolean;
  owner?: string;
  creation?: string;
  modified?: string;
  modified_by?: string;
}

export interface SfdaEntryListParams {
  filters?: Record<string, unknown>;
  fields?: string[];
  limit_start?: number;
  limit_page_length?: number;
  order_by?: string;
}

export interface SfdaEntryListResponse {
  data: SfdaEntry[];
}

const DOCTYPE = 'SFDA Entries';

class SfdaEntriesService {
  private baseURL: string;

  constructor() {
    this.baseURL = API_CONFIG.BASE_URL;
  }

  private async getHeaders(): Promise<Record<string, string>> {
    const headers: Record<string, string> = {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    };

    if (typeof window !== 'undefined' && (window as Window & { csrf_token?: string }).csrf_token) {
      headers['X-Frappe-CSRF-Token'] = (window as Window & { csrf_token?: string }).csrf_token!;
    }

    return headers;
  }

  async getEntries(params: SfdaEntryListParams = {}): Promise<SfdaEntryListResponse> {
    const {
      filters = {},
      fields = ['name', 'title', 'date', 'passed', 'passed_date', 'creation', 'modified'],
      limit_start = 0,
      limit_page_length = 20,
      order_by = 'modified desc',
    } = params;

    const queryParams = new URLSearchParams();
    queryParams.append('fields', JSON.stringify(fields));
    queryParams.append('limit_start', limit_start.toString());
    queryParams.append('limit_page_length', limit_page_length.toString());
    queryParams.append('order_by', order_by);

    if (Object.keys(filters).length > 0) {
      const filterArray = toFrappeFilterArray(filters);
      if (filterArray.length > 0) {
        queryParams.append('filters', JSON.stringify(filterArray));
      }
    }

    const response = await fetch(
      `${this.baseURL}/api/resource/${encodeURIComponent(DOCTYPE)}?${queryParams.toString()}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return { data: result.data || [] };
  }

  async getEntry(name: string): Promise<SfdaEntry> {
    const response = await fetch(
      `${this.baseURL}/api/resource/${encodeURIComponent(DOCTYPE)}/${encodeURIComponent(name)}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data;
  }

  async getEntryCount(filters: Record<string, unknown> = {}): Promise<number> {
    const queryParams = new URLSearchParams();
    queryParams.append('fields', JSON.stringify(['count(name) as count']));

    if (Object.keys(filters).length > 0) {
      const filterArray = toFrappeFilterArray(filters);
      if (filterArray.length > 0) {
        queryParams.append('filters', JSON.stringify(filterArray));
      }
    }

    const response = await fetch(
      `${this.baseURL}/api/resource/${encodeURIComponent(DOCTYPE)}?${queryParams.toString()}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data?.[0]?.count || 0;
  }
}

const sfdaEntriesService = new SfdaEntriesService();
export default sfdaEntriesService;
