import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';

/// デバイスID取得サービス
/// レート制限・ライセンス管理のためのデバイス識別に使用
///
/// ## 安定性の保証
/// - Android: ANDROID_ID をハッシュ化して使用（Factory Reset まで不変）
/// - iOS: SharedPreferences に UUID を永続化（identifierForVendor は
///         全ベンダーアプリ削除後の再インストールで変わるため不使用）
/// - その他/エラー時: SharedPreferences に UUID を永続化
class DeviceService {
  static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
  static String? _cachedDeviceId;

  static const _prefKey = 'ponshu_device_id';

  /// デバイス固有のIDを取得（SHA256ハッシュ化）
  static Future<String> getDeviceId() async {
    if (_cachedDeviceId != null) return _cachedDeviceId!;

    final prefs = await SharedPreferences.getInstance();

    // SharedPreferencesに永続化済みならそれを使う（再インストール後も同じIDを返す）
    final stored = prefs.getString(_prefKey);
    if (stored != null && stored.isNotEmpty) {
      _cachedDeviceId = stored;
      debugPrint('[Device] Using persisted device ID: ${stored.substring(0, 8)}...');
      return _cachedDeviceId!;
    }

    // 初回: ハードウェアIDから生成してSharedPreferencesに保存
    final id = await _generateAndPersist(prefs);
    _cachedDeviceId = id;
    return id;
  }

  static Future<String> _generateAndPersist(SharedPreferences prefs) async {
    String deviceIdentifier;

    try {
      if (defaultTargetPlatform == TargetPlatform.android) {
        final info = await _deviceInfo.androidInfo;
        // ANDROID_ID: アプリ再インストールでは変わらない。Factory Resetで変わる。
        deviceIdentifier = 'android-${info.id}';
      } else {
        // iOS / その他: UUIDを生成して永続化
        // identifierForVendor は全ベンダーアプリ削除後の再インストールで変わるため不使用
        deviceIdentifier = 'uuid-${const Uuid().v4()}';
      }
    } catch (e) {
      debugPrint('[Device] Failed to get hardware ID, using UUID fallback: $e');
      deviceIdentifier = 'fallback-${const Uuid().v4()}';
    }

    final id = sha256.convert(utf8.encode(deviceIdentifier)).toString();
    await prefs.setString(_prefKey, id);
    debugPrint('[Device] Generated and persisted device ID: ${id.substring(0, 8)}...');
    return id;
  }

  /// デバイス情報をリセット（テスト用）
  static Future<void> reset() async {
    _cachedDeviceId = null;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_prefKey);
  }
}
