import 'dart:convert';

import 'package:yumi/shared/business_logic/models/res/follow_room_res.dart'
    as follow;
import 'package:yumi/shared/business_logic/models/res/join_room_res.dart'
    as join;
import 'package:yumi/shared/business_logic/models/res/my_room_res.dart';
import 'package:yumi/shared/business_logic/models/res/room_res.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';

class SCRoomProfileCache {
  static const String _prefix = "room_profile_override";

  static String _key(String roomId) {
    final userId =
        AccountStorage().getCurrentUser()?.userProfile?.id ?? "guest";
    return "${_prefix}_${userId}_$roomId";
  }

  static String? preferNonEmpty(String? primary, String? fallback) {
    if ((primary ?? "").trim().isNotEmpty) {
      return primary;
    }
    if ((fallback ?? "").trim().isNotEmpty) {
      return fallback;
    }
    return primary ?? fallback;
  }

  static String? preferCachedValue(String? cached, String? remote) {
    if ((cached ?? "").trim().isNotEmpty) {
      return cached;
    }
    return preferNonEmpty(remote, cached);
  }

  static Map<String, String> getRoomProfile(String roomId) {
    if (roomId.trim().isEmpty) {
      return {};
    }
    final raw = DataPersistence.getString(_key(roomId));
    if (raw.isEmpty) {
      return {};
    }
    try {
      final data = jsonDecode(raw);
      if (data is Map) {
        return data.map(
          (key, value) => MapEntry(key.toString(), value?.toString() ?? ""),
        );
      }
    } catch (_) {}
    return {};
  }

  static Future<void> saveRoomProfile({
    required String roomId,
    String? roomCover,
    String? roomName,
    String? roomDesc,
  }) async {
    if (roomId.trim().isEmpty) {
      return;
    }
    final current = getRoomProfile(roomId);
    final payload = <String, String>{
      "roomCover": preferNonEmpty(roomCover, current["roomCover"]) ?? "",
      "roomName": preferNonEmpty(roomName, current["roomName"]) ?? "",
      "roomDesc": preferNonEmpty(roomDesc, current["roomDesc"]) ?? "",
    };
    await DataPersistence.setString(_key(roomId), jsonEncode(payload));
  }

  static SocialChatRoomRes applyToSocialChatRoomRes(SocialChatRoomRes room) {
    final cache = getRoomProfile(room.id ?? "");
    if (cache.isEmpty) {
      return room;
    }
    return room.copyWith(
      roomCover: preferCachedValue(cache["roomCover"], room.roomCover),
      roomName: preferCachedValue(cache["roomName"], room.roomName),
      roomDesc: preferCachedValue(cache["roomDesc"], room.roomDesc),
    );
  }

  static follow.FollowRoomRes applyToFollowRoomRes(follow.FollowRoomRes room) {
    final roomProfile = room.roomProfile;
    if (roomProfile == null) {
      return room;
    }
    final cache = getRoomProfile(roomProfile.id ?? "");
    if (cache.isEmpty) {
      return room;
    }
    return room.copyWith(
      roomProfile: roomProfile.copyWith(
        roomCover: preferCachedValue(cache["roomCover"], roomProfile.roomCover),
        roomName: preferCachedValue(cache["roomName"], roomProfile.roomName),
        roomDesc: preferCachedValue(cache["roomDesc"], roomProfile.roomDesc),
      ),
    );
  }

  static MyRoomRes applyToMyRoomRes(MyRoomRes room) {
    final cache = getRoomProfile(room.id ?? "");
    if (cache.isEmpty) {
      return room;
    }
    return room.copyWith(
      roomCover: preferCachedValue(cache["roomCover"], room.roomCover),
      roomName: preferCachedValue(cache["roomName"], room.roomName),
      roomDesc: preferCachedValue(cache["roomDesc"], room.roomDesc),
    );
  }

  static join.JoinRoomRes applyToJoinRoomRes(join.JoinRoomRes room) {
    final roomProfile = room.roomProfile;
    final basicRoomProfile = roomProfile?.roomProfile;
    if (roomProfile == null || basicRoomProfile == null) {
      return room;
    }
    final cache = getRoomProfile(basicRoomProfile.id ?? "");
    if (cache.isEmpty) {
      return room;
    }
    return room.copyWith(
      roomProfile: roomProfile.copyWith(
        roomProfile: basicRoomProfile.copyWith(
          roomCover: preferCachedValue(
            cache["roomCover"],
            basicRoomProfile.roomCover,
          ),
          roomName: preferCachedValue(
            cache["roomName"],
            basicRoomProfile.roomName,
          ),
          roomDesc: preferCachedValue(
            cache["roomDesc"],
            basicRoomProfile.roomDesc,
          ),
        ),
      ),
    );
  }
}
