import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

// -----------------------------
// Models
// -----------------------------

class User {
  final String username;
  final double balance;
  final String role;

  User({required this.username, required this.balance, required this.role});
}

class ServerModel {
  final int id;
  final String name;
  final String planName;
  final int cpu;
  final int ram;
  final String disk;
  final String os;
  final String status;
  final String ip;
  final String vncAddress;
  final String vncPassword;
  final Map<String, dynamic> ports;

  ServerModel({
    required this.id,
    required this.name,
    required this.planName,
    required this.cpu,
    required this.ram,
    required this.disk,
    required this.os,
    required this.status,
    required this.ip,
    required this.vncAddress,
    required this.vncPassword,
    required this.ports,
  });

  factory ServerModel.fromJson(Map<String, dynamic> json) {
    return ServerModel(
      id: json['id'],
      name: json['name'],
      planName: json['plan']['name'],
      cpu: json['plan']['cpu'],
      ram: json['plan']['ram'],
      disk: json['plan']['disk'],
      os: json['os'],
      status: json['status'],
      ip: json['ip'],
      vncAddress: json['vnc_address'],
      vncPassword: json['vnc_password'],
      ports: json['ports'],
    );
  }
}

// Add the main() function here
void main() {
  runApp(NetpcSpaceApp());
}

class Ticket {
  final int id;
  final String title;
  final String description;
  final String status;
  final String createdAt;
  final List<Message> messages;

  Ticket({
    required this.id,
    required this.title,
    required this.description,
    required this.status,
    required this.createdAt,
    required this.messages,
  });

  factory Ticket.fromJson(Map<String, dynamic> json) {
    var messagesFromJson = json['messages'] as List;
    List<Message> messageList =
        messagesFromJson.map((m) => Message.fromJson(m)).toList();

    return Ticket(
      id: json['id'],
      title: json['title'],
      description: json['description'],
      status: json['status'],
      createdAt: json['created_at'],
      messages: messageList,
    );
  }
}

class Message {
  final String content;
  final String sender;
  final String timestamp;

  Message(
      {required this.content, required this.sender, required this.timestamp});

  factory Message.fromJson(Map<String, dynamic> json) {
    return Message(
      content: json['content'],
      sender: json['sender'],
      timestamp: json['timestamp'],
    );
  }
}

// -----------------------------
// API Service
// -----------------------------

class ApiService {
  final String baseUrl;
  final FlutterSecureStorage secureStorage = FlutterSecureStorage();

  ApiService({required this.baseUrl});

  Future<http.Response> sendRequest(
    String endpoint, {
    String method = 'GET',
    Map<String, String>? headers,
    dynamic body,
  }) async {
    String url = '$baseUrl$endpoint';
    Map<String, String> requestHeaders = headers ?? {};

    // Attach JWT token if available
    String? token = await secureStorage.read(key: 'authToken');
    if (token != null) {
      requestHeaders['Authorization'] = 'Bearer $token';
    }

    switch (method.toUpperCase()) {
      case 'POST':
        return await http.post(
          Uri.parse(url),
          headers: requestHeaders,
          body: jsonEncode(body),
        );
      case 'PUT':
        return await http.put(
          Uri.parse(url),
          headers: requestHeaders,
          body: jsonEncode(body),
        );
      case 'DELETE':
        return await http.delete(
          Uri.parse(url),
          headers: requestHeaders,
        );
      default:
        return await http.get(
          Uri.parse(url),
          headers: requestHeaders,
        );
    }
  }

  // Authentication Endpoints
  Future<Map<String, dynamic>> login(String username, String password) async {
    final response = await sendRequest(
      '/api/login',
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: {'username': username, 'password': password},
    );

    if (response.statusCode == 200) {
      Map<String, dynamic> data = jsonDecode(response.body);
      await secureStorage.write(key: 'authToken', value: data['token']);
      return data;
    } else {
      throw Exception(jsonDecode(response.body)['error'] ?? 'Login failed');
    }
  }

  Future<Map<String, dynamic>> register(
      String username, String password) async {
    final response = await sendRequest(
      '/api/register',
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: {'username': username, 'password': password},
    );

    if (response.statusCode == 201) {
      return jsonDecode(response.body);
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Registration failed');
    }
  }

  Future<Map<String, dynamic>> getUserInfo() async {
    final response = await sendRequest(
      '/api/userinfo',
      method: 'GET',
      headers: {'Content-Type': 'application/json'},
    );

    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to fetch user info');
    }
  }

  Future<void> updateUserInfo(
      {String? newUsername,
      String? newPassword,
      required String currentPassword}) async {
    Map<String, dynamic> payload = {'current_password': currentPassword};
    if (newUsername != null && newUsername.isNotEmpty)
      payload['new_username'] = newUsername;
    if (newPassword != null && newPassword.isNotEmpty)
      payload['new_password'] = newPassword;

    final response = await sendRequest(
      '/api/userinfo',
      method: 'PUT',
      headers: {'Content-Type': 'application/json'},
      body: payload,
    );

    if (response.statusCode == 200) {
      return;
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to update user info');
    }
  }

  Future<void> logout() async {
    // Simply delete the token from secure storage
    await secureStorage.delete(key: 'authToken');
  }

  // Server Endpoints
  Future<List<ServerModel>> getServers() async {
    final response = await sendRequest('/api/servers', method: 'GET');

    if (response.statusCode == 200) {
      List<dynamic> serverList = jsonDecode(response.body);
      return serverList.map((s) => ServerModel.fromJson(s)).toList();
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to fetch servers');
    }
  }

  Future<ServerModel> createServer(String name, String plan, String os) async {
    final response = await sendRequest(
      '/api/servers',
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: {'name': name, 'plan': plan, 'os': os},
    );

    if (response.statusCode == 201) {
      return ServerModel.fromJson(jsonDecode(response.body));
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to create server');
    }
  }

  Future<void> toggleServerStatus(int serverId) async {
    final response =
        await sendRequest('/api/servers/$serverId/toggle', method: 'POST');

    if (response.statusCode != 200) {
      throw Exception(jsonDecode(response.body)['error'] ??
          'Failed to toggle server status');
    }
  }

  Future<void> deleteServer(int serverId) async {
    final response =
        await sendRequest('/api/servers/$serverId', method: 'DELETE');

    if (response.statusCode != 200) {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to delete server');
    }
  }

  // Ticket Endpoints
  Future<List<Ticket>> getTickets() async {
    final response = await sendRequest('/api/tickets', method: 'GET');

    if (response.statusCode == 200) {
      List<dynamic> ticketList = jsonDecode(response.body);
      return ticketList.map((t) => Ticket.fromJson(t)).toList();
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to fetch tickets');
    }
  }

  Future<Ticket> createTicket(String title, String description) async {
    final response = await sendRequest(
      '/api/tickets',
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: {'title': title, 'description': description},
    );

    if (response.statusCode == 201) {
      return Ticket.fromJson(jsonDecode(response.body));
    } else {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to create ticket');
    }
  }

  Future<void> replyTicket(int ticketId, String message) async {
    final response = await sendRequest(
      '/api/tickets/$ticketId/reply',
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: {'message': message},
    );

    if (response.statusCode != 201) {
      throw Exception(
          jsonDecode(response.body)['error'] ?? 'Failed to reply to ticket');
    }
  }
}

// -----------------------------
// Authentication Provider
// -----------------------------

class AuthProvider with ChangeNotifier {
  final ApiService apiService;
  final FlutterSecureStorage secureStorage = FlutterSecureStorage();

  User? _user;
  bool _isAuthenticated = false;

  User? get user => _user;
  bool get isAuthenticated => _isAuthenticated;

  AuthProvider({required this.apiService}) {
    _initialize();
  }

  Future<void> _initialize() async {
    String? token = await secureStorage.read(key: 'authToken');
    if (token != null) {
      try {
        await getUserInfo();
      } catch (e) {
        await logout();
      }
    }
  }

  Future<void> login(String username, String password) async {
    try {
      Map<String, dynamic> data = await apiService.login(username, password);
      _user = User(
        username: data['username'],
        balance: (data['balance'] as num).toDouble(),
        role: data['role'] ?? 'user',
      );
      _isAuthenticated = true;
      notifyListeners();
    } catch (e) {
      throw e;
    }
  }

  Future<void> register(String username, String password) async {
    try {
      await apiService.register(username, password);
    } catch (e) {
      throw e;
    }
  }

  Future<void> getUserInfo() async {
    try {
      Map<String, dynamic> data = await apiService.getUserInfo();
      _user = User(
        username: data['username'],
        balance: (data['balance'] as num).toDouble(),
        role: data['role'] ?? 'user',
      );
      _isAuthenticated = true;
      notifyListeners();
    } catch (e) {
      throw e;
    }
  }

  Future<void> updateUserInfo(
      {String? newUsername,
      String? newPassword,
      required String currentPassword}) async {
    try {
      await apiService.updateUserInfo(
        newUsername: newUsername,
        newPassword: newPassword,
        currentPassword: currentPassword,
      );
      await getUserInfo(); // Refresh user info
    } catch (e) {
      throw e;
    }
  }

  Future<void> logout() async {
    await apiService.logout();
    _user = null;
    _isAuthenticated = false;
    notifyListeners();
  }
}

// -----------------------------
// Main Application
// -----------------------------

class NetpcSpaceApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Replace with your backend URL
    final apiService = ApiService(baseUrl: 'http://localhost:5000');

    return ChangeNotifierProvider(
      create: (_) => AuthProvider(apiService: apiService),
      child: Consumer<AuthProvider>(
        builder: (context, authProvider, child) {
          return MaterialApp(
            title: 'Netpc.Space Dashboard',
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              primaryColor: Color(0xFF532E41),
              scaffoldBackgroundColor: Color(0xFF09090A),
              fontFamily: 'Roboto', // Default font
              textTheme: TextTheme(
                bodyLarge: TextStyle(color: Colors.white),
                bodyMedium: TextStyle(color: Colors.white),
              ),
            ),
            initialRoute:
                authProvider.isAuthenticated ? '/dashboard' : '/login',
            routes: {
              '/login': (context) => LoginScreen(),
              '/register': (context) => RegisterScreen(),
              '/dashboard': (context) => DashboardScreen(),
              '/settings': (context) => SettingsScreen(),
              '/tickets': (context) => TicketsScreen(),
            },
            onUnknownRoute: (settings) => MaterialPageRoute(
              builder: (context) => Scaffold(
                body: Center(
                  child: Text('Страница не найдена',
                      style: TextStyle(color: Colors.white)),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

// -----------------------------
// Screens
// -----------------------------

// 1. Login Screen
class LoginScreen extends StatefulWidget {
  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final _formKey = GlobalKey<FormState>();

  String _username = '';
  String _password = '';
  bool _isLoading = false;

  void _showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);

    return Scaffold(
      body: Center(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 24),
          constraints: BoxConstraints(maxWidth: 400),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Войти',
                    style: TextStyle(
                        fontSize: 32,
                        fontWeight: FontWeight.bold,
                        color: Colors.white)),
                SizedBox(height: 32),
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Имя пользователя',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  validator: (value) => value == null || value.isEmpty
                      ? 'Пожалуйста, введите имя пользователя'
                      : null,
                  onSaved: (value) => _username = value!.trim(),
                ),
                SizedBox(height: 16),
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Пароль',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  obscureText: true,
                  validator: (value) => value == null || value.isEmpty
                      ? 'Пожалуйста, введите пароль'
                      : null,
                  onSaved: (value) => _password = value!.trim(),
                ),
                SizedBox(height: 24),
                _isLoading
                    ? CircularProgressIndicator()
                    : ElevatedButton(
                        onPressed: () async {
                          if (!_formKey.currentState!.validate()) return;
                          _formKey.currentState!.save();

                          setState(() {
                            _isLoading = true;
                          });

                          try {
                            await authProvider.login(_username, _password);
                            Navigator.pushReplacementNamed(
                                context, '/dashboard');
                            _showSnackBar('Вход выполнен успешно!',
                                color: Colors.green);
                          } catch (e) {
                            _showSnackBar(e.toString());
                          } finally {
                            setState(() {
                              _isLoading = false;
                            });
                          }
                        },
                        child: Text('Войти'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Color(0xFF532E41),
                          padding: EdgeInsets.symmetric(
                              vertical: 12, horizontal: 24),
                        ),
                      ),
                SizedBox(height: 16),
                TextButton(
                  onPressed: () {
                    Navigator.pushReplacementNamed(context, '/register');
                  },
                  child: Text('Нет аккаунта? Зарегистрироваться',
                      style: TextStyle(color: Colors.white)),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 2. Register Screen
class RegisterScreen extends StatefulWidget {
  @override
  State<RegisterScreen> createState() => _RegisterScreenState();
}

class _RegisterScreenState extends State<RegisterScreen> {
  final _formKey = GlobalKey<FormState>();

  String _username = '';
  String _password = '';
  bool _isLoading = false;

  void _showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);

    return Scaffold(
      body: Center(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 24),
          constraints: BoxConstraints(maxWidth: 400),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Регистрация',
                    style: TextStyle(
                        fontSize: 32,
                        fontWeight: FontWeight.bold,
                        color: Colors.white)),
                SizedBox(height: 32),
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Имя пользователя',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  validator: (value) => value == null || value.isEmpty
                      ? 'Пожалуйста, введите имя пользователя'
                      : null,
                  onSaved: (value) => _username = value!.trim(),
                ),
                SizedBox(height: 16),
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Пароль',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  obscureText: true,
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Пожалуйста, введите пароль';
                    } else if (value.length < 6) {
                      return 'Пароль должен содержать минимум 6 символов';
                    }
                    return null;
                  },
                  onSaved: (value) => _password = value!.trim(),
                ),
                SizedBox(height: 24),
                _isLoading
                    ? CircularProgressIndicator()
                    : ElevatedButton(
                        onPressed: () async {
                          if (!_formKey.currentState!.validate()) return;
                          _formKey.currentState!.save();

                          setState(() {
                            _isLoading = true;
                          });

                          try {
                            await authProvider.register(_username, _password);
                            Navigator.pushReplacementNamed(context, '/login');
                            _showSnackBar(
                                'Регистрация успешна! Теперь вы можете войти.',
                                color: Colors.green);
                          } catch (e) {
                            _showSnackBar(e.toString());
                          } finally {
                            setState(() {
                              _isLoading = false;
                            });
                          }
                        },
                        child: Text('Зарегистрироваться'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Color(0xFF532E41),
                          padding: EdgeInsets.symmetric(
                              vertical: 12, horizontal: 24),
                        ),
                      ),
                SizedBox(height: 16),
                TextButton(
                  onPressed: () {
                    Navigator.pushReplacementNamed(context, '/login');
                  },
                  child: Text('Уже есть аккаунт? Войти',
                      style: TextStyle(color: Colors.white)),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 3. Dashboard Screen
class DashboardScreen extends StatefulWidget {
  @override
  State<DashboardScreen> createState() => _DashboardScreenState();
}

class _DashboardScreenState extends State<DashboardScreen> {
  String selectedTab = 'Главное';
  List<ServerModel> servers = [];
  bool isLoading = true;

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

  Future<void> fetchServers() async {
    setState(() {
      isLoading = true;
    });
    try {
      final apiService =
          Provider.of<AuthProvider>(context, listen: false).apiService;
      final fetchedServers = await apiService.getServers();
      setState(() {
        servers = fetchedServers;
      });
    } catch (e) {
      showSnackBar('Не удалось загрузить серверы: $e');
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  void showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  void handleLogout() async {
    final authProvider = Provider.of<AuthProvider>(context, listen: false);
    await authProvider.logout();
    Navigator.pushReplacementNamed(context, '/login');
  }

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);
    final user = authProvider.user!;

    return Scaffold(
      body: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Sidebar
          Sidebar(
            selectedTab: selectedTab,
            user: user,
            onTabSelected: (tab) {
              if (tab == 'Выход') {
                handleLogout();
              } else {
                setState(() {
                  selectedTab = tab;
                });
                if (tab == 'Настройки') {
                  Navigator.pushNamed(context, '/settings');
                } else if (tab == 'Тикеты') {
                  Navigator.pushNamed(context, '/tickets');
                }
              }
            },
          ),
          // Main Content
          Expanded(
            child: selectedTab == 'Главное'
                ? RefreshIndicator(
                    onRefresh: fetchServers,
                    child: isLoading
                        ? Center(child: CircularProgressIndicator())
                        : servers.isEmpty
                            ? Center(
                                child: Text('У вас нет серверов',
                                    style: TextStyle(color: Colors.white)))
                            : ListView.builder(
                                padding: EdgeInsets.all(16),
                                itemCount: servers.length,
                                itemBuilder: (context, index) {
                                  final server = servers[index];
                                  return ServerCard(
                                    server: server,
                                    onDeleted: () {
                                      fetchServers();
                                    },
                                    onToggled: () {
                                      fetchServers();
                                    },
                                  );
                                },
                              ),
                  )
                : Center(
                    child: Text('Выбранная вкладка: $selectedTab',
                        style: TextStyle(color: Colors.white))),
          ),
        ],
      ),
      floatingActionButton: selectedTab == 'Главное'
          ? FloatingActionButton(
              onPressed: () => showDialog(
                context: context,
                builder: (context) => CreateServerDialog(
                  onServerCreated: () => fetchServers(),
                ),
              ),
              child: Icon(Icons.add),
              backgroundColor: Color(0xFF532E41),
              tooltip: 'Создать сервер',
            )
          : null,
    );
  }
}

// 4. Settings Screen
class SettingsScreen extends StatefulWidget {
  @override
  State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  final _formKey = GlobalKey<FormState>();

  String _currentPassword = '';
  String? _newUsername;
  String? _newPassword;
  bool _isLoading = false;

  void _showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);
    final user = authProvider.user!;

    return Scaffold(
      appBar: AppBar(
        title: Text('Настройки'),
        backgroundColor: Color(0xFF532E41),
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.all(24),
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                // Update Username
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Новое имя пользователя',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  onSaved: (value) => _newUsername = value!.trim(),
                ),
                SizedBox(height: 16),
                // Update Password
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Новый пароль',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  obscureText: true,
                  onSaved: (value) => _newPassword = value!.trim(),
                ),
                SizedBox(height: 16),
                // Current Password
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Текущий пароль',
                      labelStyle: TextStyle(color: Colors.white70)),
                  style: TextStyle(color: Colors.white),
                  obscureText: true,
                  validator: (value) => value == null || value.isEmpty
                      ? 'Пожалуйста, введите текущий пароль'
                      : null,
                  onSaved: (value) => _currentPassword = value!.trim(),
                ),
                SizedBox(height: 24),
                // Save Button
                _isLoading
                    ? CircularProgressIndicator()
                    : ElevatedButton(
                        onPressed: () async {
                          if (!_formKey.currentState!.validate()) return;
                          _formKey.currentState!.save();

                          setState(() {
                            _isLoading = true;
                          });

                          try {
                            await authProvider.updateUserInfo(
                              newUsername: _newUsername != null &&
                                      _newUsername!.isNotEmpty
                                  ? _newUsername
                                  : null,
                              newPassword: _newPassword != null &&
                                      _newPassword!.isNotEmpty
                                  ? _newPassword
                                  : null,
                              currentPassword: _currentPassword,
                            );
                            _showSnackBar('Настройки успешно обновлены!',
                                color: Colors.green);
                          } catch (e) {
                            _showSnackBar(e.toString());
                          } finally {
                            setState(() {
                              _isLoading = false;
                            });
                          }
                        },
                        child: Text('Сохранить'),
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Color(0xFF532E41),
                          padding: EdgeInsets.symmetric(
                              vertical: 12, horizontal: 24),
                        ),
                      ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 5. Tickets Screen
class TicketsScreen extends StatefulWidget {
  @override
  State<TicketsScreen> createState() => _TicketsScreenState();
}

class _TicketsScreenState extends State<TicketsScreen> {
  final _formKey = GlobalKey<FormState>();
  String _title = '';
  String _description = '';
  bool _isLoading = false;
  List<Ticket> tickets = [];
  bool isLoadingTickets = true;

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

  Future<void> fetchTickets() async {
    setState(() {
      isLoadingTickets = true;
    });
    try {
      final apiService =
          Provider.of<AuthProvider>(context, listen: false).apiService;
      final fetchedTickets = await apiService.getTickets();
      setState(() {
        tickets = fetchedTickets;
      });
    } catch (e) {
      showSnackBar('Не удалось загрузить тикеты: $e');
    } finally {
      setState(() {
        isLoadingTickets = false;
      });
    }
  }

  void showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  Future<void> createTicket() async {
    if (!_formKey.currentState!.validate()) return;
    _formKey.currentState!.save();

    setState(() {
      _isLoading = true;
    });

    try {
      final apiService =
          Provider.of<AuthProvider>(context, listen: false).apiService;
      await apiService.createTicket(_title, _description);
      showSnackBar('Тикет успешно создан!', color: Colors.green);
      _formKey.currentState!.reset();
      fetchTickets();
    } catch (e) {
      showSnackBar('Ошибка создания тикета: $e');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> replyToTicket(int ticketId, String message) async {
    try {
      final apiService =
          Provider.of<AuthProvider>(context, listen: false).apiService;
      await apiService.replyTicket(ticketId, message);
      showSnackBar('Ответ успешно отправлен!', color: Colors.green);
      fetchTickets();
    } catch (e) {
      showSnackBar('Ошибка отправки ответа: $e');
    }
  }

  Future<void> viewTicket(Ticket ticket) async {
    TextEditingController _replyController = TextEditingController();

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(ticket.title, style: TextStyle(color: Colors.black)),
        content: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Описание:', style: TextStyle(fontWeight: FontWeight.bold)),
              SizedBox(height: 8),
              Text(ticket.description),
              SizedBox(height: 16),
              Text('Сообщения:', style: TextStyle(fontWeight: FontWeight.bold)),
              SizedBox(height: 8),
              ...ticket.messages.map((msg) => ListTile(
                    title: Text(msg.sender == 'admin' ? 'Админ' : 'Вы',
                        style: TextStyle(fontWeight: FontWeight.bold)),
                    subtitle: Text(msg.content),
                    trailing: Text(
                      TimeOfDay.fromDateTime(DateTime.parse(msg.timestamp))
                          .format(context),
                      style: TextStyle(fontSize: 12, color: Colors.grey),
                    ),
                  )),
              SizedBox(height: 16),
              TextFormField(
                controller: _replyController,
                decoration: InputDecoration(labelText: 'Ваш ответ'),
                maxLines: 3,
              ),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Закрыть'),
          ),
          TextButton(
            onPressed: () async {
              String message = _replyController.text.trim();
              if (message.isNotEmpty) {
                await replyToTicket(ticket.id, message);
                Navigator.pop(context);
              }
            },
            child: Text('Отправить'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);
    final user = authProvider.user!;

    return Scaffold(
      appBar: AppBar(
        title: Text('Тикеты'),
        backgroundColor: Color(0xFF532E41),
      ),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            // Ticket Creation Form
            Form(
              key: _formKey,
              child: Column(
                children: [
                  TextFormField(
                    decoration: InputDecoration(
                        labelText: 'Заголовок тикета',
                        labelStyle: TextStyle(color: Colors.white70)),
                    style: TextStyle(color: Colors.white),
                    validator: (value) => value == null || value.isEmpty
                        ? 'Пожалуйста, введите заголовок'
                        : null,
                    onSaved: (value) => _title = value!.trim(),
                  ),
                  SizedBox(height: 16),
                  TextFormField(
                    decoration: InputDecoration(
                        labelText: 'Описание тикета',
                        labelStyle: TextStyle(color: Colors.white70)),
                    style: TextStyle(color: Colors.white),
                    maxLines: 3,
                    validator: (value) => value == null || value.isEmpty
                        ? 'Пожалуйста, введите описание'
                        : null,
                    onSaved: (value) => _description = value!.trim(),
                  ),
                  SizedBox(height: 16),
                  _isLoading
                      ? CircularProgressIndicator()
                      : ElevatedButton(
                          onPressed: createTicket,
                          child: Text('Создать тикет'),
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Color(0xFF532E41),
                            padding: EdgeInsets.symmetric(
                                vertical: 12, horizontal: 24),
                          ),
                        ),
                ],
              ),
            ),
            SizedBox(height: 32),
            // Tickets List
            Expanded(
              child: isLoadingTickets
                  ? Center(child: CircularProgressIndicator())
                  : tickets.isEmpty
                      ? Center(
                          child: Text('У вас нет тикетов',
                              style: TextStyle(color: Colors.white)))
                      : ListView.builder(
                          itemCount: tickets.length,
                          itemBuilder: (context, index) {
                            final ticket = tickets[index];
                            return Card(
                              color: Color.fromARGB(255, 4, 4, 4),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                                side: BorderSide(color: Colors.grey),
                              ),
                              margin: EdgeInsets.symmetric(vertical: 8),
                              child: ListTile(
                                title: Text(ticket.title,
                                    style: TextStyle(color: Colors.white)),
                                subtitle: Text(ticket.description,
                                    style: TextStyle(color: Colors.grey)),
                                trailing: Chip(
                                  label: Text(ticket.status,
                                      style: TextStyle(color: Colors.white)),
                                  backgroundColor: ticket.status == 'open'
                                      ? Colors.green
                                      : Colors.orange,
                                ),
                                onTap: () => viewTicket(ticket),
                              ),
                            );
                          },
                        ),
            ),
          ],
        ),
      ),
    );
  }
}

// -----------------------------
// Widgets
// -----------------------------

// Sidebar Widget
class Sidebar extends StatelessWidget {
  final String selectedTab;
  final User user;
  final Function(String) onTabSelected;

  Sidebar(
      {required this.selectedTab,
      required this.user,
      required this.onTabSelected});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300, // Adjusted width for better fit
      height: double.infinity,
      color: Color(0xFF09090A),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            SizedBox(height: 60),
            // Centered "netpc.space" Text
            Text(
              'netpc.space',
              style: TextStyle(
                color: Colors.white,
                fontSize: 28,
                fontWeight: FontWeight.bold,
                fontFamily: 'NeueMachina',
              ),
            ),
            SizedBox(height: 50),
            // User Information
            Container(
              width: double.infinity,
              padding: EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.white.withOpacity(0.1),
                border: Border.all(color: Colors.grey),
                borderRadius: BorderRadius.circular(12),
              ),
              child: Column(
                children: [
                  // User Icon with Username and Logout Button
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.account_circle,
                        color: Colors.white,
                        size: 30,
                      ),
                      SizedBox(width: 8),
                      Text(
                        user.username,
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 18,
                          fontFamily: 'Roboto',
                        ),
                      ),
                      SizedBox(width: 8),
                      GestureDetector(
                        onTap: () => onTabSelected('Выход'),
                        child: Icon(
                          Icons.logout,
                          color: Colors.white,
                          size: 24,
                        ),
                      ),
                    ],
                  ),
                  SizedBox(height: 16),
                  // Money Emoji with Balance
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        '💰',
                        style: TextStyle(
                          fontSize: 24,
                        ),
                      ),
                      SizedBox(width: 8),
                      Text(
                        '${user.balance}',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 18,
                          fontFamily: 'Roboto',
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
            SizedBox(height: 50),
            // Navigation Buttons
            NavButton(
              icon: Icons.dashboard,
              label: 'Главное',
              isSelected: selectedTab == 'Главное',
              onTap: () => onTabSelected('Главное'),
            ),
            NavButton(
              icon: Icons.settings,
              label: 'Настройки',
              isSelected: selectedTab == 'Настройки',
              onTap: () => onTabSelected('Настройки'),
            ),
            NavButton(
              icon: Icons.question_answer,
              label: 'Тикеты',
              isSelected: selectedTab == 'Тикеты',
              onTap: () => onTabSelected('Тикеты'),
            ),
            Spacer(),
          ],
        ),
      ),
    );
  }
}

// Navigation Button Widget
class NavButton extends StatelessWidget {
  final IconData icon;
  final String label;
  final bool isSelected;
  final VoidCallback onTap;

  NavButton({
    required this.icon,
    required this.label,
    this.isSelected = false,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: double.infinity,
        height: 50, // Fixed height for consistency
        margin: EdgeInsets.symmetric(vertical: 8),
        padding: EdgeInsets.symmetric(horizontal: 16),
        decoration: BoxDecoration(
          color:
              isSelected ? Colors.black.withOpacity(0.7) : Colors.transparent,
          border: Border.all(color: Colors.grey),
          borderRadius: BorderRadius.circular(8),
        ),
        child: Row(
          children: [
            Icon(
              icon,
              color: Colors.white,
            ),
            SizedBox(width: 16),
            Text(
              label,
              style: TextStyle(
                color: Colors.white,
                fontSize: 16,
                fontFamily: 'Roboto',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// Server Card Widget
class ServerCard extends StatelessWidget {
  final ServerModel server;
  final VoidCallback onDeleted;
  final VoidCallback onToggled;

  ServerCard(
      {required this.server, required this.onDeleted, required this.onToggled});

  @override
  Widget build(BuildContext context) {
    final statusColor = server.status == 'active' ? Colors.green : Colors.red;
    final apiService =
        Provider.of<AuthProvider>(context, listen: false).apiService;

    return Card(
      color: Color.fromARGB(255, 4, 4, 4),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(24),
        side: BorderSide(color: Colors.grey),
      ),
      margin: EdgeInsets.symmetric(vertical: 8),
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Server Name and Status
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  server.name,
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                      fontFamily: 'Unbounded'),
                ),
                Text(
                  server.status,
                  style: TextStyle(
                      color: statusColor, fontWeight: FontWeight.bold),
                ),
              ],
            ),
            SizedBox(height: 8),
            // Server Details
            Text('IP: ${server.ip}', style: TextStyle(color: Colors.white)),
            Text('VNC: ${server.vncAddress}',
                style: TextStyle(color: Colors.white)),
            Text('VNC Пароль: ${server.vncPassword}',
                style: TextStyle(color: Colors.white)),
            SizedBox(height: 8),
            // Ports
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text('План: ${server.planName}',
                    style: TextStyle(color: Colors.white)),
                Text('CPU: ${server.cpu} / RAM: ${server.ram}GB',
                    style: TextStyle(color: Colors.white)),
              ],
            ),
            SizedBox(height: 16),
            // Buttons
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                ElevatedButton.icon(
                  onPressed: () async {
                    try {
                      await apiService.toggleServerStatus(server.id);
                      onToggled();
                      showSnackBar(context, 'Статус сервера изменен',
                          color: Colors.green);
                    } catch (e) {
                      showSnackBar(context, 'Ошибка: $e');
                    }
                  },
                  icon: Icon(Icons.sync),
                  label: Text(
                      server.status == 'active' ? 'Остановить' : 'Запустить'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor:
                        server.status == 'active' ? Colors.red : Colors.green,
                    side: BorderSide(color: Colors.grey),
                  ),
                ),
                SizedBox(width: 8),
                ElevatedButton.icon(
                  onPressed: () async {
                    bool confirm = await showDialog(
                      context: context,
                      builder: (context) => AlertDialog(
                        title: Text('Удалить сервер'),
                        content: Text(
                            'Вы уверены, что хотите удалить сервер "${server.name}"? Это действие нельзя отменить.'),
                        actions: [
                          TextButton(
                            onPressed: () => Navigator.pop(context, false),
                            child: Text('Отмена'),
                          ),
                          TextButton(
                            onPressed: () => Navigator.pop(context, true),
                            child: Text('Удалить',
                                style: TextStyle(color: Colors.red)),
                          ),
                        ],
                      ),
                    );

                    if (confirm) {
                      try {
                        await apiService.deleteServer(server.id);
                        onDeleted();
                        showSnackBar(context, 'Сервер удален',
                            color: Colors.green);
                      } catch (e) {
                        showSnackBar(context, 'Ошибка удаления сервера: $e');
                      }
                    }
                  },
                  icon: Icon(Icons.delete),
                  label: Text('Удалить'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.black,
                    side: BorderSide(color: Colors.grey),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  void showSnackBar(BuildContext context, String message,
      {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }
}

// Create Server Dialog
class CreateServerDialog extends StatefulWidget {
  final VoidCallback onServerCreated;

  CreateServerDialog({required this.onServerCreated});

  @override
  State<CreateServerDialog> createState() => _CreateServerDialogState();
}

class _CreateServerDialogState extends State<CreateServerDialog> {
  final _formKey = GlobalKey<FormState>();
  String _serverName = '';
  String _selectedPlan = 'basic';
  String _selectedOS = 'win10';
  bool _isLoading = false;

  final Map<String, dynamic> planConfigs = {
    'basic': {
      'name': 'Базовый',
      'cpu': 2,
      'ram': 4,
      'disk': '50GB',
      'price': 500
    },
    'advanced': {
      'name': 'Продвинутый',
      'cpu': 4,
      'ram': 8,
      'disk': '100GB',
      'price': 1000
    },
    'premium': {
      'name': 'Премиум',
      'cpu': 8,
      'ram': 16,
      'disk': '200GB',
      'price': 2000
    },
  };

  final List<String> osOptions = ['win10', 'win11', 'win2020', 'win2022'];

  void _showSnackBar(String message, {Color color = Colors.red}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  Future<void> createServer() async {
    if (!_formKey.currentState!.validate()) return;
    _formKey.currentState!.save();

    setState(() {
      _isLoading = true;
    });

    try {
      final apiService =
          Provider.of<AuthProvider>(context, listen: false).apiService;
      await apiService.createServer(_serverName, _selectedPlan, _selectedOS);
      widget.onServerCreated();
      Navigator.pop(context);
      _showSnackBar('Сервер успешно создан!', color: Colors.green);
    } catch (e) {
      _showSnackBar('Ошибка создания сервера: $e');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Создать новый сервер'),
      content: SingleChildScrollView(
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              // Server Name
              TextFormField(
                decoration: InputDecoration(
                    labelText: 'Имя сервера',
                    labelStyle: TextStyle(color: Colors.white70)),
                style: TextStyle(color: Colors.white),
                validator: (value) => value == null || value.isEmpty
                    ? 'Пожалуйста, введите имя сервера'
                    : null,
                onSaved: (value) => _serverName = value!.trim(),
              ),
              SizedBox(height: 16),
              // Select Plan
              DropdownButtonFormField<String>(
                decoration: InputDecoration(
                    labelText: 'Выберите план',
                    labelStyle: TextStyle(color: Colors.white70)),
                value: _selectedPlan,
                dropdownColor: Color(0xFF09090A),
                items: planConfigs.keys
                    .map((planKey) => DropdownMenuItem(
                          value: planKey,
                          child: Text(planConfigs[planKey]['name'],
                              style: TextStyle(color: Colors.white)),
                        ))
                    .toList(),
                onChanged: (val) => setState(() {
                  _selectedPlan = val!;
                }),
              ),
              SizedBox(height: 16),
              // Select OS
              DropdownButtonFormField<String>(
                decoration: InputDecoration(
                    labelText: 'Выберите ОС',
                    labelStyle: TextStyle(color: Colors.white70)),
                value: _selectedOS,
                dropdownColor: Color(0xFF09090A),
                items: osOptions
                    .map((os) => DropdownMenuItem(
                          value: os,
                          child: Text(os.toUpperCase(),
                              style: TextStyle(color: Colors.white)),
                        ))
                    .toList(),
                onChanged: (val) => setState(() {
                  _selectedOS = val!;
                }),
              ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: _isLoading ? null : () => Navigator.pop(context),
          child: Text('Отмена', style: TextStyle(color: Colors.white)),
        ),
        ElevatedButton(
          onPressed: _isLoading ? null : createServer,
          child: _isLoading
              ? CircularProgressIndicator(color: Colors.white)
              : Text('Создать'),
          style: ElevatedButton.styleFrom(
            backgroundColor: Color(0xFF532E41),
            padding: EdgeInsets.symmetric(vertical: 12, horizontal: 24),
          ),
        ),
      ],
      backgroundColor: Color(0xFF09090A),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
    );
  }
}


══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
js_primitives.dart:28 The following TypeErrorImpl was thrown building DashboardScreen(dirty, dependencies:
js_primitives.dart:28 [_InheritedProviderScope<AuthProvider?>], state: _DashboardScreenState#53cef):
js_primitives.dart:28 Unexpected null value.
js_primitives.dart:28 
js_primitives.dart:28 The relevant error-causing widget was:
js_primitives.dart:28   DashboardScreen DashboardScreen:file:///E:/flutter/flutter_application_4/lib/main.dart:467:42
js_primitives.dart:28 
js_primitives.dart:28 When the exception was thrown, this was the stack:
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3       throw_
js_primitives.dart:28 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 606:18  nullCheck
js_primitives.dart:28 packages/flutter_application_4/main.dart 769:35                                   build
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5729:27                               build
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5617:15                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5780:11                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5771:11                               [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5642:16                               performRebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5333:7                                rebuild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5599:5                                [_firstBuild]
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 5593:5                                mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 3963:18                               updateChild
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 6900:14                               mount
js_primitives.dart:28 packages/flutter/src/widgets/framework.dart 4468:15                               inflateWidget
errors.dart:296  Uncaught (in promise) DartError: Assertion failed: file:///C:/Users/lvvmodel/dev/flutter/packages/flutter/lib/src/material/scaffold.dart:314:7
_scaffolds.isNotEmpty
"ScaffoldMessenger.showSnackBar was called, but there are currently no descendant Scaffolds to present to."
    at Object.throw_ [as throw] (errors.dart:296:3)
    at Object.assertFailed (errors.dart:29:3)
    at scaffold$.ScaffoldMessengerState.new.showSnackBar (scaffold.dart:314:18)
    at main._DashboardScreenState.new.showSnackBar (main.dart:755:26)
    at main._DashboardScreenState.new.fetchServers (main.dart:746:7)
    at fetchServers.throw (<anonymous>)
    at async_patch.dart:60:31
    at _RootZone.runBinary (zone.dart:1666:54)
    at _FutureListener.thenAwait.handleError (future_impl.dart:178:22)
    at handleError (future_impl.dart:873:46)
    at _Future._propagateToListeners (future_impl.dart:894:13)
    at [_completeWithValue] (future_impl.dart:666:5)
    at async._AsyncCallbackEntry.new.callback (future_impl.dart:736:7)
    at Object._microtaskLoop (schedule_microtask.dart:40:11)
    at _startMicrotaskLoop (schedule_microtask.dart:49:5)
    at async_patch.dart:181:7