import React from 'react';
import { defineMessages, FormattedMessage, IntlShape } from 'react-intl';

import { deactivateUser, deleteUser, deleteStatus, toggleStatusSensitivity } from '@/actions/admin';
import OutlineBox from '@/components/outline-box';
import Stack from '@/components/ui/stack';
import Text from '@/components/ui/text';
import AccountContainer from '@/containers/account-container';
import { selectAccount } from '@/queries/accounts/selectors';
import { queryClient } from '@/queries/client';
import { useModalsStore } from '@/stores/modals';
import toast from '@/toast';

import type { AppDispatch, RootState } from '@/store';

const messages = defineMessages({
  deactivateUserHeading: {
    id: 'confirmations.admin.deactivate_user.heading',
    defaultMessage: 'Deactivate @{acct}',
  },
  deactivateUserConfirm: {
    id: 'confirmations.admin.deactivate_user.confirm',
    defaultMessage: 'Deactivate @{name}',
  },
  userDeactivated: {
    id: 'admin.users.user_deactivated_message',
    defaultMessage: '@{acct} was deactivated',
  },
  deleteUserHeading: {
    id: 'confirmations.admin.delete_user.heading',
    defaultMessage: 'Delete @{acct}',
  },
  deleteUserPrompt: {
    id: 'confirmations.admin.delete_user.message',
    defaultMessage:
      'You are about to delete @{acct}. THIS IS A DESTRUCTIVE ACTION THAT CANNOT BE UNDONE.',
  },
  deleteUserConfirm: {
    id: 'confirmations.admin.delete_user.confirm',
    defaultMessage: 'Delete @{name}',
  },
  deleteLocalUserCheckbox: {
    id: 'confirmations.admin.delete_local_user.checkbox',
    defaultMessage: 'I understand that I am about to delete a local user.',
  },
  userDeleted: { id: 'admin.users.user_deleted_message', defaultMessage: '@{acct} was deleted' },
  deleteStatusHeading: {
    id: 'confirmations.admin.delete_status.heading',
    defaultMessage: 'Delete post',
  },
  deleteStatusPrompt: {
    id: 'confirmations.admin.delete_status.message',
    defaultMessage: 'You are about to delete a post by @{acct}. This action cannot be undone.',
  },
  deleteStatusConfirm: {
    id: 'confirmations.admin.delete_status.confirm',
    defaultMessage: 'Delete post',
  },
  statusDeleted: {
    id: 'admin.statuses.status_deleted_message',
    defaultMessage: 'Post by @{acct} was deleted',
  },
  markStatusSensitiveHeading: {
    id: 'confirmations.admin.mark_status_sensitive.heading',
    defaultMessage: 'Mark post sensitive',
  },
  markStatusNotSensitiveHeading: {
    id: 'confirmations.admin.mark_status_not_sensitive.heading',
    defaultMessage: 'Mark post not sensitive.',
  },
  markStatusSensitivePrompt: {
    id: 'confirmations.admin.mark_status_sensitive.message',
    defaultMessage: 'You are about to mark a post by @{acct} sensitive.',
  },
  markStatusNotSensitivePrompt: {
    id: 'confirmations.admin.mark_status_not_sensitive.message',
    defaultMessage: 'You are about to mark a post by @{acct} not sensitive.',
  },
  markStatusSensitiveConfirm: {
    id: 'confirmations.admin.mark_status_sensitive.confirm',
    defaultMessage: 'Mark post sensitive',
  },
  markStatusNotSensitiveConfirm: {
    id: 'confirmations.admin.mark_status_not_sensitive.confirm',
    defaultMessage: 'Mark post not sensitive',
  },
  statusMarkedSensitive: {
    id: 'admin.statuses.status_marked_message_sensitive',
    defaultMessage: 'Post by @{acct} was marked sensitive',
  },
  statusMarkedNotSensitive: {
    id: 'admin.statuses.status_marked_message_not_sensitive',
    defaultMessage: 'Post by @{acct} was marked not sensitive',
  },
});

const deactivateUserModal =
  (intl: IntlShape, accountId: string, afterConfirm = () => {}) =>
  (dispatch: AppDispatch) => {
    const acct = selectAccount(accountId)!.acct;
    const name = selectAccount(accountId)!.username;

    const message = (
      <Stack space={4}>
        <OutlineBox>
          <AccountContainer id={accountId} hideActions />
        </OutlineBox>

        <Text>
          <FormattedMessage
            id='confirmations.admin.deactivate_user.message'
            defaultMessage='You are about to deactivate @{acct}. Deactivating a user is a reversible action.'
            values={{ acct }}
          />
        </Text>
      </Stack>
    );

    useModalsStore.getState().actions.openModal('CONFIRM', {
      heading: intl.formatMessage(messages.deactivateUserHeading, { acct }),
      message,
      confirm: intl.formatMessage(messages.deactivateUserConfirm, { name }),
      onConfirm: () => {
        dispatch(deactivateUser(accountId))
          .then(() => {
            const message = intl.formatMessage(messages.userDeactivated, { acct });
            toast.success(message);
            afterConfirm();
          })
          .catch(() => {});
      },
    });
  };

const deleteUserModal =
  (intl: IntlShape, accountId: string, afterConfirm = () => {}) =>
  (dispatch: AppDispatch) => {
    const account = selectAccount(accountId)!;
    const acct = account.acct;
    const name = account.username;
    const local = account.local;

    const message = (
      <Stack space={4}>
        <OutlineBox>
          <AccountContainer id={accountId} hideActions />
        </OutlineBox>

        <Text>
          <FormattedMessage
            id='confirmations.admin.delete_user.message'
            defaultMessage='You are about to delete @{acct}. THIS IS A DESTRUCTIVE ACTION THAT CANNOT BE UNDONE.'
            values={{ acct }}
          />
        </Text>
      </Stack>
    );

    const confirm = intl.formatMessage(messages.deleteUserConfirm, { name });
    const checkbox = local ? intl.formatMessage(messages.deleteLocalUserCheckbox) : false;

    useModalsStore.getState().actions.openModal('CONFIRM', {
      heading: intl.formatMessage(messages.deleteUserHeading, { acct }),
      message,
      confirm,
      checkbox,
      onConfirm: () => {
        dispatch(deleteUser(accountId))
          .then(() => {
            const message = intl.formatMessage(messages.userDeleted, { acct });
            queryClient.invalidateQueries({ queryKey: ['accounts', accountId] });
            queryClient.invalidateQueries({
              queryKey: ['accounts', 'lookup', acct.toLocaleLowerCase()],
            });
            toast.success(message);
            afterConfirm();
          })
          .catch(() => {});
      },
    });
  };

const toggleStatusSensitivityModal =
  (intl: IntlShape, statusId: string, sensitive: boolean, afterConfirm = () => {}) =>
  (dispatch: AppDispatch, getState: () => RootState) => {
    const state = getState();
    const acct = state.statuses[statusId].account.acct;

    useModalsStore.getState().actions.openModal('CONFIRM', {
      heading: intl.formatMessage(
        !sensitive ? messages.markStatusSensitiveHeading : messages.markStatusNotSensitiveHeading,
      ),
      message: intl.formatMessage(
        !sensitive ? messages.markStatusSensitivePrompt : messages.markStatusNotSensitivePrompt,
        { acct },
      ),
      confirm: intl.formatMessage(
        !sensitive ? messages.markStatusSensitiveConfirm : messages.markStatusNotSensitiveConfirm,
      ),
      onConfirm: () => {
        dispatch(toggleStatusSensitivity(statusId, sensitive))
          .then(() => {
            const message = intl.formatMessage(
              !sensitive ? messages.statusMarkedSensitive : messages.statusMarkedNotSensitive,
              { acct },
            );
            toast.success(message);
          })
          .catch(() => {});
        afterConfirm();
      },
    });
  };

const deleteStatusModal =
  (intl: IntlShape, statusId: string, afterConfirm = () => {}) =>
  (dispatch: AppDispatch, getState: () => RootState) => {
    const state = getState();
    const acct = state.statuses[statusId].account.acct;

    useModalsStore.getState().actions.openModal('CONFIRM', {
      heading: intl.formatMessage(messages.deleteStatusHeading),
      message: intl.formatMessage(messages.deleteStatusPrompt, {
        acct: <strong className='break-words'>{acct}</strong>,
      }),
      confirm: intl.formatMessage(messages.deleteStatusConfirm),
      onConfirm: () => {
        dispatch(deleteStatus(statusId))
          .then(() => {
            const message = intl.formatMessage(messages.statusDeleted, { acct });
            toast.success(message);
          })
          .catch(() => {});
        afterConfirm();
      },
    });
  };

export { deactivateUserModal, deleteUserModal, toggleStatusSensitivityModal, deleteStatusModal };
