import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../modelos/gamificacion_usuario.dart';

class PerfilUsuario {
  final String nombre;
  final String nick;
  final String avatarAsset;

  const PerfilUsuario({
    required this.nombre,
    required this.nick,
    required this.avatarAsset,
  });

  PerfilUsuario copiar({String? nombre, String? nick, String? avatarAsset}) {
    return PerfilUsuario(
      nombre: nombre ?? this.nombre,
      nick: nick ?? this.nick,
      avatarAsset: avatarAsset ?? this.avatarAsset,
    );
  }
}

class ServicioPerfilUsuario extends ChangeNotifier {
  static const _claveNombre = 'perfil.nombre';
  static const _claveNick = 'perfil.nick';
  static const _claveAvatar = 'perfil.avatar';
  static const _claveEstadisticas = 'perfil.estadisticas';

  static const avatares = [
    'assets/avatars/avatar_01.png',
    'assets/avatars/avatar_02.png',
    'assets/avatars/avatar_03.png',
    'assets/avatars/avatar_04.png',
    'assets/avatars/avatar_05.png',
    'assets/avatars/avatar_06.png',
    'assets/avatars/avatar_07.png',
    'assets/avatars/avatar_08.png',
    'assets/avatars/avatar_09.png',
    'assets/avatars/avatar_10.png',
    'assets/avatars/avatar_11.png',
    'assets/avatars/avatar_12.png',
    'assets/avatars/avatar_13.png',
    'assets/avatars/avatar_14.png',
    'assets/avatars/avatar_15.png',
    'assets/avatars/avatar_16.png',
    'assets/avatars/avatar_17.png',
    'assets/avatars/avatar_18.png',
    'assets/avatars/avatar_19.png',
    'assets/avatars/avatar_20.png',
    'assets/avatars/avatar_21.png',
    'assets/avatars/avatar_22.png',
    'assets/avatars/avatar_23.png',
    'assets/avatars/avatar_24.png',
    'assets/avatars/avatar_25.png',
    'assets/avatars/avatar_26.png',
    'assets/avatars/avatar_27.png',
    'assets/avatars/avatar_28.png',
    'assets/avatars/avatar_29.png',
    'assets/avatars/avatar_30.png',
    'assets/avatars/avatar_79.png',
    'assets/avatars/avatar_80.png',
    'assets/avatars/avatar_81.png',
    'assets/avatars/avatar_82.png',
    'assets/avatars/avatar_83.png',
    'assets/avatars/avatar_84.png',
    'assets/avatars/avatar_31.png',
    'assets/avatars/avatar_32.png',
    'assets/avatars/avatar_33.png',
    'assets/avatars/avatar_34.png',
    'assets/avatars/avatar_35.png',
    'assets/avatars/avatar_36.png',
    'assets/avatars/avatar_37.png',
    'assets/avatars/avatar_38.png',
    'assets/avatars/avatar_39.png',
    'assets/avatars/avatar_40.png',
    'assets/avatars/avatar_41.png',
    'assets/avatars/avatar_42.png',
    'assets/avatars/avatar_43.png',
    'assets/avatars/avatar_44.png',
    'assets/avatars/avatar_45.png',
    'assets/avatars/avatar_46.png',
    'assets/avatars/avatar_47.png',
    'assets/avatars/avatar_48.png',
    'assets/avatars/avatar_49.png',
    'assets/avatars/avatar_50.png',
    'assets/avatars/avatar_51.png',
    'assets/avatars/avatar_52.png',
    'assets/avatars/avatar_53.png',
    'assets/avatars/avatar_54.png',
    'assets/avatars/avatar_55.png',
    'assets/avatars/avatar_56.png',
    'assets/avatars/avatar_57.png',
    'assets/avatars/avatar_58.png',
    'assets/avatars/avatar_59.png',
    'assets/avatars/avatar_60.png',
    'assets/avatars/avatar_61.png',
    'assets/avatars/avatar_62.png',
    'assets/avatars/avatar_63.png',
    'assets/avatars/avatar_64.png',
    'assets/avatars/avatar_65.png',
    'assets/avatars/avatar_66.png',
    'assets/avatars/avatar_67.png',
    'assets/avatars/avatar_68.png',
    'assets/avatars/avatar_69.png',
    'assets/avatars/avatar_70.png',
    'assets/avatars/avatar_71.png',
    'assets/avatars/avatar_72.png',
    'assets/avatars/avatar_73.png',
    'assets/avatars/avatar_74.png',
    'assets/avatars/avatar_75.png',
    'assets/avatars/avatar_76.png',
    'assets/avatars/avatar_77.png',
    'assets/avatars/avatar_78.png',
  ];

  PerfilUsuario _perfil = const PerfilUsuario(
    nombre: 'Jugador',
    nick: 'farolero',
    avatarAsset: 'assets/avatars/avatar_01.png',
  );
  EstadisticasPerfilUsuario _estadisticas =
      const EstadisticasPerfilUsuario();
  bool _cargado = false;

  PerfilUsuario get perfil => _perfil;
  EstadisticasPerfilUsuario get estadisticas => _estadisticas;
  ResumenGamificacionUsuario get resumenGamificacion => _estadisticas.resumen;
  bool get cargado => _cargado;

  Future<void> cargar() async {
    final prefs = await SharedPreferences.getInstance();
    _perfil = PerfilUsuario(
      nombre: prefs.getString(_claveNombre) ?? _perfil.nombre,
      nick: prefs.getString(_claveNick) ?? _perfil.nick,
      avatarAsset: prefs.getString(_claveAvatar) ?? _perfil.avatarAsset,
    );
    final estadisticasJson = prefs.getString(_claveEstadisticas);
    if (estadisticasJson != null) {
      try {
        _estadisticas = EstadisticasPerfilUsuario.fromJson(
          json.decode(estadisticasJson) as Map<String, dynamic>,
        );
      } catch (_) {
        _estadisticas = const EstadisticasPerfilUsuario();
      }
    }
    _cargado = true;
    notifyListeners();
  }

  Future<void> guardar({
    required String nombre,
    required String nick,
    required String avatarAsset,
  }) async {
    final nombreLimpio = nombre.trim().isEmpty ? 'Jugador' : nombre.trim();
    final nickLimpio = nick.trim().isEmpty ? 'farolero' : nick.trim();
    final avatarSeguro = avatares.contains(avatarAsset)
        ? avatarAsset
        : avatares.first;
    _perfil = PerfilUsuario(
      nombre: nombreLimpio,
      nick: nickLimpio,
      avatarAsset: avatarSeguro,
    );
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_claveNombre, _perfil.nombre);
    await prefs.setString(_claveNick, _perfil.nick);
    await prefs.setString(_claveAvatar, _perfil.avatarAsset);
    notifyListeners();
  }

  Future<ProgresoGamificacionUsuario> registrarPartidaCompletada({
    required bool victoria,
    bool comoImpostor = false,
    bool victoriaComoImpostor = false,
    DateTime? fecha,
  }) async {
    final antes = _estadisticas;
    final despues = antes.registrarPartida(
      victoria: victoria,
      comoImpostor: comoImpostor,
      victoriaComoImpostor: victoriaComoImpostor,
      fecha: fecha,
    );
    final medallasPrevias = antes.medallas.toSet();
    final nuevasMedallas = despues.medallas
        .where((id) => !medallasPrevias.contains(id))
        .toList(growable: false);

    _estadisticas = despues;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_claveEstadisticas, json.encode(despues.toJson()));
    notifyListeners();

    return ProgresoGamificacionUsuario(
      antes: antes,
      despues: despues,
      nuevasMedallas: nuevasMedallas,
    );
  }
}
