part of 'sidebar_navigation.dart';

class SidebarTaskItem {
  const SidebarTaskItem({
    required this.sessionKey,
    required this.title,
    required this.preview,
    required this.updatedAtMs,
    required this.executionTarget,
    required this.isCurrent,
    required this.pending,
    this.lifecycleStatus = '',
    this.lastResultCode = '',
    this.draft = false,
  });

  final String sessionKey;
  final String title;
  final String preview;
  final double? updatedAtMs;
  final AssistantExecutionTarget executionTarget;
  final bool isCurrent;
  final bool pending;
  final String lifecycleStatus;
  final String lastResultCode;
  final bool draft;
}

class SidebarTaskSection extends StatefulWidget {
  const SidebarTaskSection({
    super.key,
    required this.currentSection,
    required this.items,
    required this.visibleExecutionTargets,
    required this.skillCount,
    required this.showCollapseControl,
    required this.onCycleSidebarState,
    this.onRefreshTasks,
    this.onCreateTask,
    this.onReturnToAssistant,
    this.onSelectTask,
    this.onArchiveTask,
    this.onRenameTask,
  });

  final WorkspaceDestination currentSection;
  final List<SidebarTaskItem> items;
  final List<AssistantExecutionTarget> visibleExecutionTargets;
  final int skillCount;
  final bool showCollapseControl;
  final VoidCallback onCycleSidebarState;
  final Future<void> Function()? onRefreshTasks;
  final Future<void> Function()? onCreateTask;
  final VoidCallback? onReturnToAssistant;
  final Future<void> Function(String sessionKey)? onSelectTask;
  final Future<void> Function(String sessionKey)? onArchiveTask;
  final Future<void> Function(String sessionKey, String title)? onRenameTask;

  @override
  State<SidebarTaskSection> createState() => _SidebarTaskSectionState();
}

class _SidebarTaskSectionState extends State<SidebarTaskSection> {
  final TextEditingController _searchController = TextEditingController();
  final ScrollController _scrollController = ScrollController();
  final Set<AssistantExecutionTarget> _expandedTargets =
      <AssistantExecutionTarget>{};
  String _query = '';

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

  @override
  void didUpdateWidget(covariant SidebarTaskSection oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.items != widget.items) {
      _syncExpandedTargets();
    }
  }

  @override
  void dispose() {
    _searchController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final palette = context.palette;
    final filteredItems = _filteredItems();
    final groups = _groupedItems(filteredItems);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(4, 0, 4, 8),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Expanded(
                child: TextField(
                  key: const Key('workspace-sidebar-task-search'),
                  controller: _searchController,
                  onChanged: (value) {
                    setState(() {
                      _query = value.trim().toLowerCase();
                    });
                  },
                  decoration: InputDecoration(
                    hintText: appText('搜索任务', 'Search tasks'),
                    prefixIcon: const Icon(Icons.search_rounded),
                    suffixIcon: _query.isEmpty
                        ? null
                        : IconButton(
                            tooltip: appText('清除搜索', 'Clear search'),
                            onPressed: () {
                              _searchController.clear();
                              setState(() {
                                _query = '';
                              });
                            },
                            icon: const Icon(Icons.close_rounded),
                          ),
                  ),
                ),
              ),
              if (widget.showCollapseControl) ...[
                const SizedBox(width: AppSpacing.xs),
                Tooltip(
                  message: appText('收起侧边栏', 'Collapse sidebar'),
                  child: IconButton(
                    key: const Key('workspace-sidebar-collapse-button'),
                    onPressed: widget.onCycleSidebarState,
                    visualDensity: VisualDensity.compact,
                    splashRadius: 18,
                    padding: EdgeInsets.zero,
                    constraints: const BoxConstraints.tightFor(
                      width: 28,
                      height: 28,
                    ),
                    style: IconButton.styleFrom(
                      padding: EdgeInsets.zero,
                      minimumSize: const Size(28, 28),
                      maximumSize: const Size(28, 28),
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      backgroundColor: Colors.transparent,
                      foregroundColor: palette.textSecondary,
                      overlayColor: palette.chromeSurfacePressed,
                      side: BorderSide.none,
                      shape: const CircleBorder(),
                    ),
                    icon: const Icon(
                      Icons.keyboard_double_arrow_left_rounded,
                      size: 20,
                    ),
                  ),
                ),
              ],
            ],
          ),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(4, 0, 4, 8),
          child: widget.currentSection == WorkspaceDestination.settings
              ? _SidebarBackToAssistantButton(
                  onPressed: widget.onReturnToAssistant,
                )
              : FilledButton.tonalIcon(
                  key: const Key('workspace-sidebar-new-task-button'),
                  onPressed: widget.onCreateTask == null
                      ? null
                      : () async {
                          await widget.onCreateTask!();
                        },
                  icon: const Icon(Icons.edit_note_rounded),
                  label: Text(appText('新对话', 'New conversation')),
                  style: FilledButton.styleFrom(
                    minimumSize: const Size(0, 40),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10),
                    ),
                  ),
                ),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(4, 4, 4, 6),
          child: Text(
            appText('任务列表', 'Task list'),
            style: theme.textTheme.titleSmall,
          ),
        ),
        Expanded(
          child: Scrollbar(
            child: ListView(
              key: const PageStorageKey<String>('workspace-sidebar-task-list'),
              controller: _scrollController,
              padding: const EdgeInsets.fromLTRB(0, 0, 0, 4),
              children: [
                for (final group in groups)
                  KeyedSubtree(
                    key: ValueKey<String>(
                      'workspace-sidebar-task-group-block-${group.executionTarget.name}',
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        _SidebarTaskGroupHeader(
                          executionTarget: group.executionTarget,
                          count: group.items.length,
                          expanded: _expandedTargets.contains(
                            group.executionTarget,
                          ),
                          onTap: () {
                            setState(() {
                              if (_expandedTargets.contains(
                                group.executionTarget,
                              )) {
                                _expandedTargets.remove(group.executionTarget);
                              } else {
                                _expandedTargets.add(group.executionTarget);
                              }
                            });
                          },
                        ),
                        if (_expandedTargets.contains(
                          group.executionTarget,
                        )) ...[
                          if (group.items.isEmpty)
                            Padding(
                              padding: const EdgeInsets.fromLTRB(28, 0, 8, 6),
                              child: Text(
                                appText('当前分组没有任务。', 'No tasks in this group.'),
                                style: theme.textTheme.bodySmall?.copyWith(
                                  color: palette.textMuted,
                                ),
                              ),
                            ),
                          for (final item in group.items)
                            Padding(
                              key: ValueKey<String>(
                                'workspace-sidebar-task-row-${item.sessionKey}',
                              ),
                              padding: const EdgeInsets.only(bottom: 4),
                              child: _SidebarTaskTile(
                                item: item,
                                onTap: widget.onSelectTask == null
                                    ? null
                                    : () async {
                                        await widget.onSelectTask!(
                                          item.sessionKey,
                                        );
                                      },
                                onArchive:
                                    widget.onArchiveTask == null || item.pending
                                    ? null
                                    : () async {
                                        await widget.onArchiveTask!(
                                          item.sessionKey,
                                        );
                                      },
                                onRename: widget.onRenameTask == null
                                    ? null
                                    : () async {
                                        final renamed = await _promptRenameTask(
                                          context,
                                          item.title,
                                        );
                                        if (!mounted || renamed == null) {
                                          return;
                                        }
                                        await widget.onRenameTask!(
                                          item.sessionKey,
                                          renamed,
                                        );
                                      },
                              ),
                            ),
                        ],
                        const SizedBox(height: 4),
                      ],
                    ),
                  ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  List<SidebarTaskItem> _filteredItems() {
    if (_query.isEmpty) {
      return widget.items;
    }
    return widget.items
        .where((item) {
          final haystack = '${item.title}\n${item.preview}\n${item.sessionKey}'
              .toLowerCase();
          return haystack.contains(_query);
        })
        .toList(growable: false);
  }

  List<_SidebarTaskGroup> _groupedItems(List<SidebarTaskItem> items) {
    final compactTargets = compactAssistantExecutionTargets(
      widget.visibleExecutionTargets,
    );
    final grouped = <AssistantExecutionTarget, List<SidebarTaskItem>>{
      for (final target in compactTargets) target: <SidebarTaskItem>[],
    };
    for (final item in items) {
      final bucket =
          grouped[collapseAssistantExecutionTargetForDisplay(
            item.executionTarget,
          )];
      if (bucket == null) {
        continue;
      }
      bucket.add(item);
    }
    return compactTargets
        .map(
          (target) => _SidebarTaskGroup(
            executionTarget: target,
            items: grouped[target]!,
          ),
        )
        .toList(growable: false);
  }

  Future<String?> _promptRenameTask(
    BuildContext context,
    String currentTitle,
  ) async {
    final input = TextEditingController(text: currentTitle);
    final result = await showDialog<String>(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(appText('重命名任务', 'Rename task')),
        content: TextField(
          key: const Key('workspace-sidebar-task-rename-input'),
          controller: input,
          autofocus: true,
          decoration: InputDecoration(
            labelText: appText('任务名称', 'Task name'),
            hintText: appText('留空后恢复默认名称', 'Leave empty to restore default'),
          ),
          onSubmitted: (value) => Navigator.of(context).pop(value.trim()),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: Text(appText('取消', 'Cancel')),
          ),
          FilledButton(
            onPressed: () => Navigator.of(context).pop(input.text.trim()),
            child: Text(appText('保存', 'Save')),
          ),
        ],
      ),
    );
    input.dispose();
    return result;
  }

  void _syncExpandedTargets() {
    if (_expandedTargets.isNotEmpty) {
      return;
    }
    _expandedTargets.addAll(
      compactAssistantExecutionTargets(widget.visibleExecutionTargets),
    );
  }
}

class _SidebarBackToAssistantButton extends StatelessWidget {
  const _SidebarBackToAssistantButton({required this.onPressed});

  final VoidCallback? onPressed;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;
    final theme = Theme.of(context);
    return Material(
      color: Colors.transparent,
      child: InkWell(
        key: const Key('workspace-sidebar-back-to-chat-button'),
        onTap: onPressed,
        borderRadius: BorderRadius.circular(18),
        child: Ink(
          height: 56,
          decoration: BoxDecoration(
            color: palette.surfaceSecondary,
            borderRadius: BorderRadius.circular(18),
            border: Border.all(color: palette.strokeSoft),
          ),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 12),
            child: Row(
              children: [
                Container(
                  width: 36,
                  height: 36,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(color: palette.textPrimary, width: 1.8),
                  ),
                  child: Icon(
                    Icons.arrow_back_rounded,
                    size: 24,
                    color: palette.textPrimary,
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Text(
                    appText('返回聊天', 'Back to chat'),
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: theme.textTheme.titleMedium?.copyWith(
                      fontWeight: FontWeight.w700,
                      color: palette.textPrimary,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _SidebarTaskGroup {
  const _SidebarTaskGroup({required this.executionTarget, required this.items});

  final AssistantExecutionTarget executionTarget;
  final List<SidebarTaskItem> items;
}

class _SidebarTaskGroupHeader extends StatelessWidget {
  const _SidebarTaskGroupHeader({
    required this.executionTarget,
    required this.count,
    required this.expanded,
    required this.onTap,
  });

  final AssistantExecutionTarget executionTarget;
  final int count;
  final bool expanded;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;
    final theme = Theme.of(context);
    return Material(
      color: Colors.transparent,
      child: InkWell(
        key: ValueKey<String>(
          'workspace-sidebar-task-group-${executionTarget.name}',
        ),
        borderRadius: BorderRadius.circular(8),
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.fromLTRB(4, 4, 4, 2),
          child: Row(
            children: [
              Icon(
                expanded
                    ? Icons.keyboard_arrow_down_rounded
                    : Icons.keyboard_arrow_right_rounded,
                size: 16,
                color: palette.textMuted,
              ),
              const SizedBox(width: 4),
              Icon(
                _sidebarTaskTargetIcon(executionTarget),
                size: 14,
                color: palette.textMuted,
              ),
              const SizedBox(width: 6),
              Expanded(
                child: Text(
                  executionTarget.compactLabel,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: theme.textTheme.labelMedium?.copyWith(
                    color: palette.textSecondary,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
              const SizedBox(width: 6),
              Text(
                '$count',
                style: theme.textTheme.bodySmall?.copyWith(
                  color: palette.textMuted,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SidebarTaskTile extends StatelessWidget {
  const _SidebarTaskTile({
    required this.item,
    this.onTap,
    this.onArchive,
    this.onRename,
  });

  final SidebarTaskItem item;
  final Future<void> Function()? onTap;
  final Future<void> Function()? onArchive;
  final Future<void> Function()? onRename;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;
    final theme = Theme.of(context);
    final statusInfo = _sidebarTaskStatusInfo(item);
    return Material(
      color: item.isCurrent ? palette.surfacePrimary : Colors.transparent,
      borderRadius: BorderRadius.circular(8),
      child: InkWell(
        key: ValueKey<String>('workspace-sidebar-task-item-${item.sessionKey}'),
        borderRadius: BorderRadius.circular(8),
        onTap: onTap == null
            ? null
            : () async {
                await onTap!();
              },
        onLongPress: onRename == null
            ? null
            : () async {
                await onRename!();
              },
        onSecondaryTap: onRename == null
            ? null
            : () async {
                await onRename!();
              },
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
          decoration: BoxDecoration(
            color: item.isCurrent
                ? palette.surfaceSecondary
                : Colors.transparent,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(
              color: item.isCurrent ? palette.strokeSoft : Colors.transparent,
            ),
          ),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: 24,
                height: 24,
                decoration: BoxDecoration(
                  color: item.pending
                      ? palette.accentMuted.withValues(alpha: 0.88)
                      : palette.surfacePrimary,
                  borderRadius: BorderRadius.circular(6),
                ),
                child: Icon(
                  item.draft
                      ? Icons.edit_note_rounded
                      : item.pending
                      ? Icons.play_arrow_rounded
                      : Icons.task_alt_rounded,
                  size: 15,
                  color: item.pending ? palette.accent : palette.textSecondary,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      item.title,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: theme.textTheme.titleSmall?.copyWith(
                        fontWeight: item.isCurrent
                            ? FontWeight.w700
                            : FontWeight.w600,
                      ),
                    ),
                    if (item.preview.trim().isNotEmpty) ...[
                      const SizedBox(height: 2),
                      Text(
                        item.preview.trim(),
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                        style: theme.textTheme.bodySmall?.copyWith(
                          color: palette.textMuted,
                        ),
                      ),
                    ],
                  ],
                ),
              ),
              const SizedBox(width: 8),
              Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    _sidebarTaskUpdatedAtLabel(item.updatedAtMs),
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: palette.textMuted,
                    ),
                  ),
                  if (statusInfo != null)
                    Padding(
                      padding: const EdgeInsets.only(top: 4),
                      child: _SidebarTaskStatusChip(status: statusInfo),
                    ),
                  if (onArchive != null)
                    IconButton(
                      key: ValueKey<String>(
                        'workspace-sidebar-task-archive-${item.sessionKey}',
                      ),
                      tooltip: appText('归档任务', 'Archive task'),
                      visualDensity: VisualDensity.compact,
                      splashRadius: 12,
                      onPressed: () async {
                        await onArchive!();
                      },
                      icon: Icon(
                        Icons.archive_outlined,
                        size: 18,
                        color: palette.textMuted,
                      ),
                    ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SidebarTaskStatusChip extends StatelessWidget {
  const _SidebarTaskStatusChip({required this.status});

  final StatusInfo status;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;
    final colors = switch (status.tone) {
      StatusTone.accent => (palette.accentMuted, palette.accent),
      StatusTone.warning => (palette.surfacePrimary, palette.warning),
      StatusTone.success => (palette.surfacePrimary, palette.success),
      StatusTone.danger => (palette.surfacePrimary, palette.danger),
      StatusTone.neutral => (palette.surfacePrimary, palette.textMuted),
    };
    return Container(
      key: const Key('workspace-sidebar-task-status-chip'),
      constraints: const BoxConstraints(minHeight: 18),
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: colors.$1,
        borderRadius: BorderRadius.circular(999),
        border: Border.all(color: colors.$2.withValues(alpha: 0.22)),
      ),
      child: Text(
        status.label,
        maxLines: 1,
        overflow: TextOverflow.ellipsis,
        style: Theme.of(context).textTheme.labelSmall?.copyWith(
          color: colors.$2,
          fontWeight: FontWeight.w700,
        ),
      ),
    );
  }
}

StatusInfo? _sidebarTaskStatusInfo(SidebarTaskItem item) {
  if (item.draft && !item.pending) {
    return null;
  }
  final lifecycleStatus = item.lifecycleStatus.trim().toLowerCase();
  final lastResultCode = item.lastResultCode.trim();
  final normalizedResultCode = lastResultCode.toLowerCase();
  if (item.pending &&
      (lifecycleStatus == 'queued' || normalizedResultCode == 'queued')) {
    return StatusInfo(appText('Pending', 'Pending'), StatusTone.warning);
  }
  if (item.pending ||
      lifecycleStatus == 'running' ||
      normalizedResultCode == 'running') {
    return StatusInfo(appText('运行', 'Running'), StatusTone.accent);
  }
  if (lifecycleStatus == 'ready' &&
      lastResultCode.isNotEmpty &&
      normalizedResultCode != 'queued' &&
      normalizedResultCode != 'running') {
    return StatusInfo(appText('结束', 'Done'), StatusTone.neutral);
  }
  return null;
}

String _sidebarTaskUpdatedAtLabel(double? updatedAtMs) {
  if (updatedAtMs == null) {
    return '';
  }
  final timestamp = DateTime.fromMillisecondsSinceEpoch(updatedAtMs.round());
  final now = DateTime.now();
  final delta = now.difference(timestamp);
  if (delta.inMinutes < 1) {
    return appText('刚刚', 'Just now');
  }
  if (delta.inHours < 1) {
    return appText('${delta.inMinutes} 分钟前', '${delta.inMinutes}m ago');
  }
  if (delta.inDays < 1) {
    return appText('${delta.inHours} 小时前', '${delta.inHours}h ago');
  }
  if (delta.inDays < 7) {
    return appText('${delta.inDays} 天前', '${delta.inDays}d ago');
  }
  return '${timestamp.month}/${timestamp.day}';
}

IconData _sidebarTaskTargetIcon(AssistantExecutionTarget target) {
  return switch (target) {
    AssistantExecutionTarget.agent => Icons.hub_rounded,
    AssistantExecutionTarget.gateway => Icons.cloud_outlined,
  };
}
