import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:forui/forui.dart';

import '../../core/contracts/auth.dart';
import '../../core/contracts/server.dart';
import '../../providers/item_counts_provider.dart';
import '../../providers/server_connectivity_provider.dart';
import '../../providers/server_provider.dart';
import '../../providers/server_sync_provider.dart';
import '../../providers/session_provider.dart';
import 'add_server_modal.dart';
import 'app_dialog.dart';
import 'icon_picker_dialog.dart';
import 'server_change_password_dialog.dart';

typedef ServerActionCallbacks = ({
  VoidCallback? onRefresh,
  VoidCallback? onChangeIcon,
  VoidCallback? onEdit,
  VoidCallback? onChangePassword,
  VoidCallback? onTogglePause,
  VoidCallback? onDelete,
});

ServerActionCallbacks buildServerActionCallbacks({
  required BuildContext context,
  required WidgetRef ref,
  required EmbyServer? server,
  AuthedSession? session,
}) {
  Future<void> changeIcon(EmbyServer server) async {
    final picked = await showIconPickerDialog(
      context,
      currentIconUrl: server.iconUrl,
    );
    if (picked == null) return;
    await ref
        .read(serverListProvider.notifier)
        .save(
          EmbyServerSaveReq(
            id: server.id,
            name: server.name,
            baseUrl: server.baseUrl,
            iconUrl: picked,
          ),
        );
  }

  Future<void> togglePause(EmbyServer server) async {
    final wasPaused = server.paused;
    final sessions = ref.read(sessionProvider).value;
    final wasActive = sessions?.activeServerId == server.id;
    await ref.read(serverListProvider.notifier).togglePause(server.id);

    if (!wasPaused && wasActive) {
      final updatedServers = ref.read(serverListProvider).value ?? const [];
      final pausedIds = {
        for (final s in updatedServers)
          if (s.paused) s.id,
      };
      final nextSession = sessions?.sessions
          .where(
            (s) => s.serverId != server.id && !pausedIds.contains(s.serverId),
          )
          .firstOrNull;

      if (nextSession != null) {
        await ref
            .read(sessionProvider.notifier)
            .switchSession(nextSession.serverId);
      } else {
        await ref.read(sessionProvider.notifier).logout(serverId: server.id);
      }
    }

    await ref.read(serverSyncProvider.notifier).upload();
  }

  Future<void> delete(EmbyServer server) async {
    final confirmed = await showAppConfirmDialog(
      context,
      title: '删除服务器',
      body: Text('确定删除「${server.name}」？此操作不可撤销。'),
      confirmLabel: '删除',
      destructive: true,
    );
    if (!confirmed) return;
    await ref.read(serverListProvider.notifier).delete(server.id);
    await ref.read(sessionProvider.notifier).refresh();
  }

  final s = server;
  return (
    onRefresh: s == null
        ? null
        : () {
            ref.invalidate(serverConnectivityProvider(s.baseUrl));
            ref.invalidate(serverItemCountsProvider(s.id));
          },
    onChangeIcon: s == null ? null : () => changeIcon(s),
    onEdit: s == null ? null : () => showAddServerModal(context, initial: s),
    onChangePassword: session == null
        ? null
        : () => showServerChangePasswordDialog(
            context: context,
            serverId: session.serverId,
            serverName: s?.name ?? session.serverName,
          ),
    onTogglePause: s == null ? null : () => togglePause(s),
    onDelete: s == null ? null : () => delete(s),
  );
}

List<FItem> buildServerActionMenuItems({
  VoidCallback? onRefresh,
  VoidCallback? onChangeIcon,
  VoidCallback? onEdit,
  VoidCallback? onChangePassword,
  bool paused = false,
  VoidCallback? onTogglePause,
  VoidCallback? onDelete,
}) => [
  if (onRefresh != null)
    FItem(
      prefix: const Icon(Icons.refresh_outlined, size: 16),
      title: const Text('刷新'),
      onPress: onRefresh,
    ),
  if (onChangeIcon != null)
    FItem(
      prefix: const Icon(Icons.image_outlined, size: 16),
      title: const Text('更换图标'),
      onPress: onChangeIcon,
    ),
  if (onEdit != null)
    FItem(
      prefix: const Icon(Icons.edit_outlined, size: 16),
      title: const Text('编辑'),
      onPress: onEdit,
    ),
  if (onChangePassword != null)
    FItem(
      prefix: const Icon(Icons.lock_outline, size: 16),
      title: const Text('修改密码'),
      onPress: onChangePassword,
    ),
  if (onTogglePause != null)
    FItem(
      prefix: Icon(
        paused ? Icons.play_circle_outline : Icons.pause_circle_outline,
        size: 16,
      ),
      title: Text(paused ? '恢复使用' : '暂停使用'),
      onPress: onTogglePause,
    ),
  if (onDelete != null)
    FItem(
      variant: FItemVariant.destructive,
      prefix: const Icon(Icons.delete_outline, size: 16),
      title: const Text('删除'),
      onPress: onDelete,
    ),
];
