import 'dart:typed_data';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:googleapis/drive/v3.dart' as drive;
import 'package:http/http.dart' as http;

class GoogleDriveService {
  static final GoogleDriveService instance = GoogleDriveService._();
  GoogleDriveService._();

  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: [drive.DriveApi.driveFileScope],
  );

  GoogleSignInAccount? _currentUser;

  Future<GoogleSignInAccount?> signIn() async {
    _currentUser = await _googleSignIn.signInSilently();
    _currentUser ??= await _googleSignIn.signIn();
    return _currentUser;
  }

  Future<void> signOut() async {
    await _googleSignIn.signOut();
    _currentUser = null;
  }

  Future<String?> uploadAsGoogleSheet(List<int> excelBytes, String fileName) async {
    _currentUser ??= await signIn();
    if (_currentUser == null) return null;

    final authHeaders = await _currentUser!.authHeaders;
    final authenticatedClient = _AuthenticatedClient(authHeaders);

    final driveApi = drive.DriveApi(authenticatedClient);

    final fileMetadata = drive.File()
      ..name = fileName
      ..mimeType = 'application/vnd.google-apps.spreadsheet';

    final media = drive.Media(
      Stream.value(Uint8List.fromList(excelBytes)),
      excelBytes.length,
      contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );

    final result = await driveApi.files.create(
      fileMetadata,
      uploadMedia: media,
    );

    authenticatedClient.close();

    return result.id;
  }
}

class _AuthenticatedClient extends http.BaseClient {
  final Map<String, String> _headers;
  final http.Client _inner = http.Client();

  _AuthenticatedClient(this._headers);

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers.addAll(_headers);
    return _inner.send(request);
  }

  @override
  void close() {
    _inner.close();
  }
}
