import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';

import 'package:wz_location_plugin/config/location_option.dart';
import 'package:wz_location_plugin/wz_location_plugin.dart';
import 'package:wz_location_plugin/wz_location_plugin_scenario.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  final _wzLocationPlugin = WzLocationPlugin();
  final _apiKeyController = TextEditingController(
    text: 'YOUR_API_KEY',
  );
  final _logBuffer = StringBuffer();
  StreamSubscription<Map<String, Object?>>? _onLocationChangedSub;

  @override
  void initState() {
    super.initState();
    initPlatformState();
    _onLocationChangedSub = _wzLocationPlugin.onLocationChanged().listen(
          (event) => _log('onLocationChanged: $event'),
          onError: (Object e, StackTrace st) => _log('onLocationChanged error: $e'),
        );
  }

  @override
  void dispose() {
    _onLocationChangedSub?.cancel();
    _apiKeyController.dispose();
    super.dispose();
  }

  Future<void> initPlatformState() async {
    String platformVersion;
    try {
      platformVersion = await _wzLocationPlugin.getPlatformVersion() ?? 'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  void _log(String line) {
    final stamped = '${DateTime.now().toIso8601String()} $line\n';
    setState(() {
      _logBuffer.write(stamped);
    });
    debugPrint(stamped.trimRight());
  }

  Future<void> _run(String label, Future<void> Function() action) async {
    try {
      await action();
      _log('$label → success');
    } on PlatformException catch (e) {
      _log('$label → PlatformException: ${e.code} ${e.message}');
    } catch (e) {
      _log('$label → error: $e');
    }
  }

  SetApiKey() {
    WzLocationPlugin().setLocationOption(
      WzLocationOption(
        apiKey: '你的 apiKey', //官网获取
        interval: 5000,//定位时间间隔，单位毫秒
        isLocateOnce: false,//是否是单次定位
      ),
    );
  }

  String get _apiKey => _apiKeyController.text.trim();

  Future<void> _onSetApiKey() async {
    if (_apiKey.isEmpty || _apiKey == 'YOUR_API_KEY') {
      _log('setApiKey: 请在输入框中填写真实 apiKey');
      return;
    }
    await _run('setApiKey', () => _wzLocationPlugin.setApiKey(_apiKey));
  }

  Future<void> _onPrivacyShow() async {
    await _run(
      'updatePrivacyShow',
      () => WzLocationPlugin.updatePrivacyShow(true, false),
    );
  }

  Future<void> _onPrivacyAgree() async {
    await _run(
      'updatePrivacyAgree',
      () => WzLocationPlugin.updatePrivacyAgree(true),
    );
  }

  Future<void> _onSetLocationOption() async {
    if (_apiKey.isEmpty || _apiKey == 'YOUR_API_KEY') {
      _log('setLocationOption: 请先填写 apiKey');
      return;
    }
    await _run(
      'setLocationOption',
      () => _wzLocationPlugin.setLocationOption(
        WzLocationOption(
          apiKey: _apiKey,
          interval: 5000,
          isLocateOnce: false,
        ),
      ),
    );
  }

  /// 运行时定位权限：Android 6+ 必需；iOS 需在 Info.plist 配置用途说明，且 Podfile 需启用
  /// `PERMISSION_LOCATION=1`（见 ios/Podfile），否则 [permission_handler] 状态可能不准。
  Future<bool> _ensureLocationPermissionForStart() async {
    // iOS 上「使用期间」比 Permission.location（可能混合 Always）更符合示例场景；
    // iOS 14+ 仅授权「大致位置」时为 [limited]，仍应允许尝试启动定位。
    if (Platform.isIOS || Platform.isAndroid) {
    } else {
      return true;
    }
    const permission = Permission.locationWhenInUse;
    var status = await permission.status;
    if (!status.isGranted && !status.isLimited) {
      status = await permission.request();
    }
    if (status.isGranted || status.isLimited) {
      return true;
    }
    if (status.isPermanentlyDenied) {
      _log('无法在应用内再次弹出定位授权，请到系统设置中为该应用开启「位置」权限后重试');
      await openAppSettings();
    } else if (status.isRestricted) {
      _log('定位权限受系统限制（如屏幕使用时间/企业管理），无法在应用内授予');
    } else {
      _log('定位权限未授予，Wayz 定位通常无法回调（请允许使用期间定位）');
    }
    return false;
  }

  Future<void> _onStartLocation(bool isLocateOnce) async {
    if (!await _ensureLocationPermissionForStart()) {
      return;
    }
    await _onStopLocation();
    await _run(
      'setLocationOption',
      () => _wzLocationPlugin.setLocationOption(
        WzLocationOption(
          apiKey: _apiKey,
          interval: 5000,
          isLocateOnce: isLocateOnce,
        ),
      ),
    );
    await _run('startLocation', _wzLocationPlugin.startLocation);
  }

  Future<void> _onStopLocation() async {
    await _run('stopLocation', _wzLocationPlugin.stopLocation);
  }

  Future<void> _onGeocodeHttp() async {
    if (_apiKey.isEmpty || _apiKey == 'xxx') {
      _log('HTTP geocode: 请填写真实 apiKey');
      return;
    }
    await _run('HTTP geocode', () async {

      final r = await WzLocationPlugin().geocode(address: '武汉市洪山区关山大道');
      _log('HTTP geocode → ${r.name} ${r.geoPoint}');
    });
  }

  Future<void> _onReverseGeocodeHttp() async {
    if (_apiKey.isEmpty || _apiKey == 'xxx') {
      _log('HTTP reverseGeocode: 请填写真实 apiKey');
      return;
    }
    await _run('HTTP reverseGeocode', () async {

      final r = await WzLocationPlugin().reverseGeocode(
        asset: 'demo-${DateTime.now().millisecondsSinceEpoch}',
        longitude: 121.60441,
        latitude: 31.179716,
        locationSpatialReference: 'gcj02',
        source: 'wifi',
        accuracy: 2.0,
      );
      final addr = r.location.address?.name ?? '(no address)';
      _log('HTTP reverseGeocode → $addr');
    });
  }

  Future<void> _onPoiKeywordHttp() async {
    if (_apiKey.isEmpty || _apiKey == 'xxx') {
      _log('HTTP POI keyword: 请填写真实 apiKey');
      return;
    }
    await _run('HTTP POI keyword', () async {

      final list = await WzLocationPlugin().searchPoiByKeyword(
        name: '咖啡',
        cityCode: '310000',
      );
      _log('HTTP POI keyword → count=${list.length} first=${list.isEmpty ? '-' : list.first.name}');
    });
  }

  Future<void> _onPoiNearbyHttp() async {
    if (_apiKey.isEmpty || _apiKey == 'xxx') {
      _log('HTTP POI nearby: 请填写真实 apiKey');
      return;
    }
    await _run('HTTP POI nearby', () async {

      final list = await WzLocationPlugin().searchPoiNearby(
        longitude: 121.4737,
        latitude: 31.2304,
        radiusMeters: 2000,
        keywords: '餐厅',
        orderBy: 'distance_score',
      );
      _log('HTTP POI nearby → count=${list.length} first=${list.isEmpty ? '-' : list.first.name}');
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('wz_location_plugin example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Text('Running on: $_platformVersion'),
              const SizedBox(height: 12),
              TextField(
                controller: _apiKeyController,
                decoration: const InputDecoration(
                  labelText: 'ApiKey',
                  border: OutlineInputBorder(),
                ),
              ),
              const SizedBox(height: 12),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: [
                  FilledButton(
                    onPressed: _onSetApiKey,
                    child: const Text('setApiKey'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onPrivacyShow,
                    child: const Text('privacyShow'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onPrivacyAgree,
                    child: const Text('privacyAgree'),
                  ),
                  FilledButton(
                    onPressed: _onSetLocationOption,
                    child: const Text('setLocationOption'),
                  ),
                  FilledButton(
                    onPressed: () async {
                      _onStartLocation(true);
                    },
                    child: const Text('单次定位（会先请求定位权限）'),
                  ),
                  FilledButton(
                    onPressed: () {
                      _onStartLocation(false);
                    },
                    child: const Text('连续定位（会先请求定位权限）'),
                  ),
                  FilledButton(
                    onPressed: _onStopLocation,
                    child: const Text('stopLocation'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onGeocodeHttp,
                    child: const Text('HTTP 正地理编码'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onReverseGeocodeHttp,
                    child: const Text('HTTP 逆地理编码'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onPoiKeywordHttp,
                    child: const Text('HTTP POI 关键词'),
                  ),
                  FilledButton.tonal(
                    onPressed: _onPoiNearbyHttp,
                    child: const Text('HTTP POI 周边'),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              const Text('调用日志（含原生返回或异常）：'),
              Expanded(
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    border: Border.all(color: Theme.of(context).dividerColor),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.all(8),
                    child: SelectableText(
                      _logBuffer.isEmpty ? '尚无日志' : _logBuffer.toString(),
                      style: const TextStyle(fontFamily: 'monospace', fontSize: 12),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
