import { Container } from 'components/layout';
import { Text, Switch } from 'components';
import { TouchableTile } from 'components/touchable-tile';
import { MyProfileFragment } from 'expo-schema';
import { FC, useCallback } from 'react';
import { useProfile } from 'hooks';
import { omit } from 'lodash';

enum PreferencesEnum {
  Room = 'Room',
  Reminder = 'Reminder',
  BlockMessage = 'BlockMessage',
  BlockMention = 'BlockMention',
  Other = 'Other',
}
type RoomPreferences =
  | 'userRecentlyActiveInRoom'
  | 'replies'
  | 'reactions'
  | 'mentions'
  | 'inThread';

type ReminderPreferences = 'reminderSet';
type OtherPreferences = 'addedToRoom' | 'addedToSpace' | 'account';
type BlockMessagesPreferences = 'messageOnCreatedBlock' | 'replies' | 'mention';
type BlockMentionPreferences = 'mention';
type BlockPreferences = BlockMentionPreferences | BlockMessagesPreferences;

type Preferences = RoomPreferences | ReminderPreferences | BlockPreferences | OtherPreferences;

const roomsTitle: Record<RoomPreferences, string> = {
  userRecentlyActiveInRoom: 'New messages in a room I was recently active in',
  replies: 'Replies to to my messages',
  reactions: 'Reactions to my messages',
  mentions: 'Messages that @mention me',
  inThread: 'Messages in threads I am in',
};

const remindersTitle: Record<ReminderPreferences, string> = {
  reminderSet: 'Reminders I have set for events and other blocks',
};

const blockMentionTitle: Record<BlockMentionPreferences, string> = {
  mention: 'Blocks that @mention me',
};

const blockMessagesTitle: Record<BlockMessagesPreferences, string> = {
  messageOnCreatedBlock: 'Comments on blocks I created',
  replies: 'Replies to my comments',
  mention: 'Comments that @mention me',
};
const otherTitle: Record<OtherPreferences, string> = {
  addedToRoom: 'When I’m added to a new room',
  addedToSpace: 'When I’m added to a new space',
  account: 'Alerts about my Pivot account and memberships',
};

export const Notifications: FC<NotificationsProps> = ({ variant, handleUpdate }) => {
  const { profile } = useProfile();
  const isPush = variant === 'push';
  const preferences = isPush
    ? profile?.pushNotificationPreference
    : profile?.emailNotificationPreference;

  const localRooms = omit(preferences?.rooms, '__typename');
  const localReminders = omit(preferences?.reminders, '__typename');
  const localBlockMentions = omit(preferences?.blockMentions, '__typename');
  const localBlockMessages = omit(preferences?.blockMessages, '__typename');
  const localOther = omit(preferences?.other, '__typename');

  const handleSettingChange = useCallback(
    (value: boolean, key: Preferences, preferenceType: PreferencesEnum) => {
      const localRoomsOptimistic = { ...localRooms };
      const localReminderOptimistic = { ...localReminders };
      const localBlockMentionOptimistic = { ...localBlockMentions };
      const localBlockMessageOptimistic = { ...localBlockMessages };
      const localOtherOptimistic = { ...localOther };

      if (preferenceType === PreferencesEnum.Room) {
        localRoomsOptimistic[key as RoomPreferences] = !value;
      } else if (preferenceType === PreferencesEnum.Reminder) {
        localReminderOptimistic[key as ReminderPreferences] = !value;
      } else if (preferenceType === PreferencesEnum.BlockMention) {
        localBlockMentionOptimistic[key as BlockMentionPreferences] = !value;
      } else if (preferenceType === PreferencesEnum.BlockMessage) {
        localBlockMessageOptimistic[key as BlockMessagesPreferences] = !value;
      } else if (preferenceType === PreferencesEnum.Other) {
        localOtherOptimistic[key as OtherPreferences] = !value;
      }
      const updatedPreferences = {
        rooms: localRoomsOptimistic,
        reminders: localReminderOptimistic,
        blockMentions: localBlockMentionOptimistic,
        blockMessages: localBlockMessageOptimistic,
        other: localOtherOptimistic,
      };
      const update = isPush
        ? {
            pushNotificationPreference: {
              __typename: 'UserNotificationPreference',
              ...updatedPreferences,
            },
          }
        : ({
            emailNotificationPreference: {
              __typename: 'UserNotificationPreference',
              ...updatedPreferences,
            },
          } as MyProfileFragment);
      handleUpdate(update as MyProfileFragment);
    },
    [
      handleUpdate,
      isPush,
      localBlockMentions,
      localBlockMessages,
      localOther,
      localReminders,
      localRooms,
    ]
  );

  return (
    <Container flexShrink={1} mb="s">
      <Container>
        <Text mb="s" variant="caption">
          ROOMS
        </Text>
        {localRooms &&
          Object.entries(localRooms).map(([key, value], index) => {
            return (
              <Container key={index}>
                <TouchableTile
                  onPress={() =>
                    handleSettingChange(
                      value as boolean,
                      key as RoomPreferences,
                      PreferencesEnum.Room
                    )
                  }
                  leftElement={
                    <Switch
                      onValueChange={() => {
                        handleSettingChange(
                          value as boolean,
                          key as RoomPreferences,
                          PreferencesEnum.Room
                        );
                      }}
                      value={value as boolean}
                      circleSize={18}
                    />
                  }
                  shapeVariant="square"
                  variant="text"
                  isHoverAllowed={false}
                  py="xs"
                  titleVariant="caption"
                  titleColor="title"
                  title={roomsTitle[key as RoomPreferences]}
                  underlayColor={'transparent'}
                />
              </Container>
            );
          })}
      </Container>
      <Container>
        <Text my="s" variant="caption">
          REMINDERS
        </Text>
        {localReminders &&
          Object.entries(localReminders).map(([key, value], index) => {
            return (
              <Container key={index}>
                <TouchableTile
                  onPress={() =>
                    handleSettingChange(
                      value as boolean,
                      key as ReminderPreferences,
                      PreferencesEnum.Reminder
                    )
                  }
                  leftElement={
                    <Switch
                      onValueChange={() => {
                        handleSettingChange(
                          value as boolean,
                          key as ReminderPreferences,
                          PreferencesEnum.Reminder
                        );
                      }}
                      value={value as boolean}
                      circleSize={18}
                    />
                  }
                  shapeVariant="square"
                  variant="text"
                  isHoverAllowed={false}
                  py="xs"
                  titleVariant="caption"
                  titleColor="title"
                  title={remindersTitle[key as ReminderPreferences]}
                  underlayColor={'transparent'}
                />
              </Container>
            );
          })}
      </Container>

      <Container>
        <Text my="s" variant="caption">
          BLOCKS AND COMMENTS
        </Text>
        {localBlockMentions &&
          Object.entries(localBlockMentions).map(([key, value], index) => {
            return (
              <Container key={index}>
                <TouchableTile
                  onPress={() =>
                    handleSettingChange(
                      value as boolean,
                      key as BlockMentionPreferences,
                      PreferencesEnum.BlockMention
                    )
                  }
                  leftElement={
                    <Switch
                      onValueChange={() => {
                        handleSettingChange(
                          value as boolean,
                          key as BlockMentionPreferences,
                          PreferencesEnum.BlockMention
                        );
                      }}
                      value={value as boolean}
                      circleSize={18}
                    />
                  }
                  shapeVariant="square"
                  variant="text"
                  isHoverAllowed={false}
                  py="xs"
                  titleVariant="caption"
                  titleColor="title"
                  title={blockMentionTitle[key as BlockMentionPreferences]}
                  underlayColor={'transparent'}
                />
              </Container>
            );
          })}

        {localBlockMessages &&
          Object.entries(localBlockMessages).map(([key, value], index) => {
            return (
              <Container key={index}>
                <TouchableTile
                  onPress={() =>
                    handleSettingChange(
                      value as boolean,
                      key as BlockMessagesPreferences,
                      PreferencesEnum.BlockMessage
                    )
                  }
                  leftElement={
                    <Switch
                      onValueChange={() => {
                        handleSettingChange(
                          value as boolean,
                          key as BlockMessagesPreferences,
                          PreferencesEnum.BlockMessage
                        );
                      }}
                      value={value as boolean}
                      circleSize={18}
                    />
                  }
                  shapeVariant="square"
                  variant="text"
                  isHoverAllowed={false}
                  py="xs"
                  titleVariant="caption"
                  titleColor="title"
                  title={blockMessagesTitle[key as BlockMessagesPreferences]}
                  underlayColor={'transparent'}
                />
              </Container>
            );
          })}
      </Container>

      <Container>
        <Text my="s" variant="caption">
          OTHER
        </Text>
        {localOther &&
          Object.entries(localOther).map(([key, value], index) => {
            return (
              <Container key={index}>
                <TouchableTile
                  onPress={() =>
                    handleSettingChange(
                      value as boolean,
                      key as OtherPreferences,
                      PreferencesEnum.Other
                    )
                  }
                  leftElement={
                    <Switch
                      onValueChange={() => {
                        handleSettingChange(
                          value as boolean,
                          key as OtherPreferences,
                          PreferencesEnum.Other
                        );
                      }}
                      value={value as boolean}
                      circleSize={18}
                    />
                  }
                  shapeVariant="square"
                  variant="text"
                  isHoverAllowed={false}
                  py="xs"
                  titleVariant="caption"
                  titleColor="title"
                  title={otherTitle[key as OtherPreferences]}
                  underlayColor={'transparent'}
                />
              </Container>
            );
          })}
      </Container>
    </Container>
  );
};

type NotificationType = 'push' | 'email';

type NotificationsProps = {
  handleUpdate: (profile: MyProfileFragment) => void;
  variant: NotificationType;
};
