# See https://zulip.readthedocs.io/en/latest/subsystems/hotspots.html
# for documentation on this subsystem.
from typing import Dict, List

from django.conf import settings
from django.utils.translation import ugettext as _

from zerver.models import UserHotspot, UserProfile

ALL_HOTSPOTS: Dict[str, Dict[str, str]] = {
    'intro_reply': {
        'title': _('Reply to a message'),
        'description': _('Click anywhere on a message to reply.'),
    },
    'intro_streams': {
        'title': _('Catch up on a stream'),
        'description': _('Messages sent to a stream are seen by everyone subscribed '
                         'to that stream. Try clicking on one of the stream links below.'),
    },
    'intro_topics': {
        'title': _('Topics'),
        'description': _('Every message has a topic. Topics keep conversations '
                         'easy to follow, and make it easy to reply to conversations that start '
                         'while you are offline.'),
    },
    'intro_gear': {
        'title': _('Settings'),
        'description': _('Go to Settings to configure your '
                         'notifications and display settings.'),
    },
    'intro_compose': {
        'title': _('Compose'),
        'description': _('Click here to start a new conversation. Pick a topic '
                         '(2-3 words is best), and give it a go!'),
    },
}

def get_next_hotspots(user: UserProfile) -> List[Dict[str, object]]:
    # For manual testing, it can be convenient to set
    # ALWAYS_SEND_ALL_HOTSPOTS=True in `zproject/dev_settings.py` to
    # make it easy to click on all of the hotspots.  Note that
    # ALWAYS_SEND_ALL_HOTSPOTS has some bugs; see ReadTheDocs (link
    # above) for details.
    if settings.ALWAYS_SEND_ALL_HOTSPOTS:
        return [{
            'name': hotspot,
            'title': ALL_HOTSPOTS[hotspot]['title'],
            'description': ALL_HOTSPOTS[hotspot]['description'],
            'delay': 0,
        } for hotspot in ALL_HOTSPOTS]

    if user.tutorial_status == UserProfile.TUTORIAL_FINISHED:
        return []

    seen_hotspots = frozenset(UserHotspot.objects.filter(user=user).values_list('hotspot', flat=True))
    for hotspot in ['intro_reply', 'intro_streams', 'intro_topics', 'intro_gear', 'intro_compose']:
        if hotspot not in seen_hotspots:
            return [{
                'name': hotspot,
                'title': ALL_HOTSPOTS[hotspot]['title'],
                'description': ALL_HOTSPOTS[hotspot]['description'],
                'delay': 0.5,
            }]

    user.tutorial_status = UserProfile.TUTORIAL_FINISHED
    user.save(update_fields=['tutorial_status'])
    return []

def copy_hotpots(source_profile: UserProfile, target_profile: UserProfile) -> None:
    for userhotspot in frozenset(UserHotspot.objects.filter(user=source_profile)):
        UserHotspot.objects.create(user=target_profile, hotspot=userhotspot.hotspot,
                                   timestamp=userhotspot.timestamp)

    target_profile.tutorial_status = source_profile.tutorial_status
    target_profile.onboarding_steps = source_profile.onboarding_steps
    target_profile.save(update_fields=['tutorial_status', 'onboarding_steps'])

@@ -211,16 +211,21 @@
 ugettext
+_lazy
  as _%0A%0Af
@@ -1847,32 +1847,36 @@
        'title': 
+str(
 ALL_HOTSPOTS%5Bhot
@@ -1881,32 +1881,33 @@
 otspot%5D%5B'title'%5D
+)
 ,%0A            'd
@@ -1911,32 +1911,36 @@
  'description': 
+str(
 ALL_HOTSPOTS%5Bhot
@@ -1951,32 +1951,33 @@
 %5D%5B'description'%5D
+)
 ,%0A            'd
@@ -2431,16 +2431,20 @@
 title': 
+str(
 ALL_HOTS
@@ -2465,16 +2465,17 @@
 'title'%5D
+)
 ,%0A      
@@ -2499,16 +2499,20 @@
 ption': 
+str(
 ALL_HOTS
@@ -2539,16 +2539,17 @@
 iption'%5D
+)
 ,%0A      

Use ugettext_lazy for i18n.