import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:file_picker/file_picker.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../../core/app_colors.dart';
import '../../core/app_design_tokens.dart';
import '../../core/app_module_visuals.dart';
import '../../core/navigation_provider.dart';
import '../../providers/auth_provider.dart';
import '../../providers/chat_provider.dart';
import '../../providers/data_providers.dart';
import '../../widgets/health_drawer.dart';
import '../../widgets/keyboard_lift.dart';
import '../diet/diet_capture_page.dart';
import 'widgets/chat_messages_view.dart';

class HomePage extends ConsumerStatefulWidget {
  const HomePage({super.key});
  @override
  ConsumerState<HomePage> createState() => _HomePageState();
}

class _HomePageState extends ConsumerState<HomePage>
    with WidgetsBindingObserver {
  final _textCtrl = TextEditingController();
  final _scrollCtrl = ScrollController();
  final _focusNode = FocusNode();
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  String? _pickedImagePath;
  Timer? _notificationTimer;
  double _conversationDragDistance = 0;

  void _startConversationDrawerDrag(DragStartDetails details) {
    _conversationDragDistance = 0;
  }

  void _updateConversationDrawerDrag(DragUpdateDetails details) {
    _conversationDragDistance += details.delta.dx;
    if (_conversationDragDistance < 0) {
      _conversationDragDistance = 0;
    }
    if (_conversationDragDistance >= 42) {
      _conversationDragDistance = 0;
      _scaffoldKey.currentState?.openDrawer();
    }
  }

  void _endConversationDrawerDrag(DragEndDetails details) {
    _conversationDragDistance = 0;
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _scheduleScrollToLatest();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _checkDueNotifications();
      _refreshTodayHealthIfCached();
    });
    _notificationTimer = Timer.periodic(
      const Duration(minutes: 2),
      (_) => _checkDueNotifications(),
    );
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _checkDueNotifications();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _notificationTimer?.cancel();
    _textCtrl.dispose();
    _scrollCtrl.dispose();
    _focusNode.dispose();
    super.dispose();
  }

  void _sendMessage() {
    final text = _textCtrl.text.trim();
    final imagePath = _pickedImagePath;
    if (text.isEmpty && imagePath == null) return;
    _textCtrl.clear();
    _dismissKeyboard();
    setState(() => _pickedImagePath = null);
    if (imagePath != null) {
      ref.read(chatProvider.notifier).sendImage(imagePath, text);
    } else {
      ref.read(chatProvider.notifier).sendMessage(text);
    }
  }

  void _refreshTodayHealthIfCached() {
    if (!ref.read(todayHealthSnapshotProvider).hasValue) return;
    ref.invalidate(latestHealthProvider);
    ref.invalidate(medicationReminderProvider);
    ref.invalidate(currentExercisePlanProvider);
  }

  void _scheduleScrollToLatest() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted || !_scrollCtrl.hasClients) return;
      _scrollCtrl.jumpTo(_scrollCtrl.position.maxScrollExtent);

      // Lazy list items can refine the final extent after the first layout.
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (!mounted || !_scrollCtrl.hasClients) return;
        _scrollCtrl.jumpTo(_scrollCtrl.position.maxScrollExtent);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    final auth = ref.watch(authProvider);
    final user = auth.user;

    ref.listen(cameraActionProvider, (prev, next) {
      if (next == 'camera') {
        _pickImage(ImageSource.camera);
        ref.read(cameraActionProvider.notifier).clear();
      } else if (next == 'gallery') {
        _pickImage(ImageSource.gallery);
        ref.read(cameraActionProvider.notifier).clear();
      }
    });
    ref.listen(dietActionProvider, (prev, next) {
      if (next == 'pickFoodCamera') {
        _pickFoodImage(ImageSource.camera);
        ref.read(dietActionProvider.notifier).clear();
      } else if (next == 'pickFoodGallery') {
        _pickFoodImage(ImageSource.gallery);
        ref.read(dietActionProvider.notifier).clear();
      }
    });

    ref.listen<int>(chatProvider.select((state) => state.messages.length), (
      previous,
      current,
    ) {
      if (current <= (previous ?? 0)) return;
      _scheduleScrollToLatest();
    });

    return Scaffold(
      key: _scaffoldKey,
      resizeToAvoidBottomInset: false,
      backgroundColor: const Color(0xFFFFFCFF),
      drawer: const HealthDrawer(),
      drawerEnableOpenDragGesture: false,
      body: DecoratedBox(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [Color(0xFFF0EDFF), Color(0xFFE6ECFF)],
          ),
        ),
        child: SafeArea(
          child: Column(
            children: [
              _buildHeader(user),
              Expanded(
                child: GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onHorizontalDragStart: _startConversationDrawerDrag,
                  onHorizontalDragUpdate: _updateConversationDrawerDrag,
                  onHorizontalDragEnd: _endConversationDrawerDrag,
                  onHorizontalDragCancel: () => _conversationDragDistance = 0,
                  child: RepaintBoundary(
                    child: _HomeMessages(scrollCtrl: _scrollCtrl),
                  ),
                ),
              ),
              KeyboardLift(child: _buildBottomBar(context)),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildHeader(dynamic user) {
    final name = (user?.name != null && user!.name!.isNotEmpty)
        ? user.name
        : '用户';
    final unreadCount = ref.watch(notificationUnreadCountProvider).value ?? 0;
    return Container(
      padding: const EdgeInsets.fromLTRB(14, 8, 14, 6),
      child: Row(
        children: [
          Builder(
            builder: (ctx) {
              return _HeaderIconButton(
                icon: LucideIcons.menu,
                onTap: () => Scaffold.of(ctx).openDrawer(),
              );
            },
          ),
          const SizedBox(width: 14),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  '小脉健康',
                  style: TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w600,
                    color: AppColors.textHint,
                  ),
                ),
                const SizedBox(height: 2),
                Text(
                  '${_getGreeting()}，$name',
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w600,
                    color: AppColors.textPrimary,
                  ),
                ),
              ],
            ),
          ),
          _HeaderIconButton(
            icon: LucideIcons.bell,
            badgeCount: unreadCount,
            onTap: () => pushRoute(ref, 'notifications'),
          ),
        ],
      ),
    );
  }

  String _getGreeting() {
    final hour = DateTime.now().hour;
    if (hour < 9) return '早上好';
    if (hour < 12) return '上午好';
    if (hour < 18) return '下午好';
    return '晚上好';
  }

  static final _agentDefs = [
    ActiveAgent.consultation,
    ActiveAgent.health,
    ActiveAgent.diet,
    ActiveAgent.medication,
    ActiveAgent.report,
    ActiveAgent.exercise,
  ];

  Widget _buildAgentBar() {
    final activeAgent = ref.watch(
      chatProvider.select((state) => state.activeAgent),
    );
    return SizedBox(
      height: 46,
      child: ListView.separated(
        scrollDirection: Axis.horizontal,
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 2),
        itemCount: _agentDefs.length,
        separatorBuilder: (_, _) => const SizedBox(width: 8),
        itemBuilder: (_, i) {
          final agent = _agentDefs[i];
          final visual = _agentVisual(agent);
          final selected = activeAgent == agent;
          return GestureDetector(
            onTap: () => ref
                .read(chatProvider.notifier)
                .triggerAgent(agent, visual.label),
            child: Container(
              decoration: BoxDecoration(
                color: selected ? null : Colors.transparent,
                gradient: selected ? AppColors.actionOutlineGradient : null,
                borderRadius: AppRadius.pillBorder,
              ),
              padding: const EdgeInsets.all(1.2),
              child: Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 11.8,
                  vertical: 7.8,
                ),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: AppRadius.pillBorder,
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      width: 18,
                      height: 18,
                      decoration: BoxDecoration(
                        gradient: visual.gradient,
                        borderRadius: BorderRadius.circular(6),
                      ),
                      child: Icon(
                        visual.icon,
                        size: 13,
                        color: visual.iconColor,
                      ),
                    ),
                    const SizedBox(width: 6),
                    Text(
                      visual.label,
                      style: const TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w700,
                        color: AppColors.textPrimary,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),
    );
  }

  ({String label, IconData icon, LinearGradient gradient, Color iconColor})
  _agentVisual(ActiveAgent agent) {
    ({String label, AppModuleVisual visual}) fromModule(
      String label,
      AppModuleVisual visual,
    ) => (label: label, visual: visual);

    final module = switch (agent) {
      ActiveAgent.health => fromModule('记数据', AppModuleVisuals.health),
      ActiveAgent.diet => fromModule('拍饮食', AppModuleVisuals.diet),
      ActiveAgent.medication => fromModule('药管家', AppModuleVisuals.medication),
      ActiveAgent.report => fromModule('报告', AppModuleVisuals.report),
      ActiveAgent.exercise => fromModule('运动', AppModuleVisuals.exercise),
      _ => null,
    };
    if (module != null) {
      return (
        label: module.label,
        icon: module.visual.icon,
        gradient: module.visual.gradient,
        iconColor: Colors.white,
      );
    }

    return switch (agent) {
      ActiveAgent.consultation => (
        label: 'AI问诊',
        icon: LucideIcons.messageCircle,
        gradient: AppColors.doctorGradient,
        iconColor: Colors.white,
      ),
      _ => (
        label: 'AI问诊',
        icon: LucideIcons.messageCircle,
        gradient: AppColors.primaryGradient,
        iconColor: Colors.white,
      ),
    };
  }

  Widget _buildBottomBar(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: 0.28),
        border: Border(
          top: BorderSide(color: Colors.white.withValues(alpha: 0.62)),
        ),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const SizedBox(height: 8),
          _buildAgentBar(),
          const SizedBox(height: 12),
          if (_pickedImagePath != null) _buildImagePreview(),
          _buildInputBar(),
        ],
      ),
    );
  }

  Widget _buildImagePreview() {
    return Container(
      margin: const EdgeInsets.fromLTRB(14, 8, 14, 0),
      padding: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: 0.9),
        borderRadius: BorderRadius.circular(14),
        border: Border.all(color: AppColors.borderLight),
      ),
      child: Row(
        children: [
          ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: Image.file(
              File(_pickedImagePath!),
              width: 48,
              height: 48,
              fit: BoxFit.cover,
            ),
          ),
          const SizedBox(width: 10),
          const Expanded(
            child: Text(
              '点击发送图片',
              style: TextStyle(fontSize: 14, color: AppColors.textSecondary),
            ),
          ),
          GestureDetector(
            onTap: () => setState(() => _pickedImagePath = null),
            child: const Icon(Icons.close, size: 20, color: AppColors.textHint),
          ),
        ],
      ),
    );
  }

  Widget _buildInputBar() {
    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 0, 12, 10),
      child: Container(
        padding: const EdgeInsets.fromLTRB(6, 5, 6, 5),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: AppRadius.pillBorder,
        ),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Material(
              color: Colors.transparent,
              child: InkWell(
                customBorder: const CircleBorder(),
                onTap: () => _showAttachmentPicker(context),
                child: Ink(
                  width: 38,
                  height: 38,
                  decoration: const BoxDecoration(
                    gradient: AppColors.primaryGradient,
                    shape: BoxShape.circle,
                  ),
                  child: const Icon(
                    LucideIcons.plus,
                    size: 21,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
            const SizedBox(width: 6),
            Expanded(
              child: ConstrainedBox(
                constraints: const BoxConstraints(maxHeight: 112),
                child: TextField(
                  controller: _textCtrl,
                  focusNode: _focusNode,
                  style: const TextStyle(
                    fontSize: 15,
                    color: AppColors.textPrimary,
                  ),
                  maxLines: null,
                  textInputAction: TextInputAction.newline,
                  decoration: const InputDecoration(
                    hintText: '输入你想说的...',
                    filled: false,
                    isDense: true,
                    contentPadding: EdgeInsets.symmetric(
                      horizontal: 4,
                      vertical: 12,
                    ),
                    border: InputBorder.none,
                    enabledBorder: InputBorder.none,
                    focusedBorder: InputBorder.none,
                  ),
                  onSubmitted: (_) => _sendMessage(),
                ),
              ),
            ),
            const SizedBox(width: 6),
            Material(
              color: Colors.transparent,
              child: InkWell(
                customBorder: const CircleBorder(),
                onTap: _sendMessage,
                child: Ink(
                  width: 38,
                  height: 38,
                  decoration: const BoxDecoration(
                    gradient: AppColors.primaryGradient,
                    shape: BoxShape.circle,
                  ),
                  child: const Icon(
                    LucideIcons.send,
                    size: 18,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _showAttachmentPicker(BuildContext context) {
    _dismissKeyboard();
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (ctx) => SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 10),
          child: Wrap(
            children: [
              ListTile(
                leading: const Icon(
                  Icons.camera_alt_outlined,
                  color: AppColors.primary,
                ),
                title: const Text('拍照'),
                onTap: () {
                  Navigator.pop(ctx);
                  _dismissKeyboard();
                  _pickImage(ImageSource.camera);
                },
              ),
              ListTile(
                leading: const Icon(
                  Icons.photo_library_outlined,
                  color: AppColors.primary,
                ),
                title: const Text('从相册选择'),
                onTap: () {
                  Navigator.pop(ctx);
                  _dismissKeyboard();
                  _pickImage(ImageSource.gallery);
                },
              ),
              ListTile(
                leading: const Icon(
                  Icons.picture_as_pdf_outlined,
                  color: AppColors.primary,
                ),
                title: const Text('上传 PDF'),
                onTap: () async {
                  Navigator.pop(ctx);
                  await _pickPdf();
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _pickImage(ImageSource source) async {
    _dismissKeyboard();
    final picked = await ImagePicker().pickImage(
      source: source,
      imageQuality: 85,
    );
    _dismissKeyboard();
    if (picked != null) {
      final token = await ref.read(apiClientProvider).accessToken;
      if (token == null) return;
      setState(() => _pickedImagePath = picked.path);
      WidgetsBinding.instance.addPostFrameCallback((_) => _dismissKeyboard());
    }
  }

  void _dismissKeyboard() {
    _focusNode.unfocus();
    FocusManager.instance.primaryFocus?.unfocus();
  }

  Future<void> _pickPdf() async {
    _dismissKeyboard();
    final result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['pdf'],
      withData: false,
    );
    if (result == null || result.files.isEmpty) return;
    final pdfFile = result.files.first;
    final path = pdfFile.path;
    if (path == null || path.isEmpty) return;
    await ref
        .read(chatProvider.notifier)
        .sendPdf(path, pdfFile.name, _textCtrl.text.trim());
    _textCtrl.clear();
    _dismissKeyboard();
  }

  Future<void> _checkDueNotifications() async {
    try {
      await ref.read(inAppNotificationServiceProvider).checkDue();
    } catch (_) {
      // Network failures should not block the home page.
    } finally {
      ref.invalidate(notificationUnreadCountProvider);
    }
  }

  Future<void> _pickFoodImage(ImageSource source) async {
    final picked = await ImagePicker().pickImage(
      source: source,
      imageQuality: 80,
      maxWidth: 1024,
      maxHeight: 1024,
    );
    if (picked != null && mounted) {
      ref.read(dietProvider.notifier).reset();
      ref.read(dietProvider.notifier).setImage(picked.path);
      ref.read(dietProvider.notifier).analyzeImage();
      pushRoute(ref, 'dietCapture');
    }
  }
}

class _HomeMessages extends ConsumerWidget {
  final ScrollController scrollCtrl;

  const _HomeMessages({required this.scrollCtrl});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final messages = ref.watch(chatProvider.select((state) => state.messages));
    return ChatMessagesView(scrollCtrl: scrollCtrl, messages: messages);
  }
}

class _HeaderIconButton extends StatelessWidget {
  final IconData icon;
  final VoidCallback onTap;
  final int badgeCount;
  const _HeaderIconButton({
    required this.icon,
    required this.onTap,
    this.badgeCount = 0,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          Container(
            width: 44,
            height: 44,
            decoration: BoxDecoration(
              gradient: AppColors.surfaceGradient,
              borderRadius: BorderRadius.circular(14),
              border: Border.all(color: AppColors.borderLight),
              boxShadow: AppColors.cardShadowLight,
            ),
            child: Icon(icon, size: 20, color: AppColors.textPrimary),
          ),
          if (badgeCount > 0)
            Positioned(
              right: -5,
              top: -5,
              child: Container(
                constraints: const BoxConstraints(minWidth: 18, minHeight: 18),
                padding: const EdgeInsets.symmetric(horizontal: 4),
                decoration: BoxDecoration(
                  color: AppColors.error,
                  borderRadius: BorderRadius.circular(10),
                  border: Border.all(color: Colors.white, width: 2),
                ),
                alignment: Alignment.center,
                child: Text(
                  badgeCount > 99 ? '99+' : '$badgeCount',
                  style: const TextStyle(
                    color: Colors.white,
                    fontSize: 10,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }
}
