import 'dart:convert';

import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:get/get.dart';
import 'package:vitalapp/architecture/storage/text_storage.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vitalapp/store/store.dart';

import 'interfaces/models/organization.dart';
import 'interfaces/organization.dart';

class OrganizationManager implements IOrganizationManager {
  static const _fileName = "organization.conf";
  final _storage = TextStorage(directory: "/configs", fileName: _fileName);
  OrganizationConfigurations? _cache;

  @override
  Future<OrganizationConfigurations> getConfigurations() async {
    _cache ??= await _loadConfig();
    return _cache ?? OrganizationConfigurations();
  }

  @override
  Future<OrganizationConfigurations> syncConfigurations() async {
    final config = OrganizationConfigurations();
    config.dynamicParams = await _getDynamicParams();
    // TODO: add other org configs

    await _save2File(config);
    _cache = config;
    return config;
  }

  @override
  Future<DynamicParameterDTO?> getDynamicParamByKey(String key) async {
    final config = await getConfigurations();
    final param = config.dynamicParams.firstWhereOrNull((e) => e.key == key);
    return param;
  }

  Future<OrganizationConfigurations?> _loadConfig() async {
    try {
      final jsonText = await _storage.read();
      if (jsonText != null) {
        final jsonMap = jsonDecode(jsonText);
        final config = OrganizationConfigurations().fromJson(jsonMap);
        return config;
      } else {
        return syncConfigurations();
      }
    } catch (e) {
      logger.e("OrganizationManager - Save config to file error.", e);
      return null;
    }
  }

  Future<List<DynamicParameterDTO>> _getDynamicParams() async {
    try {
      final request = GetDynamicParameterRequest(
        token: Store.user.token,
        organizationCode: Store.user.organizationCode,
      );
      final result = await rpc.organization.getDynamicParameterAsync(request);
      return result;
    } catch (e) {
      logger.e("OrganizationManager - GetDynamicParameter error.", e);
      return [];
    }
  }

  Future<bool> _save2File(OrganizationConfigurations config) async {
    try {
      final jsonMap = config.toJson();
      final jsonText = jsonEncode(jsonMap);
      final result = await _storage.save(jsonText);
      return result;
    } catch (e) {
      logger.e("OrganizationManager - Save config to file error.", e);
      return false;
    }
  }
}
