import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

import '../consts.dart';
import '../data_classes.dart';

/// ChoroplethMap is a stateful widget that contains a choropleth map.
/// The map is created using the Syncfusion Flutter Maps library and
/// coordinates fetched from the server.
class ChoroplethMap extends StatefulWidget {
  const ChoroplethMap({
    Key? key,
    required this.relation,
    required this.measurements,
    required this.subdivisions,
    required this.onSelectionChanged,
  }) : super(key: key);

  final Uint8List relation;
  final List<Measurement> measurements;
  final List<SubDiv> subdivisions;
  final void Function(int selectedIndex) onSelectionChanged;

  @override
  ChoroplethMapState createState() => ChoroplethMapState();
}

class ChoroplethMapState extends State<ChoroplethMap> {
  int selectedIndex = -1;            // Subdivision/map tile index
  late MapShapeSource dataSource;
  late final MapZoomPanBehavior _zoomPanBehavior = MapZoomPanBehavior();

  void updateDataSource() {
    _initDataSource();
  }

  @override
  void initState() {
    super.initState();
      _initDataSource();
    }

    void _initDataSource() {
      dataSource = MapShapeSource.memory(
        widget.relation,
        shapeDataField: 'sub_div_id',
        dataCount: widget.subdivisions.length,
        primaryValueMapper: (int index) => widget.subdivisions[index].sub_div_id,
        shapeColorValueMapper: (int index) => widget.subdivisions[index].avgThickness, // NB will later be minThickness
        shapeColorMappers: const [
          MapColorMapper(
              from: 0,
              to: 4,
              color: Color(0xffff0000),
              text: '{0},{1}'),
          MapColorMapper(
              from: 4,
              to: 8,
              color: Color(0xffff6a00),
              text: '2'),
          MapColorMapper(
              from: 8,
              to: 12,
              color: Color(0xFFb1ff00),
              text: '3'),
          MapColorMapper(
              from: 12,
              to: 400,
              color: Color(0xFF00d6ff),
              text: '4'),
          ],
      );
  }

  @override
  Widget build(BuildContext context) {
    updateDataSource();

    return Stack(
      children: [
        SfMapsTheme(
          data: SfMapsThemeData( // Coloring of selected shape
            selectionStrokeWidth: 3.5,
            selectionStrokeColor: Colors.blue[600],
          ),
          child: SfMaps(
            layers: [
              MapShapeLayer(
                source: dataSource,
                legend: MapLegend.bar(
                    MapElement.shape,
                    position: MapLegendPosition.bottom,
                    segmentSize: const Size(70.0, 7.0),
                    textStyle: smallTextStyle,
                ),
                zoomPanBehavior: _zoomPanBehavior,
                strokeColor: Colors.blue.shade50,
                strokeWidth: 1,
                // Shape selection
                selectedIndex: selectedIndex,
                onSelectionChanged: (int index) {
                  setState(() {
                    selectedIndex = index;
                  });
                  widget.onSelectionChanged(selectedIndex);
                },
              ),
            ],
          ),
        ),
      ],
    );
  }
}