import '../../../model/account_data.dart';
import '../../marianumcloud/talk/chat/get_chat_response.dart';
import '../../marianumcloud/talk/room/get_room_response.dart';
import '../demo_persona.dart';

/// Fixtures for the Talk module while [DemoMode] is active: a curated set of
/// rooms plus a believable German conversation per room. Room tokens are the
/// join between [rooms] and [chat] — they must stay in sync.
class DemoTalk {
  const DemoTalk._();

  static const String tokenClass = 'demo-klasse-10b';
  static const String tokenMathLk = 'demo-mathe-lk';
  static const String tokenWeber = 'demo-herr-weber';
  static const String tokenWeimar = 'demo-weimar';
  static const String tokenSv = 'demo-sv';

  static GetRoomResponse rooms() {
    return GetRoomResponse({
      _room(
        id: 100,
        token: tokenClass,
        type: GetRoomResponseObjectConversationType.group,
        name: 'Klasse 10b',
        displayName: 'Klasse ${DemoPersona.className}',
        lastMessage: _lastOf(tokenClass),
        unreadMessages: 2,
        isFavorite: true,
      ),
      _room(
        id: 200,
        token: tokenMathLk,
        type: GetRoomResponseObjectConversationType.group,
        name: 'Mathe-LK',
        displayName: 'Mathe-LK · Herr Müller',
        lastMessage: _lastOf(tokenMathLk),
      ),
      _room(
        id: 300,
        token: tokenWeber,
        type: GetRoomResponseObjectConversationType.oneToOne,
        name: 'weber',
        displayName: 'Herr Weber',
        lastMessage: _lastOf(tokenWeber),
        unreadMessages: 1,
      ),
      _room(
        id: 400,
        token: tokenWeimar,
        type: GetRoomResponseObjectConversationType.group,
        name: 'Fahrt nach Weimar',
        displayName: 'Fahrt nach Weimar 🚌',
        lastMessage: _lastOf(tokenWeimar),
      ),
      _room(
        id: 500,
        token: tokenSv,
        type: GetRoomResponseObjectConversationType.group,
        name: 'SV',
        displayName: 'SV – Schülervertretung',
        lastMessage: _lastOf(tokenSv),
      ),
    });
  }

  static GetChatResponse chat(String token) =>
      GetChatResponse(_messages(token).toSet());

  static GetChatResponseObject _lastOf(String token) => _messages(token).last;

  static List<GetChatResponseObject> _messages(String token) {
    switch (token) {
      case tokenClass:
        return _classChat();
      case tokenMathLk:
        return _mathLkChat();
      case tokenWeber:
        return _weberChat();
      case tokenWeimar:
        return _weimarChat();
      case tokenSv:
        return _svChat();
      default:
        return _genericChat(token);
    }
  }

  static List<GetChatResponseObject> _classChat() {
    const token = tokenClass;
    var base = 10000;
    return [
      _msg(
        id: base + 1,
        token: token,
        actor: 'sophie',
        display: 'Sophie',
        ago: const Duration(days: 1, hours: 4),
        message: 'Weiß jemand, was wir in Bio auf haben?',
      ),
      _msg(
        id: base + 2,
        token: token,
        actor: 'max',
        display: 'Max',
        ago: const Duration(days: 1, hours: 3, minutes: 55),
        message: 'S. 42 Nr. 3 und 4, glaube ich',
      ),
      _selfMsg(
        id: base + 3,
        token: token,
        ago: const Duration(days: 1, hours: 3, minutes: 50),
        message: 'Ja genau, und das Arbeitsblatt zur Zellteilung 🙌',
        reactions: {'👍': 3},
      ),
      _msg(
        id: base + 4,
        token: token,
        actor: 'jonas',
        display: 'Jonas',
        ago: const Duration(days: 1, hours: 3, minutes: 40),
        message: 'Danke euch! 🙏',
      ),
      _msg(
        id: base + 5,
        token: token,
        actor: 'emma',
        display: 'Emma',
        ago: const Duration(hours: 20),
        message: 'Ist die Mathe-Arbeit jetzt am Donnerstag oder Freitag?',
      ),
      _msg(
        id: base + 6,
        token: token,
        actor: 'mueller',
        display: 'Herr Müller',
        ago: const Duration(hours: 19, minutes: 30),
        message: 'Die Arbeit findet am Freitag in der 3. Stunde statt.',
      ),
      _msg(
        id: base + 7,
        token: token,
        actor: 'emma',
        display: 'Emma',
        ago: const Duration(hours: 19, minutes: 20),
        message: 'Danke, Herr Müller!',
      ),
      _msg(
        id: base + 8,
        token: token,
        actor: 'paul',
        display: 'Paul',
        ago: const Duration(hours: 6),
        message: 'Wer kommt morgen mit in die Mensa?',
      ),
      _msg(
        id: base + 9,
        token: token,
        actor: 'mia',
        display: 'Mia',
        ago: const Duration(hours: 5, minutes: 50),
        message: 'Ich bin dabei 🍕',
      ),
      _selfMsg(
        id: base + 10,
        token: token,
        ago: const Duration(hours: 5, minutes: 45),
        message: 'Ich auch!',
      ),
      _msg(
        id: base + 11,
        token: token,
        actor: 'sophie',
        display: 'Sophie',
        ago: const Duration(hours: 3),
        message:
            'Vergesst nicht, die Einverständniserklärung für Weimar abzugeben 🚌',
        reactions: {'👍': 5, '🚌': 2},
      ),
      _msg(
        id: base + 12,
        token: token,
        actor: 'ben',
        display: 'Ben',
        ago: const Duration(hours: 2, minutes: 10),
        message: 'Oh stimmt, hab ich fast vergessen 😅',
      ),
    ];
  }

  static List<GetChatResponseObject> _mathLkChat() {
    const token = tokenMathLk;
    var base = 20000;
    return [
      _msg(
        id: base + 1,
        token: token,
        actor: 'mueller',
        display: 'Herr Müller',
        ago: const Duration(days: 2, hours: 2),
        message:
            'Zur Vorbereitung auf die Arbeit findet ihr die Übungsblätter in den Dateien.',
      ),
      _selfMsg(
        id: base + 2,
        token: token,
        ago: const Duration(days: 1, hours: 6),
        message: 'Danke! Können wir Aufgabe 5 nächste Stunde nochmal besprechen?',
      ),
      _msg(
        id: base + 3,
        token: token,
        actor: 'mueller',
        display: 'Herr Müller',
        ago: const Duration(days: 1, hours: 5, minutes: 30),
        message: 'Klar, wir schauen uns die Kurvendiskussion gemeinsam an.',
        reactions: {'👍': 4},
      ),
      _msg(
        id: base + 4,
        token: token,
        actor: 'jonas',
        display: 'Jonas',
        ago: const Duration(hours: 8),
        message: 'Super, danke!',
      ),
    ];
  }

  static List<GetChatResponseObject> _weberChat() {
    const token = tokenWeber;
    var base = 30000;
    return [
      _selfMsg(
        id: base + 1,
        token: token,
        ago: const Duration(days: 1, hours: 2),
        message:
            'Guten Tag Herr Weber, ich war letzte Woche krank. Was muss ich in Englisch nachholen?',
      ),
      _msg(
        id: base + 2,
        token: token,
        actor: 'weber',
        display: 'Herr Weber',
        ago: const Duration(hours: 4),
        message:
            'Hallo Lena, gute Besserung! Lies bitte Unit 4 und bereite die Vokabeln vor.',
      ),
      _msg(
        id: base + 3,
        token: token,
        actor: 'weber',
        display: 'Herr Weber',
        ago: const Duration(hours: 3, minutes: 58),
        message: 'Die Präsentation kannst du nächste Woche nachholen.',
      ),
    ];
  }

  static List<GetChatResponseObject> _weimarChat() {
    const token = tokenWeimar;
    var base = 40000;
    return [
      _msg(
        id: base + 1,
        token: token,
        actor: 'wagner',
        display: 'Frau Wagner',
        ago: const Duration(days: 3),
        message:
            'Wir treffen uns am Montag um 7:45 Uhr am Haupteingang. Bitte pünktlich sein!',
        reactions: {'👍': 8},
      ),
      _msg(
        id: base + 2,
        token: token,
        actor: 'paul',
        display: 'Paul',
        ago: const Duration(days: 2, hours: 20),
        message: 'Wie lange sind wir ungefähr unterwegs?',
      ),
      _msg(
        id: base + 3,
        token: token,
        actor: 'wagner',
        display: 'Frau Wagner',
        ago: const Duration(days: 2, hours: 19),
        message: 'Etwa zwei Stunden mit dem Bus. Denkt an Verpflegung!',
      ),
      _selfMsg(
        id: base + 4,
        token: token,
        ago: const Duration(hours: 12),
        message: 'Freue mich schon! 🎉',
        reactions: {'🎉': 6},
      ),
    ];
  }

  static List<GetChatResponseObject> _svChat() {
    const token = tokenSv;
    var base = 50000;
    return [
      _msg(
        id: base + 1,
        token: token,
        actor: 'ben',
        display: 'Ben',
        ago: const Duration(days: 2, hours: 5),
        message: 'Nächste SV-Sitzung ist am Mittwoch in der großen Pause.',
      ),
      _msg(
        id: base + 2,
        token: token,
        actor: 'mia',
        display: 'Mia',
        ago: const Duration(days: 1, hours: 8),
        message: 'Können wir über den Ablauf vom Sommerfest sprechen?',
      ),
      _selfMsg(
        id: base + 3,
        token: token,
        ago: const Duration(hours: 9),
        message: 'Gute Idee, ich sammle schon mal Vorschläge.',
        reactions: {'👍': 3},
      ),
      _msg(
        id: base + 4,
        token: token,
        actor: 'ben',
        display: 'Ben',
        ago: const Duration(hours: 2),
        message:
            '## Ablauf Sommerfest\n'
            'Ein paar **Punkte** für Mittwoch:\n\n'
            '- Stände aufbauen ab *14 Uhr*\n'
            '- [x] Getränke bestellt\n'
            '- [ ] Musik organisieren\n\n'
            '> Bitte bringt Ideen mit!\n\n'
            'Mehr Infos auf der [SV-Seite](https://marianum-fulda.de).',
        markdown: true,
      ),
    ];
  }

  static List<GetChatResponseObject> _genericChat(String token) {
    return [
      _msg(
        id: 90001,
        token: token,
        actor: 'info',
        display: 'MarianumConnect',
        ago: const Duration(hours: 1),
        message: 'Willkommen im Demo-Chat 👋',
      ),
    ];
  }

  static GetChatResponseObject _selfMsg({
    required int id,
    required String token,
    required Duration ago,
    required String message,
    Map<String, int>? reactions,
    bool markdown = false,
  }) => _msg(
    id: id,
    token: token,
    actor: AccountData().getUsername(),
    display: DemoPersona.studentName,
    ago: ago,
    message: message,
    reactions: reactions,
    markdown: markdown,
  );

  static GetChatResponseObject _msg({
    required int id,
    required String token,
    required String actor,
    required String display,
    required Duration ago,
    required String message,
    Map<String, int>? reactions,
    bool markdown = false,
  }) => GetChatResponseObject(
    id,
    token,
    GetRoomResponseObjectMessageActorType.user,
    actor,
    display,
    _epoch(ago),
    '',
    GetRoomResponseObjectMessageType.comment,
    true,
    'demo-ref-$id',
    message,
    null,
    reactions,
    null,
    null,
    markdown,
  );

  static GetRoomResponseObject _room({
    required int id,
    required String token,
    required GetRoomResponseObjectConversationType type,
    required String name,
    required String displayName,
    required GetChatResponseObject lastMessage,
    int unreadMessages = 0,
    bool isFavorite = false,
  }) => GetRoomResponseObject(
    id,
    token,
    type,
    name,
    displayName,
    '',
    3,
    0,
    0,
    0,
    0,
    'demo-session-$id',
    false,
    false,
    0,
    false,
    false,
    true,
    lastMessage.timestamp,
    isFavorite,
    GetRoomResponseObjectParticipantNotificationLevel.defaultLevel,
    unreadMessages,
    false,
    false,
    lastMessage.id - unreadMessages,
    lastMessage.id,
    lastMessage,
    null,
    null,
    null,
  );

  static int _epoch(Duration ago) =>
      DateTime.now().subtract(ago).millisecondsSinceEpoch ~/ 1000;
}
