import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../services/formation_generator.dart'; import '../data/league_data.dart'; import '../data/cardtype_data.dart'; import 'result_screen.dart'; import '../models/player.dart'; import 'pool_screen.dart'; const allRoles = [ 'GK', 'CB', 'LSB', 'RSB', 'DMF', 'CMF', 'OMF', 'LMF', 'RMF', 'CF', 'ST', 'RWG', 'LWG', ]; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { static const _poolKey = 'player_pool_v1'; ConstraintMode _mode = ConstraintMode.playstyle; bool _rareStyleOn = false; String? _selectedLeague; String? _selectedCardType; // 保存対象:選手プール List> _playerPool = []; // ★チムスタ重み(0〜100の重み。合計は気にしない) final Map _teamStyleWeights = { 'ポゼッション': 50, 'ショートカウンター': 50, 'ロングカウンター': 50, 'サイドアタック': 50, 'ロングボール': 50, }; @override void initState() { super.initState(); _loadPool(); } Future _loadPool() async { final prefs = await SharedPreferences.getInstance(); final raw = prefs.getString(_poolKey); if (raw == null || raw.isEmpty) return; try { final decoded = jsonDecode(raw) as List; setState(() { _playerPool = decoded .map((e) => { 'name': (e['name'] ?? '').toString(), 'positions': List.from(e['positions'] ?? const []), }) .toList(); }); } catch (_) { // 破損時は無視 } } Future _savePool() async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_poolKey, jsonEncode(_playerPool)); } Future _openPoolManager() async { // Map -> Player final currentPlayers = _playerPool.map((m) => Player.fromMap(m)).toList(); final updated = await Navigator.push>( context, MaterialPageRoute( builder: (_) => PoolScreen(initial: currentPlayers), ), ); if (updated != null) { final mapped = updated.map((p) => p.toMap()).toList(); setState(() => _playerPool = mapped); await _savePool(); } } // ★チムスタスライダー部品 Widget _teamStyleSlider(String label) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$label : ${_teamStyleWeights[label]}', style: const TextStyle(color: Colors.white), ), Slider( value: (_teamStyleWeights[label] ?? 0).toDouble(), min: 0, max: 100, divisions: 100, onChanged: (v) => setState(() { _teamStyleWeights[label] = v.round(); }), ), ], ); } void _goResult() { Navigator.push( context, MaterialPageRoute( builder: (_) => ResultScreen( mode: _mode, rareStyleOn: _rareStyleOn, selectedLeague: _selectedLeague, selectedCardType: _selectedCardType, playerPool: _playerPool, teamStyleWeights: _teamStyleWeights, // ★追加:Resultへ渡す ), ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.green[900], appBar: AppBar( title: const Text('efootball スカッドメーカー'), backgroundColor: Colors.green[900], actions: [ IconButton( onPressed: _openPoolManager, icon: const Icon(Icons.people_alt), tooltip: '選手プール', ), ], ), body: ListView( padding: const EdgeInsets.all(12), children: [ Row( children: [ Expanded( child: Text( '登録選手: ${_playerPool.length}人', style: const TextStyle(color: Colors.white70), ), ), TextButton( onPressed: _openPoolManager, child: const Text('選手プール'), ), ], ), const SizedBox(height: 8), DropdownButtonFormField( value: _mode, decoration: const InputDecoration( labelText: '遊び方(縛り)', filled: true, ), items: const [ DropdownMenuItem( value: ConstraintMode.playstyle, child: Text('プレースタイル縛り'), ), DropdownMenuItem( value: ConstraintMode.league, child: Text('リーグ縛り'), ), DropdownMenuItem( value: ConstraintMode.cardType, child: Text('カードタイプ縛り'), ), DropdownMenuItem( value: ConstraintMode.pool, child: Text('選手プール抽選'), ), ], onChanged: (v) { if (v == null) return; setState(() { _mode = v; if (_mode != ConstraintMode.league) _selectedLeague = null; if (_mode != ConstraintMode.cardType) _selectedCardType = null; }); }, ), const SizedBox(height: 10), if (_mode == ConstraintMode.playstyle) SwitchListTile( title: const Text( '希少なプレースタイルを出したい時にON', style: TextStyle(color: Colors.white), ), value: _rareStyleOn, onChanged: (v) => setState(() => _rareStyleOn = v), ), if (_mode == ConstraintMode.league) DropdownButtonFormField( value: _selectedLeague, decoration: const InputDecoration( labelText: 'リーグ(ランダム=ポジション別)', filled: true, ), items: [ const DropdownMenuItem( value: null, child: Text('ランダム'), ), ...leagues.map( (l) => DropdownMenuItem(value: l, child: Text(l)), ), ], onChanged: (v) => setState(() => _selectedLeague = v), ), if (_mode == ConstraintMode.cardType) DropdownButtonFormField( value: _selectedCardType, decoration: const InputDecoration( labelText: 'カードタイプ(ランダム=ポジション別)', filled: true, ), items: [ const DropdownMenuItem( value: null, child: Text('ランダム'), ), ...cardTypes.map( (c) => DropdownMenuItem(value: c, child: Text(c)), ), ], onChanged: (v) => setState(() => _selectedCardType = v), ), // ★チムスタ確率UI const SizedBox(height: 12), const Text( 'チームスタイル確率(重み)', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), ), _teamStyleSlider('ポゼッション'), _teamStyleSlider('ショートカウンター'), _teamStyleSlider('ロングカウンター'), _teamStyleSlider('サイドアタック'), _teamStyleSlider('ロングボール'), const SizedBox(height: 14), ElevatedButton.icon( onPressed: _goResult, icon: const Icon(Icons.arrow_forward), label: const Text('結果を見る(抽選)'), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.green[900], padding: const EdgeInsets.symmetric(vertical: 14), ), ), ], ), ); } }