import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../core/api/client.dart'; import '../../core/api/endpoints.dart'; import '../../core/theme/app_theme.dart'; import '../../models/auth.dart'; import '../../providers/auth_provider.dart'; class CalendarIntegrationScreen extends ConsumerStatefulWidget { const CalendarIntegrationScreen({super.key}); @override ConsumerState createState() => _CalendarIntegrationScreenState(); } class _CalendarIntegrationScreenState extends ConsumerState { List _providers = []; Map? _status; bool _isLoading = true; @override void initState() { super.initState(); _loadData(); } Future _loadData() async { setState(() => _isLoading = true); try { final api = ref.read(apiClientProvider); final providersResp = await api.get(Endpoints.calendarProviders); final statusResp = await api.get(Endpoints.calendarStatus); if (mounted) { setState(() { _providers = providersResp.data as List? ?? []; _status = statusResp.data as Map?; }); } } catch (_) {} if (mounted) setState(() => _isLoading = false); } @override Widget build(BuildContext context) { final user = ref.watch(authProvider).user; final isConnected = user?.calendarProvider != null; return Scaffold( appBar: AppBar(title: const Text('Интеграция календаря')), body: _isLoading ? const Center(child: CircularProgressIndicator()) : ListView( padding: const EdgeInsets.all(16), children: [ if (isConnected) ...[ Card( color: VoIdeaColors.success.withOpacity(0.05), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ const Icon(Icons.check_circle, color: VoIdeaColors.success), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Календарь подключён', style: TextStyle( fontWeight: FontWeight.w600)), Text( 'Провайдер: ${user!.calendarProvider}', style: const TextStyle(fontSize: 12), ), ], ), ), TextButton( onPressed: _disconnectCalendar, child: const Text('Отключить', style: TextStyle( color: VoIdeaColors.error)), ), ], ), ), ), ] else Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ const Icon(Icons.calendar_month, size: 48, color: VoIdeaColors.primary), const SizedBox(height: 16), const Text( 'Подключите календарь для автоматического создания событий из идей', textAlign: TextAlign.center, ), const SizedBox(height: 24), ...(_providers.map((p) { final name = p['name'] as String? ?? ''; final icon = name == 'google' ? Icons.g_mobiledata : name == 'yandex' ? Icons.cloud : Icons.calendar_today; return Padding( padding: const EdgeInsets.only(bottom: 8), child: OutlinedButton.icon( onPressed: () => _connectProvider(name), icon: Icon(icon), label: Text(_providerLabel(name)), ), ); })), ], ), ), ), if (_status != null) ...[ const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Статус календаря', style: TextStyle( fontWeight: FontWeight.w600)), const SizedBox(height: 8), ...(_status!.entries.map((e) => Padding( padding: const EdgeInsets.only(bottom: 4), child: Row( children: [ Text('${e.key}: ', style: const TextStyle( fontSize: 13, color: VoIdeaColors.muted)), Text('${e.value}', style: const TextStyle(fontSize: 13)), ], ), ))), ], ), ), ), ], ], ), ); } String _providerLabel(String name) { switch (name) { case 'google': return 'Google Calendar'; case 'yandex': return 'Яндекс Календарь'; case 'apple': return 'Apple Календарь'; default: return name; } } Future _connectProvider(String provider) async { try { final api = ref.read(apiClientProvider); final response = await api.get('${Endpoints.calendarProviders}/$provider'); final url = response.data['url'] as String?; if (url != null && await canLaunchUrl(Uri.parse(url))) { await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication); } } catch (_) {} } Future _disconnectCalendar() async { try { final api = ref.read(apiClientProvider); await api.post(Endpoints.calendarDisconnect); if (mounted) _loadData(); } catch (_) {} } }