import JsonData_ from '../../assets/data.json';

type TCellType = 'E' | 'I' | 'G' | 'P' | 'S';

interface JsonDataItem {
  pd: number;
  recordingVolume: {
    width: number;
    height: number;
    depth: number;
  };
  imagingDepth: {
    from: number;
    to: number;
  };
  cellType: string[]; // TCellType[] or ("E"|"I"|"G"|"P"|"S")[];
  area: string;
  cellNum: number;
  expDate: string;
  releaseDate: string;
  geneType: string;
  remark: string;
}

interface JsonData {
  [name: string]: JsonDataItem;
}

export interface SearchParams {
  pdStart: number;
  pdEnd: number;
  widthMin: number;
  widthMax: number;
  depthMin: number;
  depthMax: number;
  cellType: string;
  area: string;
  geneType: string;
  keyword: string;
}

interface SearchResult {
  name: string;
  item: JsonDataItem;
}
export type SearchResults = SearchResult[];

const jsonData: JsonData = JsonData_;

export function exists(name: string): boolean {
  return Object.hasOwn(jsonData, name);
}

export function search(params: SearchParams): SearchResults {
  const results: SearchResults = [];
  for (const name in jsonData) {
    const item = jsonData[name];
    if (item.pd < params.pdStart || params.pdEnd < item.pd) {
      continue;
    }
    if (item.recordingVolume.width < params.widthMin || params.widthMax < item.recordingVolume.width) {
      continue;
    }
    if (item.imagingDepth.from < params.depthMin || params.depthMax < item.imagingDepth.to) {
      continue;
    }
    if (params.cellType !== 'any') {
      if (!item.cellType.includes(params.cellType as TCellType)) {
        continue;
      }
    }
    if (params.area !== 'all' && item.area !== params.area) {
      continue;
    }
    if (params.geneType !== 'all' && item.geneType !== params.geneType) {
      continue;
    }
    if (params.keyword.length !== 0 && !item.remark.includes(params.keyword)) {
      continue;
    }
    results.push({ name, item });
  }
  return results;
}

const DataUtils = { exists, search };
export default DataUtils;
