/*
 * @author lsy
 * @date   2019-09-02
 **/
import 'dart:math';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/src/builder/build_step.dart';
import 'package:gmalpha_flutter/Annotations/anno/User.dart';
import 'package:gmalpha_flutter/Annotations/anno/UserCenter.dart';
import 'package:gmalpha_flutter/Annotations/base/RouterBuildItem.dart';
import 'package:source_gen/source_gen.dart';

import '../RouterCenterRestore.dart';

Map<String, String> map = {};

class UserGenerator extends GeneratorForAnnotation<UserCenter> {
  @override
  generateForAnnotatedElement(
      Element element, ConstantReader annotation, BuildStep buildStep) {

    StringBuffer buffer = new StringBuffer();
    for (var fieldData in (element as ClassElement).fields) {
      for (var annometadata in fieldData.metadata) {
        final metadata = annometadata.computeConstantValue();
//        final metadatatype = annometadata.runtimeType;
//        print("metadatatype is $metadatatype");
//        print("metadataNAME is ${metadata.type.name}");
//        print("element is $element");
        if (element is! ClassElement) {
          throw InvalidGenerationSourceError(
              "Request class is not ok for ${element.displayName}");
        }

        if (metadata.type.name == "User") {
          String key = metadata.getField("key").toStringValue();
          var field = metadata.getField("type");
          var type = field.type.name;
          if (type == "String") {
            buffer.write("""
            String _${fieldData.name};
            Observable<bool> save${fieldData.name}(String ${fieldData.name}){
              return Observable.fromFuture(mmKvUtil.saveStringKv("${key}",${fieldData.name}))
              .map((value){
                if(value){
                  this._${fieldData.name}=${fieldData.name};
                }
                return value;
              });
            }
            Observable<String> get${fieldData.name}(){
              if(_${fieldData.name}!=null){
                return Observable.fromFuture(Future.value(_${fieldData.name}));
              }
              return Observable.fromFuture(mmKvUtil.getStringKv("${key}"));
            }
            """);
          } else if (type == "int") {
            buffer.write("""
            int _${fieldData.name};
            Observable<bool> save${fieldData.name}(int ${fieldData.name}){
              return Observable.fromFuture(mmKvUtil.saveIntKv("${key}",${fieldData.name}))
              .map((value){
                 if(value){
                  this._${fieldData.name}=${fieldData.name};
                 }
                 return value;
              });
            }
            Observable<int> get${fieldData.name}(){
              if(_${fieldData.name}!=null){
                return Observable.fromFuture(Future.value(_${fieldData.name}));
              }
              return Observable.fromFuture(mmKvUtil.getIntKv("${key}"));
            }
            """);
          } else if (type == "double") {
            buffer.write("""
            double _${fieldData.name};
            Observable<bool> save${fieldData.name}(double ${fieldData.name}){
              return Observable.fromFuture(mmKvUtil.saveDoubleKv("${key}",${fieldData.name}))
              .map((value){
                if(value){
                  this._${fieldData.name}=${fieldData.name};
                }
                return value;
              });
            }
            Observable<double> get${fieldData.name}(){
              if(_${fieldData.name}!=null){
                return Observable.fromFuture(Future.value(_${fieldData.name}));
              }
              return Observable.fromFuture(mmKvUtil.getDoubleKv("${key}"));
            }
            """);
          } else if (type == "bool") {
            buffer.write("""
            bool _${fieldData.name};
            Observable<bool> save${fieldData.name}(bool ${fieldData.name}){
              return Observable.fromFuture(mmKvUtil.saveBoolKv("${key}",${fieldData.name}))
              .map((value){
                if(value){
                  this._${fieldData.name}=${fieldData.name};
                }
                return value;
              });
            }
            Observable<bool> get${fieldData.name}(){
              if(_${fieldData.name}!=null){
                return Observable.fromFuture(Future.value(_${fieldData.name}));
              }
              return Observable.fromFuture(mmKvUtil.getBoolKv("${key}"));
            }
            """);
          }
        }
      }
    }

    return """
      import 'package:rxdart/rxdart.dart';
      import 'package:${buildStep.inputId.package}/commonModel/app_module.dart';
      
      class ${element.displayName}Impl{
      
        factory ${element.displayName}Impl() => _sharedInstance();

        static ${element.displayName}Impl _instance;

        ${element.displayName}Impl._() {
        }

        static ${element.displayName}Impl _sharedInstance() {
          if (_instance == null) {
            _instance = ${element.displayName}Impl._();
          }
          return _instance;
        }
      
        ${buffer.toString()}
      }
    """;
  }
}
