// ignore_for_file: unused_import, unnecessary_import

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
import 'package:file_selector/file_selector.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:path_provider/path_provider.dart';
import 'package:super_clipboard/super_clipboard.dart';
import '../../app/app_controller.dart';
import '../../app/app_metadata.dart';
import '../../app/ui_feature_manifest.dart';
import '../../i18n/app_language.dart';
import '../../models/app_models.dart';
import '../../runtime/runtime_models.dart';
import '../../theme/app_palette.dart';
import '../../theme/app_theme.dart';
import '../../widgets/assistant_focus_panel.dart';
import '../../widgets/assistant_artifact_sidebar.dart';
import '../../widgets/desktop_workspace_scaffold.dart';
import '../../widgets/pane_resize_handle.dart';
import '../../widgets/surface_card.dart';
import 'assistant_page_main.dart';
import 'assistant_page_composer_bar.dart';
import 'assistant_page_composer_state_helpers.dart';
import 'assistant_page_composer_support.dart';
import 'assistant_page_tooltip_labels.dart';
import 'assistant_page_message_widgets.dart';
import 'assistant_page_task_models.dart';
import 'assistant_page_composer_skill_picker.dart';
import 'assistant_page_composer_clipboard.dart';
import 'assistant_page_components_core.dart';

class AssistantTaskRailInternal extends StatefulWidget {
  const AssistantTaskRailInternal({
    super.key,
    required this.controller,
    required this.tasks,
    required this.query,
    required this.searchController,
    required this.onQueryChanged,
    required this.onClearQuery,
    required this.onRefreshTasks,
    required this.onCreateTask,
    required this.onSelectTask,
    required this.onArchiveTask,
    required this.onRenameTask,
  });

  final AppController controller;
  final List<AssistantTaskEntryInternal> tasks;
  final String query;
  final TextEditingController searchController;
  final ValueChanged<String> onQueryChanged;
  final VoidCallback onClearQuery;
  final Future<void> Function() onRefreshTasks;
  final Future<void> Function() onCreateTask;
  final Future<void> Function(String sessionKey) onSelectTask;
  final Future<void> Function(String sessionKey) onArchiveTask;
  final Future<void> Function(AssistantTaskEntryInternal entry) onRenameTask;

  @override
  State<AssistantTaskRailInternal> createState() =>
      AssistantTaskRailStateInternal();
}

class AssistantTaskRailStateInternal extends State<AssistantTaskRailInternal> {
  final Set<AssistantExecutionTarget> expandedGroupsInternal =
      <AssistantExecutionTarget>{};

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final palette = context.palette;
    final tasks = widget.tasks;
    final groupedTasks = groupTasksForRailInternal(
      tasks,
      widget.controller.visibleAssistantExecutionTargets(
        AssistantExecutionTarget.values,
      ),
    );
    final activeCount = tasks.where((task) {
      final status = normalizedTaskStatusInternal(task.status);
      return status == 'running';
    }).length;
    final openCount = tasks
        .where((task) => normalizedTaskStatusInternal(task.status) == 'open')
        .length;

    return SurfaceCard(
      borderRadius: 0,
      padding: EdgeInsets.zero,
      tone: SurfaceCardTone.chrome,
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.fromLTRB(8, 8, 8, 6),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    Expanded(
                      child: TextField(
                        key: const Key('assistant-task-search'),
                        controller: widget.searchController,
                        onChanged: widget.onQueryChanged,
                        decoration: InputDecoration(
                          hintText: appText('搜索任务', 'Search tasks'),
                          prefixIcon: const Icon(Icons.search_rounded),
                          suffixIcon: widget.query.isEmpty
                              ? null
                              : IconButton(
                                  tooltip: appText('清除搜索', 'Clear search'),
                                  onPressed: widget.onClearQuery,
                                  icon: const Icon(Icons.close_rounded),
                                ),
                        ),
                      ),
                    ),
                    const SizedBox(width: 6),
                    IconButton(
                      key: const Key('assistant-task-refresh'),
                      tooltip: appText('刷新任务', 'Refresh tasks'),
                      onPressed: () async {
                        await widget.onRefreshTasks();
                      },
                      icon: const Icon(Icons.refresh_rounded),
                    ),
                  ],
                ),
                const SizedBox(height: 6),
                SizedBox(
                  width: double.infinity,
                  child: FilledButton.tonalIcon(
                    key: const Key('assistant-new-task-button'),
                    onPressed: () async {
                      await widget.onCreateTask();
                    },
                    icon: const Icon(Icons.edit_note_rounded),
                    label: Text(appText('新对话', 'New conversation')),
                    style: FilledButton.styleFrom(
                      minimumSize: const Size(0, 32),
                      padding: const EdgeInsets.symmetric(
                        horizontal: 10,
                        vertical: 6,
                      ),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 6),
                Wrap(
                  spacing: 6,
                  runSpacing: 6,
                  children: [
                    MetaPillInternal(
                      label: '${appText('运行中', 'Running')} $activeCount',
                      icon: Icons.play_circle_outline_rounded,
                    ),
                    MetaPillInternal(
                      label: '${appText('当前', 'Open')} $openCount',
                      icon: Icons.forum_outlined,
                    ),
                    MetaPillInternal(
                      label:
                          '${appText('技能', 'Skills')} ${widget.controller.currentAssistantSkillCount}',
                      icon: Icons.key_rounded,
                    ),
                  ],
                ),
              ],
            ),
          ),
          Divider(height: 1, color: palette.strokeSoft),
          Padding(
            padding: const EdgeInsets.fromLTRB(8, 6, 8, 4),
            child: Row(
              children: [
                Text(
                  appText('任务列表', 'Task list'),
                  style: theme.textTheme.titleSmall,
                ),
                const SizedBox(width: 6),
                Text(
                  '${tasks.length}',
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: palette.textMuted,
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.separated(
              padding: const EdgeInsets.fromLTRB(4, 0, 4, 4),
              itemCount: groupedTasks.length,
              separatorBuilder: (_, _) => const SizedBox(height: 8),
              itemBuilder: (context, index) {
                final group = groupedTasks[index];
                final expanded = expandedGroupsInternal.contains(
                  group.executionTarget,
                );
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    AssistantTaskGroupHeaderInternal(
                      executionTarget: group.executionTarget,
                      count: group.items.length,
                      expanded: expanded,
                      onTap: () {
                        setState(() {
                          if (expanded) {
                            expandedGroupsInternal.remove(
                              group.executionTarget,
                            );
                          } else {
                            expandedGroupsInternal.add(group.executionTarget);
                          }
                        });
                      },
                    ),
                    if (expanded) ...[
                      const SizedBox(height: 4),
                      if (group.items.isEmpty)
                        Padding(
                          padding: const EdgeInsets.fromLTRB(28, 0, 8, 4),
                          child: Text(
                            appText('当前分组没有任务。', 'No tasks in this group.'),
                            style: theme.textTheme.bodySmall?.copyWith(
                              color: palette.textMuted,
                            ),
                          ),
                        ),
                      for (
                        var itemIndex = 0;
                        itemIndex < group.items.length;
                        itemIndex++
                      ) ...[
                        if (itemIndex > 0) const SizedBox(height: 4),
                        AssistantTaskTileInternal(
                          entry: group.items[itemIndex],
                          archiveEnabled:
                              normalizedTaskStatusInternal(
                                group.items[itemIndex].status,
                              ) !=
                              'running',
                          onTap: () async {
                            await widget.onSelectTask(
                              group.items[itemIndex].sessionKey,
                            );
                          },
                          onRename: () async {
                            await widget.onRenameTask(group.items[itemIndex]);
                          },
                          onArchive: () async {
                            await widget.onArchiveTask(
                              group.items[itemIndex].sessionKey,
                            );
                          },
                        ),
                      ],
                    ],
                  ],
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

List<AssistantTaskGroupInternal> groupTasksForRailInternal(
  List<AssistantTaskEntryInternal> tasks,
  List<AssistantExecutionTarget> visibleExecutionTargets,
) {
  final compactTargets = compactAssistantExecutionTargets(
    visibleExecutionTargets,
  );
  final grouped = <AssistantExecutionTarget, List<AssistantTaskEntryInternal>>{
    for (final target in compactTargets) target: <AssistantTaskEntryInternal>[],
  };
  for (final task in tasks) {
    final bucket =
        grouped[collapseAssistantExecutionTargetForDisplay(
          task.executionTarget,
        )];
    if (bucket == null) {
      continue;
    }
    bucket.add(task);
  }
  return compactTargets
      .map(
        (target) => AssistantTaskGroupInternal(
          executionTarget: target,
          items: grouped[target]!,
        ),
      )
      .toList(growable: false);
}

class AssistantTaskTileInternal extends StatelessWidget {
  const AssistantTaskTileInternal({
    super.key,
    required this.entry,
    required this.archiveEnabled,
    required this.onTap,
    required this.onRename,
    required this.onArchive,
  });

  final AssistantTaskEntryInternal entry;
  final bool archiveEnabled;
  final VoidCallback onTap;
  final VoidCallback onRename;
  final VoidCallback onArchive;

  @override
  Widget build(BuildContext context) {
    final palette = context.palette;
    final theme = Theme.of(context);
    final statusStyle = pillStyleForStatusInternal(context, entry.status);

    return Material(
      color: entry.isCurrent ? palette.surfacePrimary : Colors.transparent,
      borderRadius: BorderRadius.circular(8),
      child: InkWell(
        key: ValueKey<String>('assistant-task-item-${entry.sessionKey}'),
        borderRadius: BorderRadius.circular(8),
        onTap: onTap,
        onLongPress: onRename,
        onSecondaryTap: onRename,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 7),
          decoration: BoxDecoration(
            color: entry.isCurrent
                ? palette.surfaceSecondary
                : Colors.transparent,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(
              color: entry.isCurrent ? palette.strokeSoft : Colors.transparent,
            ),
          ),
          child: Row(
            children: [
              Container(
                width: 24,
                height: 24,
                decoration: BoxDecoration(
                  color: statusStyle.backgroundColor,
                  borderRadius: BorderRadius.circular(6),
                ),
                child: Icon(
                  entry.draft
                      ? Icons.edit_note_rounded
                      : _taskIsActiveInternal(entry.status)
                      ? Icons.play_arrow_rounded
                      : normalizedTaskStatusInternal(entry.status) ==
                            'interrupted'
                      ? Icons.pause_circle_outline_rounded
                      : Icons.task_alt_rounded,
                  size: 15,
                  color: statusStyle.foregroundColor,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: Text(
                  entry.title,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: theme.textTheme.titleSmall?.copyWith(
                    color: theme.colorScheme.onSurface,
                    fontWeight: entry.isCurrent
                        ? FontWeight.w600
                        : FontWeight.w500,
                  ),
                ),
              ),
              const SizedBox(width: 8),
              Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    entry.updatedAtLabel,
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: palette.textMuted,
                    ),
                  ),
                  if (_taskShowsProgressInternal(entry.status)) ...[
                    const SizedBox(height: 4),
                    SizedBox(
                      key: ValueKey<String>(
                        'assistant-task-progress-${entry.sessionKey}',
                      ),
                      width: 56,
                      child: LinearProgressIndicator(
                        value: _taskProgressValueInternal(entry.status),
                        minHeight: 3,
                        color: statusStyle.foregroundColor,
                        backgroundColor: statusStyle.foregroundColor.withValues(
                          alpha: 0.16,
                        ),
                        borderRadius: BorderRadius.circular(999),
                      ),
                    ),
                  ],
                ],
              ),
              const SizedBox(width: 2),
              IconButton(
                key: ValueKey<String>(
                  'assistant-task-archive-${entry.sessionKey}',
                ),
                tooltip: appText('归档任务', 'Archive task'),
                visualDensity: VisualDensity.compact,
                splashRadius: 12,
                onPressed: archiveEnabled ? onArchive : null,
                icon: Icon(
                  Icons.archive_outlined,
                  size: 18,
                  color: palette.textMuted,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

bool _taskIsActiveInternal(String status) {
  final normalized = normalizedTaskStatusInternal(status);
  return normalized == 'running';
}

bool _taskShowsProgressInternal(String status) {
  final normalized = normalizedTaskStatusInternal(status);
  return normalized == 'running' || normalized == 'interrupted';
}

double? _taskProgressValueInternal(String status) {
  return switch (normalizedTaskStatusInternal(status)) {
    'interrupted' => 0.48,
    _ => null,
  };
}

class AssistantTaskGroupHeaderInternal extends StatelessWidget {
  const AssistantTaskGroupHeaderInternal({
    super.key,
    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>('assistant-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(executionTarget.icon, size: 14, color: palette.textMuted),
              const SizedBox(width: 6),
              Flexible(
                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 AssistantEmptyStateInternal extends StatelessWidget {
  const AssistantEmptyStateInternal({
    super.key,
    required this.controller,
    required this.onFocusComposer,
    required this.onOpenGateway,
    required this.onOpenAiGatewaySettings,
    required this.onReconnectGateway,
  });

  final AppController controller;
  final VoidCallback onFocusComposer;
  final VoidCallback onOpenGateway;
  final VoidCallback onOpenAiGatewaySettings;
  final Future<void> Function() onReconnectGateway;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final connectionState = controller.currentAssistantConnectionState;
    final connected = connectionState.connected;
    final reconnectAvailable = controller.canQuickConnectGateway;
    final title = connected
        ? appText('开始对话或运行任务', 'Start a chat or run a task')
        : connectionState.status == RuntimeConnectionStatus.error
        ? appText('Bridge 连接失败', 'Bridge connection failed')
        : appText('先连接 Bridge', 'Connect xworkmate-bridge first');
    final description = connected
        ? appText(
            '输入需求后即可开始执行，结果会回到当前会话并同步到任务页。',
            'Type a request to start execution. Results return to this session and the Tasks page.',
          )
        : connectionState.gatewayTokenMissing
        ? appText(
            '首次连接需要共享 Token；配对完成后可继续使用本机的 device token。',
            'The first connection requires a shared token; after pairing, this device can continue with its device token.',
          )
        : connectionState.status == RuntimeConnectionStatus.error
        ? (connectionState.lastError?.trim().isNotEmpty == true
              ? connectionState.lastError!.trim()
              : appText(
                  '当前 bridge 连接失败。请重试连接；如果问题持续存在，请检查 bridge 运行状态和本机身份材料。',
                  'The bridge connection failed. Retry the connection, and if it keeps failing, check bridge health and local device identity material.',
                ))
        : !connected
        ? appText(
            '当前 xworkmate-bridge 尚未连接。请先恢复 bridge 连接，再继续当前任务。',
            'xworkmate-bridge is not connected yet. Restore the bridge connection, then continue this task.',
          )
        : (connectionState.lastError?.trim().isNotEmpty == true
              ? connectionState.lastError!.trim()
              : appText(
                  '连接后可直接对话、创建任务，并在当前会话查看结果。',
                  'After connecting, you can chat, create tasks, and read results in this session.',
                ));

    return Align(
      alignment: Alignment.topCenter,
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(8),
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 420),
          child: Container(
            key: const Key('assistant-empty-state-card'),
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: context.palette.surfacePrimary.withValues(alpha: 0.92),
              borderRadius: BorderRadius.circular(8),
              border: Border.all(color: context.palette.strokeSoft),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(title, style: theme.textTheme.titleMedium),
                const SizedBox(height: 6),
                Text(description, style: theme.textTheme.bodyMedium),
                const SizedBox(height: 8),
                Wrap(
                  spacing: 6,
                  runSpacing: 6,
                  children: [
                    FilledButton.icon(
                      onPressed: connected
                          ? onFocusComposer
                          : reconnectAvailable
                          ? () async {
                              await onReconnectGateway();
                            }
                          : onOpenGateway,
                      icon: Icon(
                        connected
                            ? Icons.edit_rounded
                            : reconnectAvailable
                            ? Icons.refresh_rounded
                            : Icons.link_rounded,
                      ),
                      label: Text(
                        connected
                            ? appText('开始输入', 'Start typing')
                            : reconnectAvailable
                            ? appText('重新连接 Bridge', 'Reconnect bridge')
                            : appText('连接 Bridge', 'Connect xworkmate-bridge'),
                      ),
                      style: FilledButton.styleFrom(
                        minimumSize: const Size(0, 28),
                        padding: const EdgeInsets.symmetric(
                          horizontal: 10,
                          vertical: 6,
                        ),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
