import 'package:flutter/material.dart';

import '../features/mobile/mobile_shell.dart';
import '../i18n/app_language.dart';
import '../models/app_models.dart';
import '../runtime/runtime_models.dart';
import '../theme/app_palette.dart';
import '../widgets/detail_drawer.dart';
import '../widgets/pane_resize_handle.dart';
import '../widgets/sidebar_navigation.dart';
import 'app_controller.dart';
import 'app_controller_desktop_thread_binding.dart';
import 'ui_feature_manifest.dart';
import 'workspace_page_registry.dart';

class AppShell extends StatefulWidget {
  const AppShell({super.key, required this.controller});

  final AppController controller;
  @override
  State<AppShell> createState() => _AppShellState();
}

class _AppShellState extends State<AppShell> {
  static const _sidebarMinWidth = 280.0;
  static const _sidebarViewportPadding = 72.0;
  static const _mainContentMinWidth = 640.0;
  static const _sidebarExpandedBaseWidth = 336.0;
  static const _desktopDestinations = <WorkspaceDestination>[
    WorkspaceDestination.assistant,
    WorkspaceDestination.settings,
  ];
  double? _sidebarExpandedWidth;

  static const _mobileDestinations = [
    WorkspaceDestination.assistant,
    WorkspaceDestination.settings,
  ];

  double _clampSidebarWidth(double value, double viewportWidth) {
    final responsiveMax =
        (viewportWidth - _mainContentMinWidth - _sidebarViewportPadding).clamp(
          _sidebarMinWidth,
          viewportWidth - _sidebarViewportPadding,
        );
    return value.clamp(_sidebarMinWidth, responsiveMax).toDouble();
  }

  double _defaultSidebarWidth(AppLanguage language, double viewportWidth) {
    return _clampSidebarWidth(_sidebarExpandedBaseWidth, viewportWidth);
  }

  List<SidebarTaskItem> _buildSidebarTaskItems(AppController controller) {
    final currentSessionKey = controller.currentSessionKey.trim();
    return controller.assistantSessions
        .map((session) {
          final sessionKey = session.key.trim();
          final preview = session.lastMessagePreview?.trim() ?? '';
          final thread = controller.taskThreadForSessionInternal(sessionKey);
          return SidebarTaskItem(
            sessionKey: sessionKey,
            title: session.label.trim().isEmpty
                ? appText('新对话', 'New conversation')
                : session.label.trim(),
            preview: preview,
            updatedAtMs: session.updatedAtMs,
            executionTarget: controller.assistantExecutionTargetForSession(
              sessionKey,
            ),
            isCurrent: sessionKey == currentSessionKey,
            pending: controller.assistantSessionHasPendingRun(sessionKey),
            lifecycleStatus: thread?.lifecycleState.status ?? '',
            lastResultCode: thread?.lifecycleState.lastResultCode ?? '',
            draft: sessionKey.startsWith('draft:'),
          );
        })
        .toList(growable: false);
  }

  Future<void> _createSidebarConversation(
    AppController controller,
    List<AssistantExecutionTarget> visibleTargets,
  ) async {
    final sessionKey = controller.createAssistantDraftSessionKeyInternal();
    final target = pickDraftThreadExecutionTargetInternal(
      currentTarget: controller.currentAssistantExecutionTarget,
      visibleTargets: visibleTargets,
      localWorkspaceAvailable: controller.settings.workspacePath
          .trim()
          .isNotEmpty,
    );
    controller.initializeAssistantThreadContext(
      sessionKey,
      title: appText('新对话', 'New conversation'),
      executionTarget: target,
      messageViewMode: controller.currentAssistantMessageViewMode,
    );
    controller.navigateTo(WorkspaceDestination.assistant);
    await controller.switchSession(sessionKey);
  }

  void _toggleSidebarVisibility(AppController controller) {
    controller.setSidebarState(
      controller.sidebarState == AppSidebarState.hidden
          ? AppSidebarState.expanded
          : AppSidebarState.hidden,
    );
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: widget.controller,
      builder: (context, _) {
        final controller = widget.controller;
        final palette = context.palette;
        return Scaffold(
          body: SafeArea(
            bottom: false,
            child: Column(
              children: [
                if ((controller.startupTaskThreadWarning ?? '')
                    .trim()
                    .isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
                    child: Container(
                      width: double.infinity,
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: palette.accentMuted,
                        borderRadius: BorderRadius.circular(16),
                        border: Border.all(color: palette.warning),
                      ),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Expanded(
                            child: Text(
                              controller.startupTaskThreadWarning!,
                              style: Theme.of(context).textTheme.bodyMedium,
                            ),
                          ),
                          const SizedBox(width: 12),
                          TextButton(
                            onPressed:
                                controller.dismissStartupTaskThreadWarning,
                            child: Text(appText('关闭', 'Dismiss')),
                          ),
                        ],
                      ),
                    ),
                  ),
                Expanded(
                  child: LayoutBuilder(
                    builder: (context, constraints) {
                      final palette = context.palette;
                      final platform = Theme.of(context).platform;
                      final isCompactMobile =
                          (platform == TargetPlatform.iOS ||
                              platform == TargetPlatform.android) &&
                          constraints.maxWidth < 900;
                      final isMobile = constraints.maxWidth < 900;
                      final sidebarState = controller.sidebarState;
                      final showSidebar =
                          sidebarState != AppSidebarState.hidden;
                      final uiFeatures = controller.featuresFor(
                        resolveUiFeaturePlatformFromContext(context),
                      );
                      final visibleExecutionTargets = controller
                          .visibleAssistantExecutionTargets(
                            uiFeatures.availableExecutionTargets,
                          );
                      final sidebarTaskItems = _buildSidebarTaskItems(
                        controller,
                      );
                      final expandedSidebarWidth = _clampSidebarWidth(
                        _sidebarExpandedWidth ??
                            _defaultSidebarWidth(
                              controller.appLanguage,
                              constraints.maxWidth,
                            ),
                        constraints.maxWidth,
                      );
                      final showPinnedDetail =
                          controller.detailPanel != null &&
                          constraints.maxWidth > 1280;
                      final mobileDestination = controller.destination;
                      final availableMobileDestinations = _mobileDestinations
                          .where(controller.capabilities.supportsDestination)
                          .toList(growable: false);
                      final resolvedMobileDestination =
                          availableMobileDestinations.contains(
                            mobileDestination,
                          )
                          ? mobileDestination
                          : (availableMobileDestinations.isEmpty
                                ? mobileDestination
                                : availableMobileDestinations.first);

                      void openMobileDetail(DetailPanelData detail) {
                        showModalBottomSheet<void>(
                          context: context,
                          isScrollControlled: true,
                          backgroundColor: Colors.transparent,
                          builder: (sheetContext) {
                            return FractionallySizedBox(
                              heightFactor: 0.92,
                              child: DetailSheet(
                                data: detail,
                                onClose: () => Navigator.of(sheetContext).pop(),
                              ),
                            );
                          },
                        );
                      }

                      if (isCompactMobile) {
                        return MobileShell(controller: controller);
                      }

                      if (isMobile) {
                        return Stack(
                          children: [
                            Column(
                              children: [
                                Expanded(
                                  child: Padding(
                                    padding: const EdgeInsets.fromLTRB(
                                      12,
                                      12,
                                      12,
                                      0,
                                    ),
                                    child: ClipRRect(
                                      borderRadius: BorderRadius.circular(24),
                                      child: Container(
                                        color: palette.canvas.withValues(
                                          alpha: 0.18,
                                        ),
                                        child: _pageForDestination(
                                          resolvedMobileDestination,
                                          openMobileDetail,
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.fromLTRB(
                                    12,
                                    10,
                                    12,
                                    12,
                                  ),
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(24),
                                    child: NavigationBar(
                                      selectedIndex:
                                          availableMobileDestinations.isEmpty
                                          ? 0
                                          : availableMobileDestinations.indexOf(
                                              resolvedMobileDestination,
                                            ),
                                      onDestinationSelected: (index) {
                                        controller.navigateTo(
                                          availableMobileDestinations[index],
                                        );
                                      },
                                      destinations: availableMobileDestinations
                                          .map(
                                            (destination) =>
                                                NavigationDestination(
                                                  icon: Icon(destination.icon),
                                                  label: destination.label,
                                                ),
                                          )
                                          .toList(),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                            const SizedBox.shrink(),
                          ],
                        );
                      }

                      return Stack(
                        children: [
                          Row(
                            children: [
                              if (showSidebar)
                                SidebarNavigation(
                                  currentSection: controller.destination,
                                  sidebarState: sidebarState,
                                  appLanguage: controller.appLanguage,
                                  themeMode: controller.themeMode,
                                  onSectionChanged: (destination) {
                                    if (destination ==
                                        WorkspaceDestination.settings) {
                                      controller.openSettings(
                                        tab: SettingsTab.gateway,
                                      );
                                      return;
                                    }
                                    controller.navigateTo(destination);
                                  },
                                  onToggleLanguage:
                                      controller.toggleAppLanguage,
                                  onCycleSidebarState: () =>
                                      _toggleSidebarVisibility(controller),
                                  onExpandFromCollapsed: () =>
                                      _toggleSidebarVisibility(controller),
                                  onOpenHome: controller.navigateHome,
                                  onOpenAccount: () => controller.openSettings(
                                    tab: SettingsTab.gateway,
                                  ),
                                  onOpenThemeToggle: () =>
                                      controller.setThemeMode(
                                        controller.themeMode == ThemeMode.dark
                                            ? ThemeMode.light
                                            : ThemeMode.dark,
                                      ),
                                  accountName:
                                      controller.settings.accountUsername
                                          .trim()
                                          .isEmpty
                                      ? appText('本地操作员', 'Local Operator')
                                      : controller.settings.accountUsername,
                                  accountSubtitle:
                                      controller.settings.accountWorkspace
                                          .trim()
                                          .isEmpty
                                      ? appText('账号', 'Account')
                                      : controller.settings.accountWorkspace,
                                  accountWorkspaceFollowed: controller
                                      .settings
                                      .accountWorkspaceFollowed,
                                  onToggleAccountWorkspaceFollowed:
                                      controller.toggleAccountWorkspaceFollowed,
                                  onOpenOnlineWorkspace:
                                      controller.openOnlineWorkspace,
                                  expandedWidthOverride:
                                      sidebarState == AppSidebarState.expanded
                                      ? expandedSidebarWidth
                                      : null,
                                  marginOverride: const EdgeInsets.fromLTRB(
                                    4,
                                    4,
                                    4,
                                    0,
                                  ),
                                  favoriteDestinations: controller
                                      .assistantNavigationDestinations
                                      .toSet(),
                                  onToggleFavorite: controller
                                      .toggleAssistantNavigationDestination,
                                  availableDestinations: controller
                                      .capabilities
                                      .allowedDestinations,
                                  currentSettingsTab: controller.settingsTab,
                                  availableSettingsTabs:
                                      uiFeatures.availableSettingsTabs,
                                  onSettingsTabChanged: (tab) =>
                                      controller.openSettings(tab: tab),
                                  taskItems: sidebarTaskItems,
                                  visibleExecutionTargets:
                                      visibleExecutionTargets,
                                  assistantSkillCount:
                                      controller.currentAssistantSkillCount,
                                  onRefreshTasks: controller.refreshSessions,
                                  onCreateTask: () =>
                                      _createSidebarConversation(
                                        controller,
                                        visibleExecutionTargets,
                                      ),
                                  onReturnToAssistant: () {
                                    controller.navigateTo(
                                      WorkspaceDestination.assistant,
                                    );
                                  },
                                  onSelectTask: (sessionKey) async {
                                    controller.navigateTo(
                                      WorkspaceDestination.assistant,
                                    );
                                    await controller.switchSession(sessionKey);
                                  },
                                  onArchiveTask: (sessionKey) =>
                                      controller.saveAssistantTaskArchived(
                                        sessionKey,
                                        true,
                                      ),
                                  onRenameTask: (sessionKey, title) =>
                                      controller.saveAssistantTaskTitle(
                                        sessionKey,
                                        title,
                                      ),
                                ),
                              if (sidebarState == AppSidebarState.expanded)
                                PaneResizeHandle(
                                  axis: Axis.horizontal,
                                  extent: 8,
                                  onDelta: (delta) {
                                    setState(() {
                                      _sidebarExpandedWidth =
                                          _clampSidebarWidth(
                                            expandedSidebarWidth + delta,
                                            constraints.maxWidth,
                                          );
                                    });
                                  },
                                ),
                              Expanded(
                                child: Padding(
                                  padding: const EdgeInsets.fromLTRB(
                                    0,
                                    4,
                                    4,
                                    0,
                                  ),
                                  child: AnimatedPadding(
                                    duration: const Duration(milliseconds: 220),
                                    curve: Curves.easeOutCubic,
                                    padding: EdgeInsets.only(
                                      right: showPinnedDetail ? 336 : 0,
                                    ),
                                    child: DecoratedBox(
                                      decoration: BoxDecoration(
                                        color: palette.canvas,
                                      ),
                                      child: _buildCurrentPage(
                                        controller.openDetail,
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ],
                          ),
                          if (controller.detailPanel != null &&
                              !showPinnedDetail)
                            Positioned.fill(
                              child: GestureDetector(
                                onTap: controller.closeDetail,
                                child: Container(
                                  color: Colors.black.withValues(alpha: 0.12),
                                ),
                              ),
                            ),
                          if (controller.detailPanel != null)
                            Align(
                              alignment: Alignment.centerRight,
                              child: DetailDrawer(
                                data: controller.detailPanel!,
                                onClose: controller.closeDetail,
                              ),
                            ),
                          if (!showSidebar)
                            Positioned(
                              left: 8,
                              top: 8,
                              child: _SidebarRevealRail(
                                onExpand: () =>
                                    _toggleSidebarVisibility(controller),
                              ),
                            ),
                        ],
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Widget _buildCurrentPage(ValueChanged<DetailPanelData> onOpenDetail) {
    final currentDestination = _resolveDesktopDestination(
      widget.controller.destination,
    );
    return IndexedStack(
      index: _desktopDestinations.indexOf(currentDestination),
      children: _desktopDestinations
          .map((destination) => _pageForDestination(destination, onOpenDetail))
          .toList(),
    );
  }

  WorkspaceDestination _resolveDesktopDestination(
    WorkspaceDestination destination,
  ) {
    if (_desktopDestinations.contains(destination)) {
      return destination;
    }
    return WorkspaceDestination.assistant;
  }

  Widget _pageForDestination(
    WorkspaceDestination destination,
    ValueChanged<DetailPanelData> onOpenDetail,
  ) {
    return buildWorkspacePage(
      destination: destination,
      controller: widget.controller,
      onOpenDetail: onOpenDetail,
      surface: WorkspacePageSurface.desktop,
    );
  }
}

class _SidebarRevealRail extends StatefulWidget {
  const _SidebarRevealRail({required this.onExpand});

  final VoidCallback onExpand;

  @override
  State<_SidebarRevealRail> createState() => _SidebarRevealRailState();
}

class _SidebarRevealRailState extends State<_SidebarRevealRail> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;

    return MouseRegion(
      onEnter: (_) => setState(() => _hovered = true),
      onExit: (_) => setState(() => _hovered = false),
      child: Tooltip(
        message: appText('展开导航', 'Expand sidebar'),
        child: GestureDetector(
          onTap: widget.onExpand,
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 180),
            width: _hovered ? 40 : 32,
            height: _hovered ? 40 : 32,
            decoration: BoxDecoration(
              color: _hovered ? palette.surfacePrimary : palette.chromeSurface,
              borderRadius: BorderRadius.circular(999),
            ),
            child: Icon(
              Icons.keyboard_double_arrow_right_rounded,
              size: 18,
              color: palette.textSecondary,
            ),
          ),
        ),
      ),
    );
  }
}
