import React from "react";
import type { ButtonProps } from "@bigbinary/neetoui";
import type { UseQueryResult } from "react-query";
import type { AxiosResponse } from "axios";

type Member = {
  active: boolean;
  id: string;
  name: string;
};

type Group = {
  id: string;
  name: string;
  description?: string;
  userIds?: string[];
  members?: Member[];
};

type GroupDependency = {
  isCheckEnabled?: boolean;
  verificationStatus?: "successful" | "failed" | "pending";
  isDependent?: boolean;
  selectedGroup?: Group;
};

type GroupFormConfig = {
  initialValues?: object;
  validationSchema?: object;
  otherPayloadData?: (values: object) => object;
  otherElements?: (values: object) => JSX.Element;
  otherElementsAtLast?: (values: object) => JSX.Element;
};

type GroupTableConfig = {
  columnsData?: () => object[];
  deleteAlertMessage?: (group: Group) => string | JSX.Element;
  onBeforeDelete?: (group: Group) => void;
};

type GroupHeaderConfig = {
  breadcrumbs?: Breadcrumb[];
  titleHelpPopoverProps?: object;
};

type GroupsConfig = {
  header?: GroupHeaderConfig;
  table?: GroupTableConfig;
  form?: GroupFormConfig;
  pane?: {
    isLoading?: boolean;
  };
  groupDependency?: GroupDependency;
  noDataProps?: object;
};

type Permission = {
  create: boolean;
  delete: boolean;
  update: boolean;
  view: boolean;
};

type Relation = {
  children: string[];
  uncheckOnSelect?: string[];
};

type PermissionRelation = {
  [key: string]: Relation[];
};

interface Alert {
  message?: (member: Member) => string;
  title?: (member: Member) => string;
}

type Breadcrumb = {
  text: string;
  link: string;
};

type onSuccess = { callback: () => void };

type CreateMember = { onSuccess: onSuccess };

type UpdateMember = { onSuccess: onSuccess };

type AdditionalFieldsConfig = {
  component: JSX.Element;
  initialValues: object;
};

type BulkUpdateMembers = { onSuccess: onSuccess };

type Header = { breadcrumbs: Breadcrumb[] };

type SelectedMember = {
  id: string;
  email: string;
  role: string;
};

type RowProps = { [key: string]: string[] };

type TableDropdownClickProps = {
  handleUpdateRole: (props: { member: object }) => void;
  handleUpdateStatus: (props: { member: object }) => void;
};

type TableRowSelectProps = {
  rows: RowProps;
  resetSelectedRows: () => void;
  rowData: object[];
};

type TableProps = {
  onRowSelect?: (props: TableRowSelectProps) => void;
  dropdownProps?: (props: { member: object }) => void;
  onDropdownClick?: (props: TableDropdownClickProps) => void;
};

type MembersHeader = {
  otherActionBlock?: React.FC;
  otherProps?: object;
};

type DefaultBulkActions = "activate" | "deactivate" | "role";

type Categories = "ALL" | "ACTIVE" | "DEACTIVATED";

type OrderBy = "ascend" | "descend" | "";

type DefaultFilterValues = {
  page?: number;
  pageSize?: number;
  category?: Categories;
  searchTerm?: string;
  sortBy?: string;
  orderBy?: OrderBy;
  neetoFilters?: object;
};

type LabelValueObject = {
  label: string;
  value: string;
};

type FilterColumns = {
  key: string;
  node: string;
  label: string | (() => string);
  type: string;
  model: string;
  values: LabelValueObject[] | (() => LabelValueObject[]);
};

type TeamMembersConfig = {
  additionalFields?: AdditionalFieldsConfig;
  alert?: Alert;
  bulkUpdateMembers?: BulkUpdateMembers;
  createMember?: CreateMember;
  defaultFilterValues?: DefaultFilterValues;
  excludedRoles?: string[];
  fetchApiResponse?: (response: object) => void;
  filterColumns?: FilterColumns[];
  header?: MembersHeader;
  hiddenBulkActions?: DefaultBulkActions[];
  otherBulkActions?: React.FC;
  otherColumns?: object[];
  permissions: Omit<Permission, "delete">;
  rolesButtonProps?: ButtonProps | boolean;
  pathToRolesPage: string;
  table?: TableProps;
  updateMember?: UpdateMember;
};

type RolesConfig = {
  header: Header;
  helpUrl?: string;
  permissions: Permission;
  permissionRelation?: PermissionRelation;
};

type PopupComponentProps = {
  className?: string;
  children?: React.ReactNode;
};

type Role = {
  description?: string;
  id: string;
  kind: string;
  name: string;
  organizationId: string;
  permissionIds: string[];
};

type ManageMemberComponentProps =
  | PopupComponentProps
  | React.HTMLAttributes<HTMLDivElement>;

type ManageMemberOverlayProps = {
  type?: "pane" | "modal" | "page";
  isOpen: boolean;
  className?: string;
  headerProps?: ManageMemberComponentProps;
  bodyProps?: ManageMemberComponentProps;
  footerProps?: ManageMemberComponentProps;
};

type ManageMemberFormProps = Omit<ManageMemberOverlayProps, "isOpen">;

export function TeamMembers(props: { config?: TeamMembersConfig }): JSX.Element;

export function Roles(props: { config?: RolesConfig }): JSX.Element;

export function Groups(props: { config?: GroupsConfig }): JSX.Element;

export function refetchMembers(): void;

export function useFetchMembers(
  params?: DefaultFilterValues,
  options?: object
): UseQueryResult<axios.AxiosResponse<any, any>, unknown>;

export function useFetchMembersCountsPerCategory(
  options?: object
): UseQueryResult<axios.AxiosResponse<any, any>, unknown>;

export function ManageMember(props: {
  config?: TeamMembersConfig;
  onComplete: () => void;
  roles: Role[];
  selectedMember?: SelectedMember;
  componentConfig?: ManageMemberOverlayProps | ManageMemberFormProps;
}): JSX.Element;

export function RolesRadioGroup(props: {
  role: string;
  roles: Role[];
}): JSX.Element;

interface PopoverProps {
  description?: React.ReactNode;
  helpLinkProps?: ButtonProps;
  title?: string;
}

interface PopoverValues {
  preferredDateFormat?: PopoverProps;
  preferredTimeFormat?: PopoverProps;
  timeZone?: PopoverProps;
}

interface ProfilePaneProps {
  popoverProps?: PopoverValues;
}

export const Profile: {
  Pane: React.FC<ProfilePaneProps>;
  usePaneState: () => [
    boolean,
    (arg: boolean | ((prev: boolean) => boolean)) => void
  ];
};

export const MANAGE_MEMBERS_PERMISSION: string;
export const MANAGE_ROLES_PERMISSION: string;
export const VIEW_MEMBERS_PERMISSION: string;
export const VIEW_ROLES_PERMISSION: string;

type PermissionRecord = {
  category: string;
  description: string;
  id: string;
  name: string;
};

export function Permissions(props: {
  permissions: Array<PermissionRecord>;
  isDisabled?: boolean;
  permissionRelationConfig?: Object<PermissionRelation>;
});
