// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';

import '../../gallery/demo.dart';

const List<String> _defaultMaterialsA = <String>[
  'poker',
  'tortilla',
  'fish and',
  'micro',
  'wood',
];

const List<String> _defaultMaterialsB = <String>[
  'apple',
  'orange',
  'tomato',
  'grape',
  'lettuce',
];

const List<String> _defaultActions = <String>[
  'flake',
  'cut',
  'fragment',
  'splinter',
  'nick',
  'fry',
  'solder',
  'cash in',
  'eat',
];

const Map<String, String> _results = <String, String>{
  'flake': 'flaking',
  'cut': 'cutting',
  'fragment': 'fragmenting',
  'splinter': 'splintering',
  'nick': 'nicking',
  'fry': 'frying',
  'solder': 'soldering',
  'cash in': 'cashing in',
  'eat': 'eating',
};

const List<String> _defaultToolsA = <String>[
  'hammer',
  'chisel',
  'fryer',
  'fabricator',
  'customer',
];

const List<String> _defaultToolsB = <String>[
  'keyboard',
  'mouse',
  'monitor',
  'printer',
  'cable',
];

const Map<String, String> _avatars = <String, String>{
  'hammer': 'people/square/ali.png',
  'chisel': 'people/square/sandra.png',
  'fryer': 'people/square/trevor.png',
  'fabricator': 'people/square/stella.png',
  'customer': 'people/square/peter.png',
};

const Map<String, Set<String>> _toolActions = <String, Set<String>>{
  'hammer': <String>{'flake', 'fragment', 'splinter'},
  'chisel': <String>{'flake', 'nick', 'splinter'},
  'fryer': <String>{'fry'},
  'fabricator': <String>{'solder'},
  'customer': <String>{'cash in', 'eat'},
};

const Map<String, Set<String>> _materialActions = <String, Set<String>>{
  'poker': <String>{'cash in'},
  'tortilla': <String>{'fry', 'eat'},
  'fish and': <String>{'fry', 'eat'},
  'micro': <String>{'solder', 'fragment'},
  'wood': <String>{'flake', 'cut', 'splinter', 'nick'},
};

class _ChipsTile extends StatelessWidget {
  const _ChipsTile({
    Key? key,
    this.label,
    this.children,
  }) : super(key: key);

  final String? label;
  final List<Widget>? children;

  // Wraps a list of chips into a ListTile for display as a section in the demo.
  @override
  Widget build(BuildContext context) {
    return Card(
      semanticContainer: false,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            padding: const EdgeInsets.only(top: 16.0, bottom: 4.0),
            alignment: Alignment.center,
            child: Text(label!, textAlign: TextAlign.start),
          ),
          if (children!.isNotEmpty)
            Wrap(
              children: children!.map<Widget>((Widget chip) {
                return Padding(
                  padding: const EdgeInsets.all(2.0),
                  child: chip,
                );
              }).toList(),
            )
          else
            Semantics(
              container: true,
              child: Container(
                alignment: Alignment.center,
                constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
                padding: const EdgeInsets.all(8.0),
                child: Text('None', style: Theme.of(context).textTheme.caption!.copyWith(fontStyle: FontStyle.italic)),
              ),
            ),
        ],
      ),
    );
  }
}

class ChipDemo extends StatefulWidget {
  const ChipDemo({Key? key}) : super(key: key);

  static const String routeName = '/material/chip';

  @override
  State<ChipDemo> createState() => _ChipDemoState();
}

class _ChipDemoState extends State<ChipDemo> {
  _ChipDemoState() {
    _reset();
  }

  final Set<String> _materialsA = <String>{};
  final Set<String> _materialsB = <String>{};
  String _selectedMaterial = '';
  String _selectedAction = '';
  final Set<String> _toolsA = <String>{};
  final Set<String> _toolsB = <String>{};
  final Set<String> _selectedTools = <String>{};
  final Set<String> _actions = <String>{};
  bool _showShapeBorder = false;

  // Initialize members with the default data.
  void _reset() {
    _materialsA.clear();
    _materialsA.addAll(_defaultMaterialsA);
    _materialsB.clear();
    _materialsB.addAll(_defaultMaterialsB);
    _actions.clear();
    _actions.addAll(_defaultActions);
    _toolsA.clear();
    _toolsA.addAll(_defaultToolsA);
    _toolsB.clear();
    _toolsB.addAll(_defaultToolsB);
    _selectedMaterial = '';
    _selectedAction = '';
    _selectedTools.clear();
  }

  void _removeMaterial(String name) {
    _materialsA.remove(name);
    _materialsB.remove(name);
    if (_selectedMaterial == name) {
      _selectedMaterial = '';
    }
  }

  void _removeTool(String name) {
    _toolsA.remove(name);
    _toolsB.remove(name);
    _selectedTools.remove(name);
  }

  String _capitalize(String name) {
    assert(name.isNotEmpty);
    return name.substring(0, 1).toUpperCase() + name.substring(1);
  }

  // This converts a String to a unique color, based on the hash value of the
  // String object.  It takes the bottom 16 bits of the hash, and uses that to
  // pick a hue for an HSV color, and then creates the color (with a preset
  // saturation and value).  This means that any unique strings will also have
  // unique colors, but they'll all be readable, since they have the same
  // saturation and value.
  Color _nameToColor(String name, ThemeData theme) {
    assert(name.length > 1);
    final int hash = name.hashCode & 0xffff;
    final double hue = (360.0 * hash / (1 << 15)) % 360.0;
    final double themeValue = HSVColor.fromColor(theme.backgroundColor).value;
    return HSVColor.fromAHSV(1.0, hue, 0.4, themeValue).toColor();
  }

  AssetImage _nameToAvatar(String name) {
    assert(_avatars.containsKey(name));
    return AssetImage(
      _avatars[name]!,
      package: 'flutter_gallery_assets',
    );
  }

  String _createResult() {
    if (_selectedAction.isEmpty) {
      return '';
    }
    final String value = _capitalize(_results[_selectedAction]!);
    return '$value!';
  }

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final List<Widget> chips = _materialsA.map<Widget>((String name) {
      return Chip(
        key: ValueKey<String>(name),
        backgroundColor: _nameToColor(name, theme),
        label: Text(_capitalize(name)),
        onDeleted: () {
          setState(() {
            _removeMaterial(name);
          });
        },
      );
    }).toList();

    final List<Widget> inputChips = _toolsA.map<Widget>((String name) {
      return InputChip(
          key: ValueKey<String>(name),
          avatar: CircleAvatar(
            backgroundImage: _nameToAvatar(name),
          ),
          label: Text(_capitalize(name)),
          onDeleted: () {
            setState(() {
              _removeTool(name);
            });
          });
    }).toList();

    final List<Widget> choiceChips = _materialsB.map<Widget>((String name) {
      return ChoiceChip(
        key: ValueKey<String>(name),
        backgroundColor: _nameToColor(name, theme),
        label: Text(_capitalize(name)),
        selected: _selectedMaterial == name,
        onSelected: (bool value) {
          setState(() {
            _selectedMaterial = value ? name : '';
          });
        },
      );
    }).toList();

    final List<Widget> filterChips = _toolsB.map<Widget>((String name) {
      return FilterChip(
        key: ValueKey<String>(name),
        label: Text(_capitalize(name)),
        selected: _toolsB.contains(name) && _selectedTools.contains(name),
        onSelected: !_toolsB.contains(name)
            ? null
            : (bool value) {
                setState(() {
                  if (!value) {
                    _selectedTools.remove(name);
                  } else {
                    _selectedTools.add(name);
                  }
                });
              },
      );
    }).toList();

    Set<String> allowedActions = <String>{};
    if (_selectedMaterial.isNotEmpty) {
      for (final String tool in _selectedTools) {
        allowedActions.addAll(_toolActions[tool]!);
      }
      allowedActions = allowedActions.intersection(_materialActions[_selectedMaterial]!);
    }

    final List<Widget> actionChips = allowedActions.map<Widget>((String name) {
      return ActionChip(
        label: Text(_capitalize(name)),
        onPressed: () {
          setState(() {
            _selectedAction = name;
          });
        },
      );
    }).toList();

    final List<Widget> tiles = <Widget>[
      const SizedBox(height: 8.0, width: 0.0),
      _ChipsTile(label: 'Available Materials (Chip)', children: chips),
      _ChipsTile(label: 'Available Tools (InputChip)', children: inputChips),
      _ChipsTile(label: 'Choose a Material (ChoiceChip)', children: choiceChips),
      _ChipsTile(label: 'Choose Tools (FilterChip)', children: filterChips),
      _ChipsTile(label: 'Perform Allowed Action (ActionChip)', children: actionChips),
      const Divider(),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: Text(
            _createResult(),
            style: theme.textTheme.headline6,
          ),
        ),
      ),
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Chips'),
        actions: <Widget>[
          MaterialDemoDocumentationButton(ChipDemo.routeName),
          IconButton(
            onPressed: () {
              setState(() {
                _showShapeBorder = !_showShapeBorder;
              });
            },
            icon: const Icon(Icons.vignette, semanticLabel: 'Update border shape'),
          ),
        ],
      ),
      body: ChipTheme(
        data: _showShapeBorder
            ? theme.chipTheme.copyWith(
                shape: BeveledRectangleBorder(
                side: const BorderSide(width: 0.66, color: Colors.grey),
                borderRadius: BorderRadius.circular(10.0),
              ))
            : theme.chipTheme,
        child: Scrollbar(child: ListView(children: tiles)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(_reset),
        child: const Icon(Icons.refresh, semanticLabel: 'Reset chips'),
      ),
    );
  }
}
