import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:moneymgr_mobile/services/api/api_client.dart';
import 'package:moneymgr_mobile/services/api/files_api.dart';
import 'package:moneymgr_mobile/services/api/inbox_api.dart';
import 'package:moneymgr_mobile/services/storage/expenses.dart';
import 'package:moneymgr_mobile/utils/extensions.dart';
import 'package:moneymgr_mobile/utils/hooks.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'synchronize_button.g.dart';

/// Synchronize expenses list with backend
@riverpod
Future<void> _performSynchronization(Ref ref) async {
  final expenses = ref.watch(expensesProvider).requireValue;
  final apiService = ref.watch(apiServiceProvider)!;

  final list = await expenses.getList();

  for (final exp in list) {
    // First, upload file
    final bytes = await expenses.loadFile(exp);
    final file = await apiService.uploadFile(
      filename: exp.localFileName,
      mimeType: exp.mimeType,
      bytes: bytes,
    );

    // Then, create the inbox entry
    await apiService.createInboxEntry(
      UpdateInboxEntryRequest(
        file_id: file.id,
        time: exp.time,
        label: exp.label,
        amount: -1 * exp.cost,
      ),
    );

    // Lastly delete the local expense
    ref.watch(expensesProvider).requireValue.deleteExpense(exp);
  }

  ref.invalidate(expensesProvider);
}

class SynchronizeButton extends HookConsumerWidget {
  const SynchronizeButton({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final (:pending, :snapshot, :hasError) = useAsyncTask();

    handleSynchronize() async {
      try {
        await ref.watch(
          _performSynchronizationProvider.selectAsync((it) => it),
        );
      } catch (e, s) {
        Logger.root.warning("Failed to synchronize expenses! $e $s");
        if (context.mounted) {
          context.showTextSnackBar("Failed to synchronize expenses! $e");
        }
      }
    }

    return snapshot.connectionState == ConnectionState.waiting
        ? Padding(
            padding: const EdgeInsets.all(12.0),
            child: SizedBox(
              height: 20,
              width: 20,
              child: CircularProgressIndicator(strokeWidth: 2),
            ),
          )
        : IconButton(
            onPressed: () => pending.value = handleSynchronize(),
            style: ButtonStyle(
              backgroundColor: hasError
                  ? WidgetStatePropertyAll(Colors.red)
                  : null,
            ),
            icon: Icon(Icons.sync_rounded),
          );
  }
}
