import 'dart:math';
import 'dart:typed_data';

import 'package:file_picker/file_picker.dart';
import 'package:http/http.dart' as http;

class SelectedAudio {
  const SelectedAudio({required this.name, required this.bytes});

  final String name;
  final Uint8List bytes;
}

Future<SelectedAudio?> pickAudio(List<String> supportedExtensions) async {
  final result = await FilePicker.platform.pickFiles(
    type: FileType.custom,
    allowedExtensions: supportedExtensions,
    allowMultiple: false,
    withData: true,
  );

  final pickedFile = result?.files.single;
  final bytes = pickedFile?.bytes;
  if (pickedFile == null || bytes == null) {
    return null;
  }

  return SelectedAudio(name: pickedFile.name, bytes: bytes);
}

Future<SelectedAudio?> audioFromRecorderPath(
  String path,
  String fallbackName,
) async {
  final response = await http.get(Uri.parse(path));
  if (response.statusCode < 200 || response.statusCode >= 300) {
    return null;
  }

  return SelectedAudio(name: fallbackName, bytes: response.bodyBytes);
}

Future<List<double>> buildWavePreview(SelectedAudio audio) async {
  return _wavePoints(audio.bytes);
}

Future<http.MultipartFile> multipartFileFromAudio(
  String fieldName,
  SelectedAudio audio,
) {
  return Future.value(
    http.MultipartFile.fromBytes(fieldName, audio.bytes, filename: audio.name),
  );
}

String recordingFilePath(String fileName) => fileName;

List<double> _wavePoints(List<int> bytes) {
  if (bytes.isEmpty) {
    return const [];
  }

  const pointCount = 96;
  final step = max(1, bytes.length ~/ pointCount);
  final points = <double>[];

  for (var index = 0; index < bytes.length; index += step) {
    final normalized = (bytes[index] - 128) / 128.0;
    points.add(normalized.clamp(-1.0, 1.0));
    if (points.length == pointCount) {
      break;
    }
  }

  return points;
}
