import { DefineComponent, Slot } from 'vue';
import { FilterOption } from '@/types/filterOption.type';
import { FilterField } from '@/types/filterField.type';

export interface DialogSelectAssetFilterModels {
  assetName?: string[];
  name?: string[];
  brands?: string[];
  models?: string[];
  tagType?: string[];
  group?: string[];
}

export type AssetStatus =
  | 'Assigned'
  | 'Available'
  | 'Borrowed'
  | 'Damaged'
  | 'Missing'
  | 'Non-Transactionable'
  | 'Not Paired Yet'
  | 'On Assign Process'
  | 'On Audit Process'
  | 'On Borrowing Process'
  | 'On Transfer'
  | 'TAG Reported';

export type AssetOptionField = 'nameOptions' | 'brandOptions' | 'modelOptions';

/**
 * The filter field config
 */
export type FilterFieldConfig = {
  /**
   * The label for the field.
   */
  label: string;
  /**
   * The fieldname for the option.
   *
   * The fieldname is used to fill the option menu.
   *
   * The fieldname must be the same string as the asset options response from API.
   */
  fieldName: 'brand' | 'name' | 'model' | 'tagType' | 'group';
  /**
   * The placeholder for the option.
   */
  placeholder?: string;
  /**
   * Determine if the option is included or not.
   *
   * @default false
   */
  exception?: boolean;
  /**
   * Determine if the option is static or not.
   *
   * @default false
   */
  static?: boolean;
  staticOptions?: FilterOption[];
};

export interface AssetName {
  _id: string;
  name: string;
  totalAssets: number;
  key: number;
  tagType: 'RFID' | 'QR' | 'RFID & QR' | 'Non TAG';
}

/**
 * Type of the selected data, it refers to data response from Asset API.
 */
export interface Asset {
  _id?: string;
  name?: {
    _id?: string;
    nameWithSequence?: string;
    name?: string;
    key?: number;
  };
  tagType?: string;
  status?: string;
  category?: {
    _id?: string;
    name?: string;
    key?: number;
  };
  group?: {
    _id?: string;
    name?: string;
    key?: number;
  };
  brand?: {
    _id?: string;
    name?: string;
    key?: number;
  };
  model?: {
    _id?: string;
    name?: string;
    key?: number;
  };
  policy?: 'Need Handover' | 'Self Service';
  transactions?: {
    borrowing?: boolean;
    disposal?: boolean;
    transfer?: boolean;
    audit?: boolean;
    maintenance?: boolean;
    tracking?: boolean;
  };
  maintenanceStatus?: string | null;
  auditStatus?: string | null;
  rfid?: boolean;
  qr?: boolean;
  assetImage?: 'string';
  image?: 'string';
  firstImage?: string;
}

export type QueryParams = {
  [key: string]: unknown;
};

export type FetchResponse = {
  data: Data[];
  totalRecords: number;
};

/**
 * Props for DialogSelectAsset component
 */
export interface DialogSelectAssetProps {
  /**
   * With default trigger button or not
   *
   * @default true
   */
  withButton?: boolean;
  /**
   * Dialog visibility model when not using default button.
   */
  visible?: boolean;
  /**
   * The custom label for the trigger button.
   *
   * @default '+ Asset' | '+ Child';
   */
  buttonLabel?: string;
  /**
   * The current asset from detail asset
   */
  currentAssetDetail?: Asset;
  /**
   * The already selected assets to be exculuded on fetch request.
   *
   * The list of asset _id
   */
  selectedAssets?: string[];
  filterLists?: ('group' | 'tagType' | 'name' | 'brand' | 'model')[];
  /**
   *
   * The list of asset name key to be excluded in fetch list
   */
  excludedKey?: string[];
  /**
   *
   * The list of asset name _id to be excluded in fetch list
   */
  excludeId?: string[];
  /**
   *
   * The list of group _id of asset names to be excluded in fetch list
   */
  excludeInitialGroup?: string[];
  /**
   * The header of the dialog.
   *
   * @default 'Select Asset' | 'Select Child Asset';
   */
  header?: string;
  /**
   * The description of the dialog.
   * Placed above the table.
   *
   * @default 'Select asset to be linked' | 'Select asset to be transacted';
   */
  description?: string;
  /**
   * The size of the dialog.
   *
   * '600 px' | '800 px' | '1000 px'
   *
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
  /**
   * The type of the dialog.
   *
   * The type will determine table data response from API.
   *
   * Type'asset' will return response of asset lists with or without excluded asset Id.
   *
   * Type 'child' will return response of unlinked asset with specific group key.
   *
   * @default 'asset';
   */
  type?: 'asset' | 'assetName' | 'child' | 'parent';
  /**
   * Specify the asset status filter to be included
   *
   * @default ["Available"]
   */
  assetStatus?: AssetStatus[];
  /**
   * Set to true to get Asset Name with unpaired status
   */
  unpaired?: boolean;
  /**
   * The extra props when dialog type is 'asset'.
   *
   * It will return table data response filtered by the tag type.
   *
   * Set to true to show TAG Column in Select Asset Name Dialog
   *  @default false
   */
  tagType?: 'RFID' | 'QR' | 'RFID & QR' | boolean;
  /**
   * The required group key when the dialog type is 'child'.
   */
  groupKey?: number;
  /**
   * Hide or show the scan button.
   *
   * @default false
   */
  useScanButton?: boolean;
  /**
   * Type of the scan button.
   *
   * @default 'search'
   */
  scanType?: 'search' | 'rfid-qr';
  /**
   * Tooltip information about the Dialog.
   */
  tooltipInfo?: string;
  /**
   * Disabled state for the button.
   */
  disabled?: boolean;
  /**
   * Tooltip information about the button dialog.
   */
  btnTooltipInfo?: string;
  /**
   * The function to fetch data on DataTable mounted and on queryParams dependencies updated.
   *
   * @param params this is required
   */
  fetchFunction?: (params: QueryParams) => Promise<FetchResponse | undefined>;
  /**
   * The function to fetch filter options for AssetFilters.
   *
   * Overrides the default handleFetchOptions when provided.
   */
  fetchOptionFunction?: FilterField<QueryParams>['fetchOptionFn'];
}

/**
 * Emits for DialogSelectAsset component
 */
export type DialogSelectAssetEmit = {
  /**
   * Emits when the button select clicked.
   */
  select: [payload: Asset[] | AssetName[]];
};

export interface DialogSelectAssetSlots {
  /**
   * Slot for dialog select asset description section.
   */
  description: Slot;
}

/**
 * *TSVue - DialogSelectAsset*
 *
 * DialogSelectAsset is a component for creating select assets dialogs.
 *
 * --- ---
 * ![TSVue](https://ik.imagekit.io/kurniadev/TS-HEAD-BLACK.png)
 *
 * @group components
 */
declare const DialogSelectAsset: DefineComponent<
  DialogSelectAssetProps,
  DialogSelectAssetEmit,
  DialogSelectAssetSlots
>;

export default DialogSelectAsset;
