import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_pickers/address_picker/locations_data.dart';
import 'package:path/path.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite/sqflite.dart';

import '../models/region.dart';

class RegionProvider extends ChangeNotifier {
  RegionProvider() {
    loadRegionData();
  }

  String _provinceName = '';
  String _cityName = '';
  String _tempProvinceName = '';
  String _tempCityName = '';
  double _declination = 0.0;
  double _tempDeclination = 0.0;

  Database db;

  String get provinceName => _provinceName;

  String get cityName => _cityName;

  String get tempProvinceName => _tempProvinceName;

  String get tempCityName => _tempCityName;

  double get tempDeclination => _tempDeclination;

  double get declination => _declination;

  final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  loadRegionData() async {
    db = await loadDatabase();
    final prefs = await _prefs;
    if (prefs.getString('REGION') != null) {
      final region = RegionData.fromJson(jsonDecode(prefs.getString('REGION')));
      _provinceName = region.provinceName;
      _cityName = region.cityName;
      _tempProvinceName = region.provinceName;
      _tempCityName = region.cityName;
      // WidgetsFlutterBinding.ensureInitialized();
      List<String> cityCode = Address.getCityCodeByName(
          provinceName: _provinceName, cityName: _cityName);
      if (cityCode.length == 2) {
        List<Map<String, Object>> decMap = await db.rawQuery(
            "SELECT declination FROM magnetic_declination WHERE cityId == ${cityCode[1]}");
        _declination = decMap[0]['declination'];
        _tempDeclination = decMap[0]['declination'];
      } else {
        _declination = 0.0;
        _tempDeclination = 0.0;
      }

      notifyListeners();
    }
  }

  Future<Database> loadDatabase() async {
    var databasesPath = await getDatabasesPath();
    var path = join(databasesPath, "magnetic_declination.db");
    var exists = await databaseExists(path);
    if (!exists) {
      print("Creating new copy from asset");
      try {
        await Directory(dirname(path)).create(recursive: true);
      } catch (_) {}
      // Copy from asset
      ByteData data =
          await rootBundle.load(join("assets", "magnetic_declination.db"));
      List<int> bytes =
          data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
      // Write and flush the bytes written
      await File(path).writeAsBytes(bytes, flush: true);
    } else {
      print("Opening existing database");
    }
// open the database
    Database _db = await openDatabase(path, readOnly: true);
    return _db;
  }

  // 存储临时的省市名称，不会保存本地
  void updateRegion(pname, cname) async {
    _tempProvinceName = pname;
    _tempCityName = cname;
    List<String> cityCode = Address.getCityCodeByName(
        provinceName: _tempProvinceName, cityName: _tempCityName);
    print(cityCode);
    if (cityCode.length == 2) {
      List<Map<String, Object>> decMap = await db.rawQuery(
          "SELECT declination FROM magnetic_declination WHERE cityId == ${cityCode[1]}");
      print(decMap);
      _tempDeclination = decMap[0]['declination'];
    } else {
      _tempDeclination = 0.0;
    }
    notifyListeners();
  }

  //更新磁偏角
  void updateDeclination(pname, cname) {}

  //将临时变量保存到正式变量，并保存本地
  void saveRegion() {
    _provinceName = _tempProvinceName;
    _cityName = _tempCityName;
    _declination = _tempDeclination;
    print(_tempCityName);
    final region = <String, dynamic>{
      "provinceName": _tempProvinceName,
      'cityName': _tempCityName,
      // 'declination': _tempDeclination
    };
    _prefs.then((prefs) {
      prefs.setString('REGION', jsonEncode(region));
    });
    notifyListeners();
  }

  // 覆盖临时的变量
  void resetTemp() async {
    _tempProvinceName = _provinceName;
    _tempCityName = _cityName;
    _tempDeclination = _declination;
    notifyListeners();
  }

  // 将临时的省市名设为空
  void clearTemp() {
    _tempProvinceName = '';
    _tempCityName = '';
    _tempDeclination = 0.0;
    notifyListeners();
  }
}
