Pogrupujmy to wrzućmy nazwę grupy i każdą aktywność do dodatkowego kontenera który zawiera nazwę grupy + jakąś dopiske:

"Siła" "Bo trzema wyglądać męsko i żeby ci nie najebali" Treningi siłowe + Trening boksu

"Finanse" "Jakoś trzeba mieć pieniądze na to wszystko" Przepracowane dni + Zarobione pieniądze + (Dodaj dodatkowy cel którym jest "Nauka Tradingu")

"Edukacja" "Bo chyba chcesz mieć jakąś sensowniejsza prace niż zapierdalać za 20/h" Nauka INF04 + Nauka Matematyki + Nauka fizyki (dodaj to jako nowy cel)





import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'dart:convert'; // Import do kodowania/dekodowania JSON

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initializeDateFormatting(); // Inicjalizacja dla języka polskiego
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Timelapse App',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF6200EE),
          brightness: Brightness.dark,
          primary: const Color(0xFFBB86FC),
          secondary: const Color(0xFF03DAC6),
          tertiary: const Color(0xFF3700B3),
          surface: const Color(0xFF121212),
          background: const Color(0xFF121212),
        ),
        useMaterial3: true,
        fontFamily: 'Montserrat',
        scaffoldBackgroundColor: const Color(0xFF121212),
        cardTheme: CardTheme(
          elevation: 0,
          color: const Color(0xFF1E1E1E),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
          margin: const EdgeInsets.symmetric(vertical: 8),
        ),
        appBarTheme: const AppBarTheme(
          centerTitle: true,
          elevation: 0,
          backgroundColor: Color(0xFF1E1E1E),
          foregroundColor: Colors.white,
        ),
        tabBarTheme: const TabBarTheme(
          labelColor: Colors.white,
          unselectedLabelColor: Colors.grey,
          indicatorColor: Color(0xFFBB86FC),
        ),
        dialogTheme: const DialogTheme(
          backgroundColor: Color(0xFF1E1E1E),
          titleTextStyle: TextStyle(color: Colors.white),
          contentTextStyle: TextStyle(color: Colors.white),
        ),
        textTheme: const TextTheme(
          displayLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white),
          titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.w600, color: Colors.white),
          bodyLarge: TextStyle(fontSize: 16, color: Colors.white),
        ),
      ),
      home: const Timelaps(),
    );
  }
}

// =========================================================================
// KLASY MODELU DANYCH
// =========================================================================

// Klasa Goal - teraz z możliwością mutacji progress i maxProgress oraz serializacją
class Goal {
  String id; // Unikalny ID celu, np. "silownia", "praca"
  String title;
  String description;
  double progress;
  double maxProgress;
  IconData icon; // Dodajemy ikonę dla lepszej wizualizacji

  Goal({
    required this.id,
    required this.title,
    required this.description,
    this.progress = 0,
    required this.maxProgress,
    this.icon = Icons.star, // Domyślna ikona
  });

  // Metoda do serializacji Goal do JSON
  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'description': description,
        'progress': progress,
        'maxProgress': maxProgress,
        // Ikona nie jest serializowana, bo jest statyczna i odtworzymy ją po ID
      };

  // Konstruktor do deserializacji Goal z JSON
  factory Goal.fromJson(Map<String, dynamic> json) {
    // Tutaj musimy odtworzyć ikonę na podstawie ID,
    // albo przekazać ją jako argument z mapy definicji celów.
    // Dla prostoty, w tym przykładzie, odtworzymy ją na podstawie zmapowanych ID.
    IconData defaultIcon = Icons.star;
    switch (json['id']) {
      case 'pracady':
        defaultIcon = Icons.work;
        break;
      case 'silownia':
        defaultIcon = Icons.fitness_center;
        break;
      case 'boks':
        defaultIcon = Icons.sports_mma;
        break;
      case 'zarobek':
        defaultIcon = Icons.attach_money;
        break;
      case 'inf04':
        defaultIcon = Icons.computer;
        break;
      case 'matematyka':
        defaultIcon = Icons.calculate;
        break;
      case 'wyjazdy':
        defaultIcon = Icons.card_travel;
        break;
      // Dodaj więcej przypadków dla innych celów
    }

    return Goal(
      id: json['id'],
      title: json['title'],
      description: json['description'],
      progress: json['progress'] as double,
      maxProgress: json['maxProgress'] as double,
      icon: defaultIcon,
    );
  }
}

// Klasa Phase - teraz z możliwością mutacji goals oraz serializacją
class Phase {
  String title;
  DateTime startDate;
  DateTime endDate;
  String description;
  List<Goal> goals; // Lista celów dla tej fazy

  Phase({
    required this.title,
    required this.startDate,
    required this.endDate,
    required this.description,
    required this.goals,
  });

  // Metoda do serializacji Phase do JSON
  Map<String, dynamic> toJson() => {
        'title': title,
        'startDate': startDate.toIso8601String(),
        'endDate': endDate.toIso8601String(),
        'description': description,
        'goals': goals.map((g) => g.toJson()).toList(),
      };

  // Konstruktor do deserializacji Phase z JSON
  factory Phase.fromJson(Map<String, dynamic> json) {
    return Phase(
      title: json['title'],
      startDate: DateTime.parse(json['startDate']),
      endDate: DateTime.parse(json['endDate']),
      description: json['description'],
      goals: (json['goals'] as List<dynamic>)
          .map((g) => Goal.fromJson(g as Map<String, dynamic>))
          .toList(),
    );
  }
}

// =========================================================================
// GŁÓWNY WIDGET APLIKACJI
// =========================================================================

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

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

class _HomePageState extends State<Timelaps>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  // Daty projektu (całościowego) - ZMIENIONE NA 23.06.2025
  final DateTime projectStartDate = DateTime(2025, 6, 23);
  final DateTime projectEndDate = DateTime(2027, 6, 30); // Do końca Szkoły 2026/2027

  late DateTime currentDate;
  late Duration daysPassed;
  late Duration daysToGo;
  double totalProjectProgress = 0.0;
  int currentPhaseIndex = 0;

  List<Phase> phases = []; // Będzie ładowane z SharedPreferences lub domyślne

  // Kolory dla różnych celów
  final Map<String, Color> goalColors = {
    'pracady': const Color(0xFF4CAF50), // Zielony
    'silownia': const Color(0xFFFF9800), // Pomarańczowy
    'boks': const Color(0xFFF44336), // Czerwony
    'zarobek': const Color(0xFF2196F3), // Niebieski
    'inf04': const Color(0xFF9C27B0), // Fioletowy
    'matematyka': const Color(0xFF00BCD4), // Cyjan
    'wyjazdy': const Color(0xFFFFEB3B), // Żółty
  };

  @override
  void initState() {
    super.initState();
    currentDate = DateTime.now(); // Ustawiamy bieżącą datę
    _updateProgressData();
    _loadPhases(); // Ładowanie danych przy starcie
    initializeDateFormatting('pl_PL', null);
  }

  Color _getGoalColor(String goalId) {
    return goalColors[goalId] ?? const Color(0xFFBB86FC); // Domyślny kolor jeśli nie znajdziemy
  }

  // Definicja domyślnych faz i celów
  List<Phase> _getDefaultPhases() {
    // Definicje unikalnych typów celów z domyślnymi wartościami początkowymi i ikonami
    // Ich progress i maxProgress będą zapisywane per faza
    // (tj. cel "Siłownia" w Faza 1 jest odrębnym obiektem od "Siłownia" w Faza 2)
    Goal createGoal(String id, String title, String description, double maxProgress, IconData icon) {
      return Goal(id: id, title: title, description: description, maxProgress: maxProgress, icon: icon);
    }

    final List<Goal> allPossibleGoals = [
      createGoal('pracady', 'Przepracowane dni', 'Ilość dni przepracowanych w te wakacje.', 60, Icons.work),
      createGoal('silownia', 'Treningi siłowe', 'Ilość wykonanych treningów na siłowni.', 30, Icons.fitness_center),
      createGoal('boks', 'Treningi boksu', 'Ilość sesji treningowych boksu.', 20, Icons.sports_mma),
      createGoal('zarobek', 'Zarobione pieniądze', 'Suma zarobionych pieniędzy (w tysiącach PLN).', 10, Icons.attach_money),
      createGoal('inf04', 'Nauka INF04', 'Ilość godzin poświęconych na naukę INF04.', 80, Icons.computer),
      createGoal('matematyka', 'Nauka matematyki', 'Ilość godzin poświęconych na naukę matematyki.', 60, Icons.calculate),
      createGoal('wyjazdy', 'Wyjazdy', 'Lista planowanych wyjazdów w wakacje. (1 - zrealizowany)', 1, Icons.card_travel), // Binary goal
    ];

    // Funkcja pomocnicza do klonowania celów dla konkretnej fazy
    List<Goal> _cloneGoals(List<String> goalIds) {
      return goalIds.map((id) {
        final goalDef = allPossibleGoals.firstWhere((g) => g.id == id);
        return Goal(
          id: goalDef.id,
          title: goalDef.title,
          description: goalDef.description,
          maxProgress: goalDef.maxProgress, // Domyślna wartość docelowa
          icon: goalDef.icon,
        );
      }).toList();
    }

    return [
      Phase(
        title: "FAZA 1: Wakacje 2025",
        startDate: DateTime(2025, 6, 23), // Typowe daty wakacji
        endDate: DateTime(2025, 8, 31),
        description: "Wszystkie wydarzenia",
        goals: _cloneGoals(['pracady', 'silownia', 'boks', 'zarobek', 'inf04', 'matematyka', 'wyjazdy']),
      ),
      Phase(
        title: "FAZA 2: Szkoła 2025/2026",
        startDate: DateTime(2025, 9, 1),
        endDate: DateTime(2026, 6, 20),
        description: "Wszystkie wydarzenia poza pracą",
        goals: _cloneGoals(['silownia', 'boks', 'zarobek', 'inf04', 'matematyka']), // Praca wykluczona
      ),
      Phase(
        title: "FAZA 3: Wakacje 2026",
        startDate: DateTime(2026, 6, 21),
        endDate: DateTime(2026, 8, 31),
        description: "Wszystkie wydarzenia poza pracą/INF04",
        goals: _cloneGoals(['silownia', 'boks', 'zarobek', 'matematyka', 'wyjazdy']), // Praca i INF04 wykluczone
      ),
      Phase(
        title: "FAZA 4: Szkoła 2026/2027",
        startDate: DateTime(2026, 9, 1),
        endDate: DateTime(2027, 6, 20),
        description: "Wszystkie wydarzenia poza INF04",
        goals: _cloneGoals(['pracady', 'silownia', 'boks', 'zarobek', 'matematyka']), // INF04 wykluczone
      ),
    ];
  }


  void _updateProgressData() {
    setState(() {
      daysPassed = currentDate.difference(projectStartDate);
      daysToGo = projectEndDate.difference(currentDate);
      totalProjectProgress = daysPassed.inDays / projectEndDate.difference(projectStartDate).inDays;
      currentPhaseIndex = _getCurrentPhaseIndex();
    });
  }

  int _getCurrentPhaseIndex() {
    for (int i = 0; i < phases.length; i++) {
      if (currentDate.isAfter(phases[i].startDate.subtract(const Duration(days: 1))) &&
          currentDate.isBefore(phases[i].endDate.add(const Duration(days: 1)))) {
        return i;
      }
    }
    // Jeśli poza zakresem faz, ustaw na ostatnią, lub 0 jeśli jeszcze nie było faz
    if (phases.isEmpty) return 0;
    if (currentDate.isBefore(phases.first.startDate)) return 0;
    return phases.length - 1;
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  // =========================================================================
  // ZARZĄDZANIE DANYMI (ŁADOWANIE/ZAPIS)
  // =========================================================================

  Future<void> _loadPhases() async {
    final prefs = await SharedPreferences.getInstance();
    final String? phasesJson = prefs.getString('saved_phases');

    if (phasesJson != null && phasesJson.isNotEmpty) {
      try {
        final List<dynamic> jsonList = jsonDecode(phasesJson);
        setState(() {
          phases = jsonList.map((item) => Phase.fromJson(item as Map<String, dynamic>)).toList();
        });
      } catch (e) {
        print('Error loading phases from SharedPreferences: $e');
        // W razie błędu parsowania, załaduj domyślne
        setState(() {
          phases = _getDefaultPhases();
        });
      }
    } else {
      // Jeśli brak zapisanych danych, załaduj domyślne fazy
      setState(() {
        phases = _getDefaultPhases();
      });
    }

    _tabController = TabController(length: phases.length + 1, vsync: this);
    _tabController.addListener(() {
      setState(() {}); // Odśwież UI po zmianie tabu
    });

    _updateProgressData(); // Po załadowaniu danych zaktualizuj ogólny progress
  }

  Future<void> _savePhases() async {
    final prefs = await SharedPreferences.getInstance();
    final String phasesJson = jsonEncode(phases.map((p) => p.toJson()).toList());
    await prefs.setString('saved_phases', phasesJson);
  }

  void _updateGoalProgress(int phaseIndex, int goalIndex, double newProgress) {
    if (phaseIndex >= phases.length || goalIndex >= phases[phaseIndex].goals.length) return;
    setState(() {
      phases[phaseIndex].goals[goalIndex].progress = newProgress;
      _savePhases();
    });
  }

  void _updateGoalMaxProgress(int phaseIndex, int goalIndex, double newMaxProgress) {
    if (phaseIndex >= phases.length || goalIndex >= phases[phaseIndex].goals.length) return;
    setState(() {
      final goal = phases[phaseIndex].goals[goalIndex];
      goal.maxProgress = newMaxProgress;
      // Ensure current progress doesn't exceed new maxProgress
      if (goal.progress > newMaxProgress) {
        goal.progress = newMaxProgress;
      }
      _savePhases();
    });
  }

  // =========================================================================
  // BUDOWANIE INTERFEJSU UŻYTKOWNIKA
  // =========================================================================

  @override
  Widget build(BuildContext context) {
    if (phases.isEmpty) {
      return const Scaffold(
        backgroundColor: Color(0xFF121212),
        body: Center(child: CircularProgressIndicator()), // Pokaż ładowanie
      );
    }

    return Scaffold(
      backgroundColor: const Color(0xFF121212),
      appBar: AppBar(
        backgroundColor: const Color(0xFF1E1E1E),
        title: const Text(
          'TIMELAPSE',
          style: TextStyle(
            fontWeight: FontWeight.bold,
            letterSpacing: 2,
            color: Colors.white,
          ),
        ),
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(60),
          child: Container(
            height: 60,
            padding: const EdgeInsets.symmetric(horizontal: 16),
            color: const Color(0xFF1E1E1E),
            child: TabBar(
              controller: _tabController,
              isScrollable: true,
              indicator: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: const Color(0xFFBB86FC).withOpacity(0.2),
              ),
              indicatorSize: TabBarIndicatorSize.tab,
              labelColor: Colors.white,
              unselectedLabelColor: Colors.grey,
              tabs: [
                const Tab(text: 'PODSUMOWANIE'),
                ...phases.map((phase) => Tab(text: phase.title)).toList(),
              ],
            ),
          ),
        ),
      ),
      body: Container(
        color: const Color(0xFF121212),
        child: TabBarView(
          controller: _tabController,
          children: [
            _buildMainTab(),
            ...phases.asMap().entries.map((entry) => _buildPhaseTab(entry.key)).toList(),
          ],
        ),
      ),
    );
  }

  Widget _buildMainTab() {
    return Container(
      color: const Color(0xFF121212),
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildProgressCard(),
            const SizedBox(height: 20),
            _buildCurrentPhaseCard(),
            const SizedBox(height: 20),
            _buildUpcomingGoals(),
          ],
        ),
      ),
    );
  }

Widget _buildProgressCard() {
    final DateTime june23_2025 = DateTime(2025, 6, 23);
    final bool isBeforeStart = currentDate.isBefore(june23_2025);
    
    return Card(
      color: const Color(0xFF1E1E1E),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  isBeforeStart ? 'Zaraz zaczynamy glow up' : 'Dzień ${daysPassed.inDays + 1}',
                  style: const TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.w700,
                    color: Colors.white,
                  ),
                ),
                if (!isBeforeStart) // Only show percentage if we've started
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  decoration: BoxDecoration(
                    color: _getProgressColor(totalProjectProgress).withOpacity(0.2),
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: Text(
                    "${(totalProjectProgress * 100).toStringAsFixed(1)}%",
                    style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w800,
                      color: _getProgressColor(totalProjectProgress),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            Text(
              'Postęp całego projektu',
              style: TextStyle(
                fontSize: 14,
                color: Colors.white.withOpacity(0.7),
              ),
            ),
            const SizedBox(height: 16),
            LinearPercentIndicator(
              animation: true,
              lineHeight: 12.0,
              animationDuration: 1500,
              percent: isBeforeStart ? 0.0 : totalProjectProgress.clamp(0.0, 1.0),
              barRadius: const Radius.circular(10),
              progressColor: isBeforeStart ? Colors.grey : _getProgressColor(totalProjectProgress),
              backgroundColor: Colors.grey.shade800,
              padding: EdgeInsets.zero,
            ),
            const SizedBox(height: 16),
            if (!isBeforeStart) // Only show days remaining if we've started
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  'Pozostało: ${daysToGo.inDays} dni',
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.white.withOpacity(0.7),
                  ),
                ),
                Text(
                  'Do: ${DateFormat('dd.MM.yyyy').format(projectEndDate)}',
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.white.withOpacity(0.7),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Color _getProgressColor(double progress) {
    if (progress < 0.3) return const Color(0xFFCF6679); // Czerwony/różowy
    if (progress < 0.7) return const Color(0xFFFFD166); // Żółty/pomarańczowy
    return const Color(0xFF05D577); // Zielony
  }

  Widget _buildCurrentPhaseCard() {
    // Sprawdź czy phases nie jest puste
    if (phases.isEmpty) {
      return Card(
        color: const Color(0xFF1E1E1E),
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Center(
            child: Text(
              'Brak zdefiniowanych faz.',
              style: TextStyle(color: Colors.white.withOpacity(0.7)),
            ),
          ),
        ),
      );
    }
    Phase currentPhase = phases[currentPhaseIndex];
    double phaseProgress = _calculatePhaseProgress(currentPhaseIndex);

    return Card(
      color: const Color(0xFF1E1E1E),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Container(
                  padding: const EdgeInsets.all(8),
                  decoration: BoxDecoration(
                    color: const Color(0xFFBB86FC).withOpacity(0.2),
                    shape: BoxShape.circle,
                  ),
                  child: const Icon(
                    Icons.flag,
                    color: Color(0xFFBB86FC),
                    size: 20,
                  ),
                ),
                const SizedBox(width: 8),
                Text(
                  'Aktualna faza',
                  style: TextStyle(
                    fontSize: 16,
                    color: Colors.white.withOpacity(0.7),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            Text(
              currentPhase.title,
              style: const TextStyle(
                fontSize: 22,
                fontWeight: FontWeight.bold,
                color: Colors.white,
              ),
            ),
            const SizedBox(height: 12),
            LinearPercentIndicator(
              animation: true,
              lineHeight: 8.0,
              animationDuration: 500,
              percent: phaseProgress.clamp(0.0, 1.0),
              barRadius: const Radius.circular(5),
              progressColor: _getProgressColor(phaseProgress),
              backgroundColor: Colors.grey.shade800,
              padding: EdgeInsets.zero,
            ),
            const SizedBox(height: 8),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  DateFormat('dd.MM.yyyy').format(currentPhase.startDate),
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.white.withOpacity(0.5),
                  ),
                ),
                Text(
                  DateFormat('dd.MM.yyyy').format(currentPhase.endDate),
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.white.withOpacity(0.5),
                  ),
                ),
                Text(
                  '${(phaseProgress * 100).toStringAsFixed(0)}%',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: _getProgressColor(phaseProgress),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  double _calculatePhaseProgress(int phaseIndex) {
    if (phaseIndex >= phases.length) return 0.0;
    Phase phase = phases[phaseIndex];
    if (currentDate.isBefore(phase.startDate)) return 0.0;
    if (currentDate.isAfter(phase.endDate)) return 1.0;

    // Upewnij się, że nie dzielimy przez zero
    final totalPhaseDuration = phase.endDate.difference(phase.startDate).inDays;
    if (totalPhaseDuration == 0) return 0.0;

    return currentDate.difference(phase.startDate).inDays / totalPhaseDuration;
  }

  Widget _buildUpcomingGoals() {
    if (phases.isEmpty || phases[currentPhaseIndex].goals.isEmpty) {
      return Card(
        color: const Color(0xFF1E1E1E),
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Center(
            child: Column(
              children: [
                Icon(
                  Icons.check_circle_outline,
                  size: 40,
                  color: Colors.grey.shade500,
                ),
                const SizedBox(height: 12),
                Text(
                  'Brak celów w tej fazie lub wszystkie cele zostały osiągnięte',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 16,
                    color: Colors.grey.shade500,
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          'Cele fazy',
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
        const SizedBox(height: 10),
        ...phases[currentPhaseIndex].goals.asMap().entries.map((entry) {
          int goalIndex = entry.key;
          Goal goal = entry.value;
          double progressPercentage = (goal.maxProgress > 0) ? goal.progress / goal.maxProgress : 0.0;
          return _buildGoalProgressTile(currentPhaseIndex, goalIndex, goal, progressPercentage);
        }).toList(),
      ],
    );
  }

  Widget _buildGoalProgressTile(int phaseIndex, int goalIndex, Goal goal, double progressPercentage) {
    final bool isComplete = progressPercentage >= 1.0;
    final Color goalColor = _getGoalColor(goal.id);

    return Card(
      color: const Color(0xFF1E1E1E),
      margin: const EdgeInsets.only(bottom: 12),
      child: InkWell(
        borderRadius: BorderRadius.circular(16),
        onTap: () {
          _showGoalProgressDialog(
            phaseIndex,
            goalIndex,
            goal,
          );
        },
        onLongPress: () { // Nowy gest: długie naciśnięcie dla ustawienia wartości docelowej
          _showGoalMaxProgressDialog(
            phaseIndex,
            goalIndex,
            goal,
          );
        },
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Container(
                    width: 36,
                    height: 36,
                    decoration: BoxDecoration(
                      color: isComplete
                          ? Colors.green.withOpacity(0.1)
                          : goalColor.withOpacity(0.1),
                      shape: BoxShape.circle,
                      border: Border.all(
                        color: isComplete
                            ? Colors.green.withOpacity(0.3)
                            : goalColor.withOpacity(0.3),
                        width: 1,
                      ),
                    ),
                    child: Center(
                      child: Icon(
                        goal.icon, // Używamy ikony z Goal
                        color: isComplete
                            ? Colors.green
                            : goalColor,
                        size: 18,
                      ),
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          goal.title,
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 16,
                            color: isComplete
                                ? Colors.green
                                : Colors.white,
                          ),
                        ),
                        const SizedBox(height: 4),
                        Text(
                          goal.description,
                          style: TextStyle(
                            fontSize: 13,
                            color: Colors.white.withOpacity(0.7),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
                    decoration: BoxDecoration(
                      color: isComplete
                          ? Colors.green.withOpacity(0.1)
                          : goalColor.withOpacity(0.1),
                      borderRadius: BorderRadius.circular(16),
                      border: Border.all(
                        color: isComplete
                            ? Colors.green.withOpacity(0.3)
                            : goalColor.withOpacity(0.3),
                      ),
                    ),
                    child: Text(
                      '${goal.progress.toStringAsFixed(0)}/${goal.maxProgress.toStringAsFixed(0)}',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: 13,
                        color: isComplete
                            ? Colors.green
                            : goalColor,
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              LinearPercentIndicator(
                lineHeight: 6.0,
                percent: progressPercentage.clamp(0.0, 1.0),
                progressColor: isComplete ? Colors.green : goalColor,
                backgroundColor: Colors.grey.shade800,
                padding: EdgeInsets.zero,
                barRadius: const Radius.circular(4),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildPhaseTab(int phaseIndex) {
    if (phaseIndex >= phases.length) {
      return Container(
        color: const Color(0xFF121212),
        child: const Center(child: Text('Faza nie istnieje.', style: TextStyle(color: Colors.white))),
      );
    }
    Phase phase = phases[phaseIndex];
    double phaseProgress = _calculatePhaseProgress(phaseIndex);

    return Container(
      color: const Color(0xFF121212),
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Card(
              color: const Color(0xFF1E1E1E),
              child: Padding(
                padding: const EdgeInsets.all(20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        Container(
                          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                          decoration: BoxDecoration(
                            color: const Color(0xFFBB86FC).withOpacity(0.2),
                            borderRadius: BorderRadius.circular(12),
                          ),
                          child: Text(
                            phase.title,
                            style: const TextStyle(
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                              color: Color(0xFFBB86FC),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 16),
                    Text(
                      phase.description,
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.white.withOpacity(0.8),
                      ),
                    ),
                    const SizedBox(height: 20),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(
                          'Okres: ${DateFormat('d MMM', 'pl_PL').format(phase.startDate)} - ${DateFormat('d MMM', 'pl_PL').format(phase.endDate)}',
                          style: TextStyle(
                            fontWeight: FontWeight.w500,
                            fontSize: 14,
                            color: Colors.white.withOpacity(0.7),
                          ),
                        ),
                        Container(
                          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                          decoration: BoxDecoration(
                            color: _getProgressColor(phaseProgress).withOpacity(0.2),
                            borderRadius: BorderRadius.circular(20),
                          ),
                          child: Text(
                            '${(phaseProgress * 100).toStringAsFixed(0)}%',
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              color: _getProgressColor(phaseProgress),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 16),
                    LinearPercentIndicator(
                      lineHeight: 8.0,
                      percent: phaseProgress.clamp(0.0, 1.0),
                      progressColor: _getProgressColor(phaseProgress),
                      backgroundColor: Colors.grey.shade800,
                      padding: EdgeInsets.zero,
                      barRadius: const Radius.circular(4),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 20),
            if (phase.goals.isEmpty)
              Card(
                color: const Color(0xFF1E1E1E),
                child: Padding(
                  padding: const EdgeInsets.all(20),
                  child: Center(
                    child: Column(
                      children: [
                        Icon(
                          Icons.check_circle_outline,
                          size: 48,
                          color: Colors.grey.shade500,
                        ),
                        const SizedBox(height: 16),
                        Text(
                          'Brak celów w tej fazie lub wszystkie cele zostały osiągnięte',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 16,
                            color: Colors.grey.shade500,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              )
            else
              ...phase.goals.asMap().entries.map((entry) {
                int goalIndex = entry.key;
                Goal goal = entry.value;
                double progressPercentage = (goal.maxProgress > 0) ? goal.progress / goal.maxProgress : 0.0;
                final Color goalColor = _getGoalColor(goal.id);

                return Card(
                  color: const Color(0xFF1E1E1E),
                  margin: const EdgeInsets.only(bottom: 10),
                  child: InkWell(
                    onTap: () => _showGoalProgressDialog(phaseIndex, goalIndex, goal),
                    onLongPress: () => _showGoalMaxProgressDialog(phaseIndex, goalIndex, goal), // Długie naciśnięcie
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            children: [
                              Container(
                                width: 36,
                                height: 36,
                                decoration: BoxDecoration(
                                  color: progressPercentage >= 1.0
                                      ? Colors.green.withOpacity(0.1)
                                      : goalColor.withOpacity(0.1),
                                  shape: BoxShape.circle,
                                ),
                                child: Center(
                                  child: Icon(
                                    goal.icon,
                                    color: progressPercentage >= 1.0
                                        ? Colors.green
                                        : goalColor,
                                    size: 18,
                                  ),
                                ),
                              ),
                              const SizedBox(width: 12),
                              Expanded(
                                child: Text(
                                  goal.title,
                                  style: const TextStyle(
                                    fontSize: 18,
                                    fontWeight: FontWeight.bold,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                              Container(
                                padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
                                decoration: BoxDecoration(
                                  color: progressPercentage >= 1.0
                                      ? Colors.green.withOpacity(0.1)
                                      : goalColor.withOpacity(0.1),
                                  borderRadius: BorderRadius.circular(16),
                                ),
                                child: Text(
                                  '${goal.progress.toStringAsFixed(0)}/${goal.maxProgress.toStringAsFixed(0)}',
                                  style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 14,
                                    color: progressPercentage >= 1.0
                                        ? Colors.green
                                        : goalColor,
                                  ),
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 8),
                          Text(
                            goal.description,
                            style: TextStyle(
                              fontSize: 14,
                              color: Colors.white.withOpacity(0.7),
                            ),
                          ),
                          const SizedBox(height: 16),
                          LinearPercentIndicator(
                            lineHeight: 10.0,
                            percent: progressPercentage.clamp(0.0, 1.0),
                            progressColor: progressPercentage >= 1.0
                                ? Colors.green
                                : goalColor,
                            backgroundColor: Colors.grey.shade800,
                            padding: EdgeInsets.zero,
                            barRadius: const Radius.circular(5),
                          ),
                          const SizedBox(height: 12),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              ElevatedButton(
                                onPressed: () {
                                  _showGoalProgressDialog(phaseIndex, goalIndex, goal);
                                },
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: goalColor.withOpacity(0.6),
                                  foregroundColor: Colors.white, // BIAŁY KOLOR TEKSTU
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(20),
                                  ),
                                  padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                                ),
                                child: const Text('Zapisz', style: TextStyle(color: Colors.white)),
                              ),
                              const SizedBox(width: 8),
                              ElevatedButton(
                                onPressed: () {
                                  _showGoalMaxProgressDialog(phaseIndex, goalIndex, goal);
                                },
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: const Color(0xFF03DAC6).withOpacity(0.6),
                                  foregroundColor: Colors.white, // BIAŁY KOLOR TEKSTU
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(20),
                                  ),
                                  padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                                ),
                                child: const Text('Ustaw wartość docelową', style: TextStyle(color: Colors.white)),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              }).toList(),
          ],
        ),
      ),
    );
  }

  // =========================================================================
  // MODALE DLA ZARZĄDZANIA CELEM
  // =========================================================================

  // Modal do aktualizacji BIEŻĄCEGO progressu
  void _showGoalProgressDialog(int phaseIndex, int goalIndex, Goal goal) {
    double newProgress = goal.progress;
    bool isBinaryGoal = goal.maxProgress == 1;
    final Color goalColor = _getGoalColor(goal.id);

    showDialog(
      context: context,
      builder: (context) {
        return StatefulBuilder(
          builder: (context, setState) {
            return AlertDialog(
              backgroundColor: const Color(0xFF1E1E1E),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20),
              ),
              title: Text(
                'Aktualizuj postęp - ${goal.title}',
                style: const TextStyle(
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
              content: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(
                      goal.description,
                      style: TextStyle(
                        fontSize: 14,
                        color: Colors.white.withOpacity(0.7),
                      ),
                    ),
                    const SizedBox(height: 20),
                    if (isBinaryGoal)
                      SwitchListTile(
                        title: const Text(
                          'Cel osiągnięty',
                          style: TextStyle(color: Colors.white),
                        ),
                        value: newProgress >= 1,
                        activeColor: goalColor,
                        onChanged: (value) {
                          setState(() {
                            newProgress = value ? 1 : 0;
                          });
                        },
                      )
                    else
                      Column(
                        children: [
                          Row(
                            children: [
                              const Text(
                                'Postęp: ',
                                style: TextStyle(color: Colors.white),
                              ),
                              Expanded(
                                child: Slider(
                                  value: newProgress,
                                  min: 0,
                                  max: goal.maxProgress,
                                  divisions: goal.maxProgress.toInt() > 0 ? goal.maxProgress.toInt() : 1, // Zapewnij min 1 podział
                                  activeColor: goalColor,
                                  inactiveColor: Colors.grey.shade700,
                                  label: newProgress.toStringAsFixed(0),
                                  onChanged: (value) {
                                    setState(() {
                                      newProgress = value;
                                    });
                                  },
                                ),
                              ),
                              Text(
                                newProgress.toStringAsFixed(0),
                                style: const TextStyle(color: Colors.white),
                              ),
                            ],
                          ),
                          const SizedBox(height: 10),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              IconButton(
                                icon: const Icon(Icons.remove, color: Colors.white),
                                onPressed: () {
                                  setState(() {
                                    newProgress = (newProgress - 1).clamp(0, goal.maxProgress);
                                  });
                                },
                              ),
                              IconButton(
                                icon: const Icon(Icons.add, color: Colors.white),
                                onPressed: () {
                                  setState(() {
                                    newProgress = (newProgress + 1).clamp(0, goal.maxProgress);
                                  });
                                },
                              ),
                            ],
                          ),
                        ],
                      ),
                  ],
                ),
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(context),
                  child: Text(
                    'Anuluj',
                    style: TextStyle(
                      color: Colors.white.withOpacity(0.7),
                    ),
                  ),
                ),
                ElevatedButton(
                  onPressed: () {
                    _updateGoalProgress(phaseIndex, goalIndex, newProgress);
                    Navigator.pop(context);
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: goalColor,
                    foregroundColor: Colors.white,
                  ),
                  child: const Text('Zapisz', style: TextStyle(color: Colors.white)),
                ),
              ],
            );
          },
        );
      },
    );
  }

  // Nowy modal do aktualizacji CAŁKOWITEJ wartości docelowej
  void _showGoalMaxProgressDialog(int phaseIndex, int goalIndex, Goal goal) {
    TextEditingController controller = TextEditingController(text: goal.maxProgress.toStringAsFixed(0));
    final Color goalColor = _getGoalColor(goal.id);

    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          backgroundColor: const Color(0xFF1E1E1E),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
          title: Text(
            'Ustaw wartość docelową - ${goal.title}',
            style: const TextStyle(
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                'Wpisz nową wartość docelową dla celu "${goal.title}":',
                style: TextStyle(
                  fontSize: 14,
                  color: Colors.white.withOpacity(0.7),
                ),
              ),
              const SizedBox(height: 20),
              TextField(
                controller: controller,
                keyboardType: TextInputType.number,
                textAlign: TextAlign.center,
                style: const TextStyle(color: Colors.white, fontSize: 24),
                decoration: InputDecoration(
                  filled: true,
                  fillColor: Colors.grey.shade800,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                    borderSide: BorderSide.none,
                  ),
                  contentPadding: const EdgeInsets.symmetric(vertical: 15),
                ),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text(
                'Anuluj',
                style: TextStyle(
                  color: Colors.white.withOpacity(0.7),
                ),
              ),
            ),
            ElevatedButton(
              onPressed: () {
                double? newValue = double.tryParse(controller.text);
                if (newValue != null && newValue >= 0) {
                  _updateGoalMaxProgress(phaseIndex, goalIndex, newValue);
                  Navigator.pop(context);
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('Wprowadź poprawną liczbę dodatnią.')),
                  );
                }
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: goalColor,
                foregroundColor: Colors.white,
              ),
              child: const Text('Zapisz', style: TextStyle(color: Colors.white)),
            ),
          ],
        );
      },
    );
  }
}