interface IFilterParams {
  // 床位大于等于
  bedNumberGreaterThanEqual?: number;
  // 房间数大于等于
  roomNumberGreaterThanEqual?: number;
  // 可住人大于等于
  tenantNumberGreaterThanEqual?: number;
  // 最低价大于等于
  priceGreaterThanEqual?: number;
  // 最高价大于等于
  priceLessThanEqual?: number;
  // 基础设施
  facilities?: number;
  // 床位数（多选）
  bedNumbers?: number;
  // 房间数（多选）
  roomNumbers?: number;
  // 可住人数（多选）
  tenantNumbers?: number;
  tenantNumber?: number;
}

interface IPagination {
  pageSize?: number;
  pageNum?: number;
}

interface ISortParams {
  // 好评优先: 0,
  starsSort?: 0;
  // 金额低到高: 1, 金额高到低: 0
  priceSort?: 1 | 0;
  // 推荐排序 降序: 0
  rankingSort?: 0;
  distanceSort?: 0;
}

interface IHouseImageInfo {
  id: string;
  imagePath: string;
  createTime?: string;
  orderNumber: number;
  serialNumber: number;
  module: string;
}

interface IWoker {
  id: string;
  userId: string;
  nickName: string;
  label: string;
  avatar: string;
  introduce: string;
  sex: number;
}

interface ITag {
  tagId: string;
  tagName: string;
  longitude?: string;
  latitude?: string;
  sortNumber?: string;
}

interface IFacilitie {
  id: string;
  houseId: string;
  categoryCode: string;
  categoryName: string;
  code: string;
  name: string;
  otherValue: string;
  orderNumber: number;
  remark: string;
  description?: string;
}

interface IHouseDetail {
  id: string;
  houseNo: string;
  houseType: string;
  houseSourceType: number;
  hotelId: string;
  shopName: string;
  label?: string;
  starsAverage?: string;
  minPrice?: string;
  lotelPhotoPath?: string;
  shortTitle?: string;
  title: string;
  houseNumber: number;
  otherTenantNumber: number;
  standardPrice: number;
  weekPrice: number;
  clearPrice: number;
  deposit: number;
  bedNumber: number;
  roomNumber: number;
  toiletNumber: number;
  publicToiletNumber: number;
  tenantNumber: number;
  countryCode?: string;
  countryName?: string;
  areaCode?: string;
  areaName?: string;
  provinceCode?: string;
  provinceName?: string;
  cityCode?: string;
  cityName?: string;
  cityEnName?: string;
  address?: string;
  houseLandlordType: number;
  designNameImage?: string;
  designer?: string;
  createTime?: string;
  stars: number;
  commentStatis: number;
  location?: string;
  houseArea?: number;
  designNameImageOss?: string;
  rankingNumber?: number;
  summary?: string;
  designerInfo?: null;
  navigationInfo?: null;
  housingInfo?: null;
  locationDistance?: number;
  houseImages?: Array<IHouseImageInfo>;
  landlord?: IWoker;
  assist?: IWoker;
  customTag: [];
  bizTag: Array<ITag>;
  allTag: Array<ITag>;
  calendars?: null;
  highlight?: null;
  hitSorts?: null;
  facilities: Array<IFacilitie>;
  comments?: null;
  properties: Array<string>;
  booked?: boolean;
  houseImagesGroup?: Array<IHouseImageInfo>;
  houseImagesMap?: null;
}

interface ILocationBaseParams {
  // 经
  longitude?: string;
  // 纬
  latitude?: string;

  distance?: number;
}

/**
 * 定位参数
 *
 * @interface IGeolocationParams
 * @extends {ILocationBaseParams}
 */
interface IGeolocationParams extends ILocationBaseParams {
  geolocationName?: string;

  cityName?: string;
}

/**
 * 位置参数
 *
 * @interface ILocationParams
 * @extends {ILocationBaseParams}
 */
interface ILocationParams extends ILocationBaseParams {
  secondLatitude?: string;
  secondLongitude?: string;
  areaCode?: string;
  areaName?: string;
}

interface ICityParams {
  cityName?: string;
  cityCode?: string;
  areaCode?: string;
  provinceName?: string;
}

interface ITagParams {
  customTagIds?: string;
  bizTagIds?: string;
  poiTagIds?: string;
  allTagIds?: string;
}

interface IDateParams {
  endDate?: number | string;
  beginDate?: number | string;
}

interface IKeywordParams {
  keyword?: string;
  keywordDummy?: string;
}

interface IOtherParams {
  limitImage?: number;
  recommend?: boolean;
}

type Action = (action: () => void) => void;

interface IOptions extends Window {
  /**
   * 是否直接查询，
   *
   * @type {boolean} 默认为 false, 查询后如果没有选择日期，则将查询参数存起来，等待选择了日期后再查询
   * @memberof IOptions
   */
  immediate?: boolean;

  action?: Action;

  prefix_api?: string;
}

type AmapValue = string | number | object | [];

interface IGeoregeoResponse {
  status?: AmapValue;
  info?: AmapValue;
  infocode?: AmapValue;
  count?: AmapValue;
  geocodes?: IAddressComponent[] | AmapValue;
  regeocode?: { addressComponent: IAddressComponent | AmapValue; formatted_address: AmapValue };
}

interface IDistrict {
  adcode: AmapValue;
  center: AmapValue;
  citycode: AmapValue;
  districts: AmapValue[];
  level: AmapValue;
  name: AmapValue;
}

interface IDistrictResponse {
  status?: AmapValue;
  info?: AmapValue;
  infocode?: AmapValue;
  count?: AmapValue;
  districts?: IDistrict[];
}

interface IAddressComponent {
  city: AmapValue;
  province?: AmapValue;
  adcode?: AmapValue;
  district?: AmapValue;
  towncode?: AmapValue;
  streetNumber?: AmapValue;
  country?: AmapValue;
  township?: AmapValue;
  businessAreas?: AmapValue;
  building?: AmapValue;
  neighborhood?: AmapValue;
  citycode?: AmapValue;
}

interface IAmapTips {
  address?: AmapValue;
  typecode: AmapValue;
  city: AmapValue;
  id: AmapValue;
  location: AmapValue;
  adcode: AmapValue;
  district: AmapValue;
  name: AmapValue;
}

interface IAmapBatchBody {
  info: 'OK';
  status: '1';
  count: '2';
  infocode: '10000';
  tips: Array<IAmapTips>;
}

interface IAmapBatchHeader {
  gsid?: string;
  'Content-Type'?: string;
  'Access-Control-Allow-Methods'?: string;
  'Access-Control-Allow-Origin'?: string;
  sc?: string;
  'Content-Length'?: number;
  'Access-Control-Allow-Headers'?: string;
  'X-Powered-By'?: string;
}

interface IAmapBatchResponse {
  status?: number;
  body?: IAmapBatchBody;
  header?: IAmapBatchHeader;
}

interface IApiResponse<T> {
  success: boolean;
  errorCode?: string;
  errorMsg?: string;
  errorDetail?: string;
  data?: T;
}

interface IApiListResponse<T> {
  total: number;
  size: number;
  pages: number;
  current: number;
  hasNextPage: boolean;
  list: Array<T>;
}

type HouseListParams = IFilterParams &
  ITagParams &
  ICityParams &
  IDateParams &
  ISortParams &
  IKeywordParams &
  ILocationParams &
  IGeolocationParams &
  IPagination &
  IOtherParams;

interface ClientSearchBase {
  params: HouseListParams;

  readonly geoLocationCityName: string;

  currentGeoLocation?: ILocationBaseParams;

  /**
   * 用户输入关键字，获取对应位置，与房源列表, 并且设置对应 keyword
   * 完成后可通过 keyword
   *
   * @param {string} keyword
   */
  onInputKeyword(keyword: string): Promise<[Array<IAmapTips | null>, IHouseDetail[], IApiListResponse<IHouseDetail>]>;

  /**
   * 点击定位获取的位置查询房源, 如果存在日期，则直接查询，否则将参数存起来
   *
   * @param {type} params
   */
  searchByGeolocation(params: IGeolocationParams): Promise<IHouseDetail[]>;

  /**
   * 通过关键字查询，如果存在日期，则直接查询，否则将参数存起来
   *
   * @param {type} params
   */
  searchByKeyword(keyword: string): Promise<IHouseDetail[]>;

  /**
   * 通过日期查询，将所有查询条件合并一起查询
   *
   * @param {IDateParams} date
   */
  searchByDate(date: IDateParams): Promise<IHouseDetail[]>;

  /**
   * 通过筛选条件查询，将所有查询条件合并一起查询
   *
   * @param {IFilterParams} filterCondition
   * @param {boolean} [withMap=false] 是否在地图上筛选
   */
  searchByFilter(filterCondition: IFilterParams, withMap: boolean): Promise<IHouseDetail[]>;

  /**
   * 通过位置查找, 将所有查询条件合并一起查询
   *
   * @param {ILocationParams} params 位置参数
   * @param {boolean} [withMap=false] 是否在地图上查找
   */
  searchByLocation(params: ILocationParams, withMap: boolean): Promise<IHouseDetail[]>;

  /**
   * 通过排序查找，将所有查询条件合并一起查询
   *
   * @param {ISortParams} params
   */
  searchBySort(params: ISortParams): Promise<IHouseDetail[]>;

  /**
   * 查询地图上的数据
   * 1. 如果用户查询了行政区，则通过行政区位置
   * 2. 如果用户有定位位置数据，则查询位置所在地的房源
   * 3. 如果有用查询了城市，则根据城市位置查询
   * 4. 查询用户所在地的位置
   *
   * @param {ILocationBaseParams} params 当前位置的经纬度
   * @returns {ILocationBaseParams} 定位的经纬度
   */
  searchMap(params: ILocationBaseParams): Promise<[ILocationBaseParams | null, IHouseDetail[]]>;

  /**
   * 用户通过拖拽地图进行查看, 筛选评率未 0.5 秒一次
   *
   * @param {ILocationBaseParams} params
   */
  searchMapWithCoord(params: ILocationBaseParams): Promise<[ILocationBaseParams | null, IHouseDetail[]]>;
}

interface ClientSearch extends ClientSearchBase {}
declare class ClientSearch {
  constructor(options?: IOptions);
}
