from datetime import datetime

from zoneinfo import ZoneInfo

from django.core.management import call_command
from django.core.management.base import BaseCommand

from core.models import Assembly, Conference, StaticPage, StaticPageNamespace

NS_INTRO = '_intro_'
INTRO_PAGES = {
    'assemblies': {
        'title': {
            'de': 'Was ist das hier?',
            'en': 'What is this place?',
        },
        'text': {
            'de': 'Hier findest du alle Assemblies, die dieses Jahr dabei sind.',
            'en': 'Here you can find all the assemblies taking part this year.',
        },
    },
    'assemblies_events': {
        'title': {
            'de': 'Assembly Vorträge',
            'en': 'Assembly Events',
        },
        'text': {
            'de': 'Schau dir an, was die Assemblies vorhaben!',
            'en': 'See what the assemblies are up to!',
        },
    },
    'badges': {
        'title': {
            'de': 'Was sind Badges?',
            'en': 'What are badges?',
        },
        'text': {
            'de': 'Hier findest du eine Liste der Badges, die von Assemblies erstellt wurden und die du während dieser Veranstaltung finden könntest.\r\nAssemblies können neue Badges im Backoffice erstellen!',  # noqa: E501
            'en': 'Here you can find a list of badges that assemblies have created and that you may find during this event.\r\nAssemblies can create new badges in the backoffice!',  # noqa: E501
        },
    },
    'projects': {
        'title': {
            'de': 'Was sind Projekte?',
            'en': 'What are projects?',
        },
        'text': {
            'de': 'Assemblies und auch Einzelpersonen stellen hier Projekte vor, an denen sie arbeiten. Schau dir die Liste an und füge vielleicht selbst eines hinzu?',  # noqa: E501
            'en': "Assemblies and individual people like to highlight projects they are working on. Here you'll find a list, consider adding your fancy project?",  # noqa: E501
        },
    },
    'reportcontent': {
        'title': {
            'de': 'DIES IST KEIN KONTAKTFORMULAR',
            'en': 'THIS IS NOT A CONTACT FORM',
        },
        'text': {
            'de': 'Diese Funktion ist dafür gedacht, bösartigen und/oder illegalen Inhalt zu melden. Sie ist nicht dafür gedacht, Änderungen im Wiki zu beantragen oder allgemeine Fragen zu beantworten. Dafür kontaktiere bitte die Orga. Danke!',  # noqa: E501
            'en': 'This function is intended to report malicious and/or illegal contents. It is not meant to request changes in wiki pages or ask questions. For that please contact the orga. Thanks!',  # noqa: E501
        },
    },
    'sos': {
        'title': {
            'de': 'Was ist das hier?',
            'en': 'What ist das hier?',
        },
        'text': {
            'de': 'Hier kannst du selbst organisierte Vorträge und Workshops sehen. Vielleicht möchtest du selbst etwas anbieten?',  # noqa: E501
            'en': 'Here you can find sessions and workshops which are hosted by individuals. You might host your own?',
        },
    },
}


def seed_conference(conf: Conference, year: int = 0, force: bool = False):
    if Assembly.objects.filter(conference=conf).exists():
        raise ValueError('Conference already has assemblies?!')

    # create info block namespace and texts
    StaticPageNamespace.objects.create(conference=conf, prefix=NS_INTRO, groups=['hubteam'])
    for page_slug, page_data in INTRO_PAGES.items():
        for lang in ['de', 'en']:
            title = page_data['title'][lang]
            text = page_data['text'][lang]
            page = StaticPage.objects.create(
                conference=conf,
                slug=f'{NS_INTRO}{page_slug}',
                language=lang,
                title=title,
                protection=StaticPage.Protection.PERM,
                privacy=StaticPage.Privacy.NONE,
            )
            rev = page.revisions.create(body=text, title=title)
            rev.set_public()

    # create SoS assembly
    conf.self_organized_sessions_assembly = Assembly.objects.create(
        conference=conf,
        slug='sos',
        name='Self Organized Sessions',
        is_official=True,
        state_assembly=Assembly.State.HIDDEN,
        state_channel=Assembly.State.NONE,
    )

    # create navigation (top level)
    nav_conf = conf.nav_items.create(
        label_de='Konferenz',
        title_de='Offizielle Informationen, Tipps & Tricks zur Veranstaltung',
        label_en='Conference',
        title_en='official information, tips & tricks for the event',
        index=10,
    )
    nav_visitors = conf.nav_items.create(
        label_de='Besucher',
        title_de='Nützliche Links',
        label_en='visitors',
        title_en='helpful links',
        index=15,
    )
    nav_my = conf.nav_items.create(
        label_de='Mein Congress',
        title_de='personalisiertes Erlebnis',
        label_en='my congress',
        title_en='personalized experience',
        index=100,
    )

    entries = [
        # (parent, index, icon, label_de, label_en, title_de, title_en, url)
        (
            nav_conf,
            10,
            'rocket-takeoff',
            'Willkommen',
            'Welcome',
            'Startseite',
            'start page',
            'conference://index',
        ),
        (
            nav_conf,
            19,
            'calendar-event',
            'Events (Jetzt)',
            'events (now)',
            'das Vortragsprogramm als Liste',
            'talks, workshops and other events in list view',
            'conference://fahrplan?mode=list#now',
        ),
        (
            nav_conf,
            20,
            'calendar-week',
            'Fahrplan',
            'Schedule',
            'das Vortragsprogramm',
            'talks, workshops and other events',
            'conference://fahrplan',
        ),
        (
            nav_conf,
            21,
            'person-video3',
            'Self-organized Sessions',
            'Self-organized Sessions',
            'Workshops oder Diskussionsrunden in Assemblies oder den Workshopräumen',
            'workshops or discussions in Assemblies or workshop rooms',
            'conference://sos',
        ),
        (
            nav_conf,
            22,
            'lightning',
            'Lightning Talks',
            'lightning talks',
            'Deine fünf Minuten des Ruhms!',
            'Give a short introduction on a topic',
            'https://c3lt.de/',
        ),
        (
            nav_conf,
            50,
            'camera-reels',
            'Streams',
            'Streams',
            'Live-Streams der Vorträge',
            'live streaming of talks',
            'https://streaming.media.ccc.de/%SLUG%/',
        ),
        (
            nav_conf,
            110,
            'book',
            'Wiki',
            'Wiki',
            'gemeinsames Wissen',
            'shared knowledge',
            'wiki://start',
        ),
        (
            nav_conf,
            111,
            'book',
            'Letzte Änderungen (Wiki)',
            'Recent changes (Wiki)',
            'gemeinsames Wissen',
            'shared knowledge',
            'conference://static_page_global_history',
        ),
        (
            nav_conf,
            120,
            'person-arms-up',
            'Assemblies',
            'Assemblies',
            'Gruppen von Personen die dabei sind',
            'groups of people you can meet',
            'conference://assemblies',
        ),
        (
            nav_conf,
            300,
            'lightbulb',
            'Projekte',
            'Projects',
            None,
            None,
            'conference://projects',
        ),
        (
            nav_conf,
            400,
            'award',
            'Badges',
            'Badges',
            "Schnapp' sie dir alle!",
            'Gotta find them all!',
            'conference://badges',
        ),
        (
            nav_conf,
            9001,
            'wrench',
            'Maschinenraum',
            'Backoffice',
            'Assemblies, Events, etc. verwalten',
            'Manage Assemblies, Events, etc.',
            'conference://backoffice',
        ),
        (
            nav_my,
            10,
            'shield',
            'Meine Badges',
            'My Badges',
            'entdecke den Congress',
            'explore the congress',
            'conference://manage_badges',
        ),
        (
            nav_my,
            200,
            'stars',
            'Mein Fahrplan',
            'My Schedule',
            'favorisierte Vorträge',
            'your favorite events',
            'conference://fahrplan?mode=list&my=y&kind=all',
        ),
        (
            nav_visitors,
            10,
            'ticket-perforated',
            'Tickets',
            'Tickets',
            'Wie? Wann? Wo?',
            'how? when? where?',
            'https://events.ccc.de/congress/%YEAR%/infos/tickets.html',
        ),
        (
            nav_visitors,
            15,
            'buildings',
            'Gebäude',
            'Venue',
            'Wie benutzen wir das Gebäude',
            'How we use the venue',
            'wiki://venue',
        ),
        (
            nav_visitors,
            20,
            'clipboard-fill',
            'Bulletin Board',
            'Bulletin Board',
            'ein digitales schwarzes Brett: suche und finde Dinge',
            'a digital board: search & find stuff',
            'conference://board',
        ),
        (
            nav_visitors,
            30,
            'patch-question',
            'FAQ',
            'FAQ',
            'häufig gestellte Fragen',
            'frequently asked questions',
            'https://events.ccc.de/congress/%YEAR%/infos/fundamentals-and-faq.html',
        ),
    ]

    def customize(s):
        return (s or '').replace('%SLUG%', conf.slug).replace('%YEAR%', str(year))

    for parent, index, icon, label_de, label_en, title_de, title_en, url in entries:
        if not year and '%YEAR%' in url:
            continue
        parent.children.create(
            conference=conf,
            index=index,
            icon=icon,
            label_de=customize(label_de),
            label_en=customize(label_en),
            title_de=customize(title_de),
            title_en=customize(title_en),
            url=customize(url),
        )


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('slug', type=str, nargs='?')
        parser.add_argument('--name', type=str)
        parser.add_argument('--year', type=int)
        parser.add_argument('--bootstrap', action='store_true')

    def handle(self, *args, **options):
        if not (slug := options.get('slug')):
            slug = input('SLUG of the new conference, e.g. "42c3": ')
        if not (name := options.get('name')):
            name = input('NAME of the new conference (long title): ')
        if not (year := options.get('year')):
            year = input("YEAR of the CCC congress (leave empty if it's something else): ")
        year = int(year or '0')

        print(f'Creating conference {slug} ({name}) for year {year}')

        # load our bootstrap fixtures
        if options.get('bootstrap'):
            call_command('loaddata', 'bootstrap_auth_groups.json')

        # create the new conference
        conf = Conference.objects.create(
            slug=slug,
            name=name,
            is_public=True,
        )

        # for CCC Jahresendveranstaltung we can guess some timestamps from the current year alone
        if year > 1970:
            conf.start = datetime(year, 12, 27, 10, 0, 0, tzinfo=ZoneInfo('Europe/Berlin'))
            conf.end = datetime(year, 12, 30, 18, 0, 0, tzinfo=ZoneInfo('Europe/Berlin'))
            conf.registration_deadline = datetime(year, 12, 1, 0, 0, 0, tzinfo=ZoneInfo('Europe/Berlin'))

        # save everything
        conf.save()
        self.stdout.write(self.style.SUCCESS(f'Created conference {conf.pk}'))

        # fill in initial data
        seed_conference(conf, year=year)
        self.stdout.write(self.style.SUCCESS(f'Initial data set up for "{conf.slug}"'))