import 'dart:io';

import 'package:fis_common/env/env.dart';
import 'package:fis_common/extensions/string.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/architecture/values/store_keys.dart';
import 'package:path_provider/path_provider.dart';

import 'shared_storage.dart';

/// 文本存储(持久化)
abstract class TextStorage {
  TextStorage({
    required this.fileName,
  });

  /// 文件名
  final String fileName;

  /// 保存文本文件
  Future<bool> save(String text) async {
    try {
      return await _innerSave(text);
    } catch (e) {
      logger.e("Text storage save fail, platform: ${FPlatform.current}.", e);
      return false;
    }
  }

  /// 保存文件文本
  Future<String?> fetch() async {
    try {
      return await _innerFetch();
    } catch (e) {
      logger.e("Text storage fetch fail, platform: ${FPlatform.current}.", e);
      return null;
    }
  }

  Future<bool> _innerSave(String text);
  Future<String?> _innerFetch();

  /// 创建实例
  ///
  /// [fileName] 文件名
  static TextStorage createInstance(String fileName) {
    final platform = FPlatform.current;
    switch (platform) {
      case FPlatformEnum.android:
      case FPlatformEnum.iOS:
        return _TextStorageNative(fileName);
      case FPlatformEnum.webOnMac:
      case FPlatformEnum.webOnWin:
        return _TextStorageShellWeb(fileName);
      case FPlatformEnum.web:
        return _TextStoragePureWeb(fileName);
    }
  }
}

///本地文本缓存
class _TextStorageNative extends TextStorage {
  _TextStorageNative(String fileName) : super(fileName: fileName);

  @override
  Future<String?> _innerFetch() async {
    final filePath = await _getStoragePath();
    final file = File(filePath);
    if (!await file.exists()) return null;
    final text = await file.readAsString();
    // logger.i("Text storage fetched: $text");
    return text;
  }

  @override
  Future<bool> _innerSave(String text) async {
    // logger.i("Text storage save: $text");
    final filePath = await _getStoragePath();
    final file = File(filePath);
    if (!await file.exists()) {
      logger.i("file did not exists run await file.create()");
      await file.create();
    }
    await file.writeAsString(text);
    logger.i("Text storage save end");
    return true;
  }

  Future<String> _getStoragePath() async {
    Directory? dir;
    if (Platform.isAndroid) {
      dir = await getExternalStorageDirectory();
    }
    if (dir == null) {
      dir = await getApplicationDocumentsDirectory();
    }
    logger.i("_getStoragePath Text storage path: ${dir.path}/$fileName");
    return "${dir.path}/$fileName";
  }
}

///壳子下的缓存
class _TextStorageShellWeb extends TextStorage {
  _TextStorageShellWeb(String fileName) : super(fileName: fileName);

  @override
  Future<String?> _innerFetch() async {
    return await rpc.platform.getText(this.fileName);
  }

  @override
  Future<bool> _innerSave(String text) async {
    return await rpc.platform.saveText(this.fileName, text);
  }
}

///纯web端的缓存
class _TextStoragePureWeb extends TextStorage {
  _TextStoragePureWeb(String fileName) : super(fileName: fileName);

  @override
  Future<String?> _innerFetch() async {
    final storeKey = _getStoreKey();
    final data = SharedStorageService.ins.getString(storeKey);
    return data;
  }

  @override
  Future<bool> _innerSave(String text) async {
    final storeKey = _getStoreKey();
    final saved = await SharedStorageService.ins.setString(storeKey, text);
    return saved;
  }

  String _getStoreKey() => StoreKeys.STORE_TEXTDATA_GEN.format([this.fileName]);
}
