import * as React from 'react';
import memoizeOne from 'memoize-one';
import { ValidateMessages } from 'rc-field-form/lib/interface';
import devWarning from '../_util/devWarning';

import { ModalLocale, changeConfirmLocale } from '../modal/locale';
import { TransferLocale as TransferLocaleForEmpty } from '../empty';
import { PaginationLocale } from '../pagination/Pagination';
import { TableLocale } from '../table/interface';
import { UploadLocale } from '../upload/interface';
import { TransferLocale } from '../transfer';
import { PickerLocale as DatePickerLocale } from '../date-picker/generatePicker';
import LocaleContext from './context';

export const ANT_MARK = 'internalMark';

export interface Locale {
  locale: string;
  Pagination?: PaginationLocale;
  DatePicker?: DatePickerLocale;
  TimePicker?: Record<string, any>;
  Calendar?: Record<string, any>;
  Table?: TableLocale;
  Modal?: ModalLocale;
  Transfer?: Partial<TransferLocale>;
  Select?: Record<string, any>;
  Upload?: UploadLocale;
  Empty?: TransferLocaleForEmpty;
  global?: Record<string, any>;
  PageHeader?: { back: string };
  Icon?: Record<string, any>;
  Text?: {
    edit?: any;
    copy?: any;
    copied?: any;
    expand?: any;
  };
  Form?: {
    optional?: string;
    defaultValidateMessages: ValidateMessages;
  };
  Image?: {
    preview: string;
  };
  Filters?: {
    moreFilters: string;
    moreFiltersWithCount: string;
    filter: string;
    noFiltersApplied: string;
    done: string;
    clearAllFilters: string;
    clear: string;
  };
  ApolloTable?: {
    sortingLabel: string;
    sortPlaceholder: string;
    sort: string;
    selected: string;
    selectAll: string;
    selectedAll: string;
    item: string;
    itemEnd: string;
    undo: string;
    moreActions: string;
    leftPin: string;
    rightPin: string;
    noPin: string;
    all: string;
    viewName: string;
    viewError: string;
    viewSaveHelpText: string;
    cancelText: string;
    saveViewText: string;
    editViewText: string;
    deleteViewText: string;
    deleteHelpText: string;
    removeText: string;
    filterText: string;
    reset: string;
    loading: string;
    moreThan: string;
    lessThan: string;
  };
  ContextualSaveBar?: {
    saveText: string;
    cancelText: string;
    discardText: string;
    title: string;
    message: string;
    primaryAction: string;
    secondaryAction: string;
    unsavedChanges: string;
    leavePageText: string;
    leavePageMessage: string;
  };
  TagInput?: {
    errorText: string;
  };
  PopoverRangePicker?: {
    type: string;
    date: string;
    dateTime: string;
    range: string;
    custom: string;
    currentHour: string;
    lastHour: string;
    lastThreeHours: string;
    Today: string;
    sevenDaysAgo: string;
    thirtyDaysAgo: string;
    ninetyDaysAgo: string;
    lastYear: string;
    thisWeek: string;
    thisMonth: string;
    thisQuarter: string;
    thisYear: string;
    compare: string;
    lastTerm: string;
    yesterday: string;
    lastWeek: string;
    lastMonth: string;
    comparePlaceholder: string;
    cancel: string;
    ok: string;
  };
  Thumbnail?: {
    title: string;
  };
  Notification?: {
    confirmText: string;
    closeText: string;
  };
}

export interface LocaleProviderProps {
  locale: Locale;
  children?: React.ReactNode;
  _ANT_MARK__?: string;
}

export default class LocaleProvider extends React.Component<LocaleProviderProps, any> {
  static defaultProps = {
    locale: {},
  };

  constructor(props: LocaleProviderProps) {
    super(props);
    changeConfirmLocale(props.locale && props.locale.Modal);

    devWarning(
      props._ANT_MARK__ === ANT_MARK,
      'LocaleProvider',
      '`LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead: http://u.ant.design/locale',
    );
  }

  componentDidUpdate(prevProps: LocaleProviderProps) {
    const { locale } = this.props;
    if (prevProps.locale !== locale) {
      changeConfirmLocale(locale && locale.Modal);
    }
  }

  componentWillUnmount() {
    changeConfirmLocale();
  }

  getMemoizedContextValue = memoizeOne((localeValue: Locale): Locale & { exist?: boolean } => ({
    ...localeValue,
    exist: true,
  }));

  render() {
    const { locale, children } = this.props;
    const contextValue = this.getMemoizedContextValue(locale);
    return <LocaleContext.Provider value={contextValue}>{children}</LocaleContext.Provider>;
  }
}
