import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

import '../routing/app_routes.dart';
import 'details_bottom_sheet.dart';
import 'file_pick.dart';

/// Result of the user's choice inside [showAvatarActionsSheet]. The sheet
/// only collects intent + the (cropped) image bytes — the actual upload /
/// delete and any loading state are the caller's responsibility, so failures
/// surface in the screen that owns the avatar, not in a transient sheet.
sealed class AvatarSheetResult {
  const AvatarSheetResult();
}

class AvatarUploadResult extends AvatarSheetResult {
  final Uint8List bytes;
  const AvatarUploadResult(this.bytes);
}

class AvatarRemoveResult extends AvatarSheetResult {
  const AvatarRemoveResult();
}

/// Bottom sheet with "from gallery", "take photo" and optional "remove"
/// actions. The picker + 1:1 cropper run with the sheet still mounted, so a
/// cancelled pick simply returns the user to the sheet. The sheet only pops
/// once a concrete result exists (or never, if everything was cancelled).
Future<AvatarSheetResult?> showAvatarActionsSheet(
  BuildContext context, {
  required bool allowRemove,
}) async {
  AvatarSheetResult? result;
  await showDetailsBottomSheet(
    context,
    children: (sheetContext) => [
      ListTile(
        leading: const Icon(Icons.photo_library_outlined),
        title: const Text('Aus Galerie wählen'),
        onTap: () async {
          final bytes = await _pickAndCrop(
            sheetContext,
            FilePick.singleGalleryPick,
          );
          if (bytes == null || !sheetContext.mounted) return;
          result = AvatarUploadResult(bytes);
          Navigator.of(sheetContext).pop();
        },
      ),
      ListTile(
        leading: const Icon(Icons.photo_camera_outlined),
        title: const Text('Foto aufnehmen'),
        onTap: () async {
          final bytes = await _pickAndCrop(sheetContext, FilePick.cameraPick);
          if (bytes == null || !sheetContext.mounted) return;
          result = AvatarUploadResult(bytes);
          Navigator.of(sheetContext).pop();
        },
      ),
      if (allowRemove) ...[
        const Divider(),
        ListTile(
          leading: Icon(
            Icons.delete_outline,
            color: Theme.of(sheetContext).colorScheme.error,
          ),
          title: Text(
            'Profilbild entfernen',
            style: TextStyle(color: Theme.of(sheetContext).colorScheme.error),
          ),
          onTap: () {
            result = const AvatarRemoveResult();
            Navigator.of(sheetContext).pop();
          },
        ),
      ],
    ],
  );
  return result;
}

Future<Uint8List?> _pickAndCrop(
  BuildContext context,
  Future<XFile?> Function() pick,
) async {
  final picked = await pick();
  if (picked == null) return null;
  final bytes = await picked.readAsBytes();
  if (!context.mounted) return null;
  return AppRoutes.openAvatarCrop(context, imageBytes: bytes);
}
