/**
 * Converts a filter object (including date range keys) to Frappe filter array format.
 */

export type SortOption =
  | 'creation desc'
  | 'creation asc'
  | 'modified desc'
  | 'modified asc'
  | 'name asc'
  | 'name desc'
  | 'asset_name asc'
  | 'asset_name desc';

export type DateFilterField = '' | 'creation' | 'modified';

const VALID_SORT_OPTIONS: SortOption[] = [
  'creation desc',
  'creation asc',
  'modified desc',
  'modified asc',
  'name asc',
  'name desc',
  'asset_name asc',
  'asset_name desc',
];

export function normalizeSortBy(value: string, fallback: SortOption = 'creation desc'): SortOption {
  return VALID_SORT_OPTIONS.includes(value as SortOption) ? (value as SortOption) : fallback;
}

export function toFrappeFilterArray(filters: Record<string, any>): any[] {
  if (!filters || typeof filters !== 'object') return [];
  const arr: any[] = [];
  for (const [key, value] of Object.entries(filters)) {
    if (value === undefined || value === null || value === '') continue;
    if (key === 'creation_from') {
      arr.push(['creation', '>=', value]);
    } else if (key === 'creation_to') {
      const d = new Date(value as string);
      if (!isNaN(d.getTime())) {
        d.setDate(d.getDate() + 1);
        arr.push(['creation', '<', d.toISOString().slice(0, 10)]);
      }
    } else if (key === 'modified_from') {
      arr.push(['modified', '>=', value]);
    } else if (key === 'modified_to') {
      const d = new Date(value as string);
      if (!isNaN(d.getTime())) {
        d.setDate(d.getDate() + 1);
        arr.push(['modified', '<', d.toISOString().slice(0, 10)]);
      }
    } else if (Array.isArray(value) && value.length >= 2) {
      arr.push([key, value[0], value[1]]);
    } else {
      arr.push([key, '=', value]);
    }
  }
  return arr;
}

export function buildDateRangeFilters(
  dateFilterBy: '' | 'creation' | 'modified',
  dateStart: string,
  dateEnd: string
): Record<string, string> {
  if (!dateFilterBy || (!dateStart && !dateEnd)) return {};
  const f: Record<string, string> = {};
  if (dateFilterBy === 'creation') {
    if (dateStart) f.creation_from = dateStart;
    if (dateEnd) f.creation_to = dateEnd;
  } else {
    if (dateStart) f.modified_from = dateStart;
    if (dateEnd) f.modified_to = dateEnd;
  }
  return f;
}

/** Merge date range into object filters for custom list APIs (get_assets, etc.) */
export function applyDateRangeToFilters(
  filters: Record<string, any>,
  dateFilterBy: '' | 'creation' | 'modified',
  dateStart: string,
  dateEnd: string
): Record<string, any> {
  const result = { ...filters, ...buildDateRangeFilters(dateFilterBy, dateStart, dateEnd) };

  const applyRange = (field: 'creation' | 'modified') => {
    const fromKey = `${field}_from`;
    const toKey = `${field}_to`;
    const fromVal = result[fromKey];
    const toVal = result[toKey];
    delete result[fromKey];
    delete result[toKey];

    if (fromVal && toVal) {
      result[field] = ['between', [`${fromVal} 00:00:00`, `${toVal} 23:59:59`]];
    } else if (fromVal) {
      result[field] = ['>=', `${fromVal} 00:00:00`];
    } else if (toVal) {
      const d = new Date(toVal as string);
      if (!isNaN(d.getTime())) {
        d.setDate(d.getDate() + 1);
        result[field] = ['<', `${d.toISOString().slice(0, 10)} 00:00:00`];
      }
    }
  };

  if (dateFilterBy === 'creation') applyRange('creation');
  if (dateFilterBy === 'modified') applyRange('modified');

  return result;
}
