import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'device_service.dart';
import '../secrets.dart';

/// ライセンス状態
enum LicenseStatus {
  /// 無料版（AI解析は1日50回まで利用可能）
  free,

  /// Pro版ライセンス有効（Pro機能すべて解放）
  pro,

  /// ライセンス無効化済み（不正利用・返金等）
  revoked,

  /// オフライン / サーバー疎通不可（キャッシュ利用）
  offline,
}

/// ライセンス管理サービス
///
/// ## 状態管理の優先順位
/// 1. オンライン時: VPSに問い合わせた結果を使用 + SharedPreferencesにキャッシュ
/// 2. オフライン時: SharedPreferencesのキャッシュを使用 (Pro状態を維持)
///
/// ## ライセンスキー形式
/// PONSHU-XXXX-XXXX-XXXX (6バイト = 12hex文字, 大文字)
class LicenseService {
  static const _prefLicenseKey    = 'ponshu_license_key';
  static const _prefCachedStatus  = 'ponshu_license_status_cache';
  static const _prefCachedAt      = 'ponshu_license_cached_at';
  static const _cacheValidSeconds = 24 * 60 * 60; // 24時間キャッシュ有効

  // ========== Public API ==========

  /// アプリ起動時に呼ぶ: ライセンス状態を確認して返す
  static Future<LicenseStatus> checkStatus() async {
    final prefs    = await SharedPreferences.getInstance();
    final savedKey = prefs.getString(_prefLicenseKey) ?? '';

    // ライセンスキーが保存済み → サーバーで検証
    if (savedKey.isNotEmpty) {
      try {
        final status = await _validateKeyWithServer(savedKey);
        if (status == LicenseStatus.offline) {
          // ネットワーク不通: キャッシュを上書きせずに返す
          debugPrint('[License] Server unreachable, using cache');
          return _getCachedStatus(prefs);
        }
        await _cacheStatus(prefs, status);
        return status;
      } catch (e) {
        debugPrint('[License] Server unreachable, using cache: $e');
        return _getCachedStatus(prefs);
      }
    }

    // ライセンスキーなし → 無料版
    return LicenseStatus.free;
  }

  /// ライセンスキーをアクティベートする
  ///
  /// 成功: true + 空メッセージ
  /// 失敗: false + エラーメッセージ
  static Future<({bool success, String message})> activate(String rawKey) async {
    final key = rawKey.trim().toUpperCase();

    if (!_isValidKeyFormat(key)) {
      return (success: false, message: 'キーの形式が正しくありません\n(例: PONSHU-XXXX-XXXX-XXXX)');
    }

    final status = await _validateKeyWithServer(key);

    if (status == LicenseStatus.pro) {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString(_prefLicenseKey, key);
      await _cacheStatus(prefs, LicenseStatus.pro);
      debugPrint('[License] Activated successfully.');
      return (success: true, message: '');
    }

    if (status == LicenseStatus.revoked) {
      return (success: false, message: 'このライセンスは無効化されています。\nサポートにお問い合わせください。');
    }

    if (status == LicenseStatus.offline) {
      return (success: false, message: 'サーバーに接続できませんでした。\nネットワーク接続を確認してください。');
    }

    return (success: false, message: 'ライセンスキーが見つかりません。\nご購入時のメールをご確認ください。');
  }

  /// ライセンスキーがローカルに保存されているか
  static Future<bool> hasLicenseKey() async {
    final prefs = await SharedPreferences.getInstance();
    return (prefs.getString(_prefLicenseKey) ?? '').isNotEmpty;
  }

  /// ライセンスをリセット（デバッグ用）
  static Future<void> reset() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_prefLicenseKey);
    await prefs.remove(_prefCachedStatus);
    await prefs.remove(_prefCachedAt);
    debugPrint('[License] Reset complete.');
  }

  // ========== Private Helpers ==========

  static bool _isValidKeyFormat(String key) {
    final regex = RegExp(r'^PONSHU-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}$');
    return regex.hasMatch(key);
  }

  static Future<LicenseStatus> _validateKeyWithServer(String key) async {
    try {
      final deviceId = await DeviceService.getDeviceId();
      final response = await http.post(
        Uri.parse('${Secrets.posimaiBaseUrl}/api/ponshu/license/validate'),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'license_key': key, 'device_id': deviceId}),
      ).timeout(const Duration(seconds: 15));

      final data = jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;

      if (data['valid'] == true) return LicenseStatus.pro;
      if ((data['error'] as String? ?? '').contains('無効化')) return LicenseStatus.revoked;
      return LicenseStatus.free;

    } catch (e) {
      debugPrint('[License] Validation network error: $e');
      return LicenseStatus.offline;
    }
  }

  static Future<void> _cacheStatus(SharedPreferences prefs, LicenseStatus status) async {
    await prefs.setString(_prefCachedStatus, status.name);
    await prefs.setString(_prefCachedAt, DateTime.now().toIso8601String());
  }

  static LicenseStatus _getCachedStatus(SharedPreferences prefs) {
    final cached  = prefs.getString(_prefCachedStatus);
    final cachedAt = prefs.getString(_prefCachedAt);

    if (cached == null) return LicenseStatus.free;

    // キャッシュが古すぎる場合はfreeにフォールバック
    // pro と revoked は期限切れにしない（proは購入者を締め出さない、revokedは誤って復活させない）
    if (cachedAt != null) {
      final age = DateTime.now().difference(DateTime.parse(cachedAt));
      final isPermanentStatus = cached == LicenseStatus.pro.name || cached == LicenseStatus.revoked.name;
      if (age.inSeconds > _cacheValidSeconds && !isPermanentStatus) {
        return LicenseStatus.free;
      }
    }

    // Pro キャッシュはオフラインでも維持（購入者を締め出さない）
    return LicenseStatus.values.firstWhere(
      (s) => s.name == cached,
      orElse: () => LicenseStatus.free,
    );
  }
}
