import 'package:pocketbase/pocketbase.dart';

import '../api/pocketbase_client.dart';

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

  PocketBase get _pb => PocketBaseClient.instance.pb;

  Future<void> ensureEntriesForJob({
    required String jobId,
    required String clinicTenantId,
    required String labTenantId,
    required String clinicName,
    required String labName,
    required double amount,
    required String currency,
  }) async {
    if (amount <= 0) return;

    final existing = await _pb.collection('finance_entries').getFullList(
          filter: 'job_id = "$jobId"',
          batch: 200,
        );

    await _upsertEntry(
      existing: existing,
      jobId: jobId,
      tenantId: clinicTenantId,
      counterpartyTenantId: labTenantId,
      counterpartyName: labName,
      type: 'payable',
      amount: amount,
      currency: currency,
    );

    await _upsertEntry(
      existing: existing,
      jobId: jobId,
      tenantId: labTenantId,
      counterpartyTenantId: clinicTenantId,
      counterpartyName: clinicName,
      type: 'receivable',
      amount: amount,
      currency: currency,
    );
  }

  Future<void> reportJobPayment(String jobId) async {
    final existing = await _pb.collection('finance_entries').getFullList(
          filter: 'job_id = "$jobId"',
          batch: 200,
        );
    for (final record in existing) {
      await _pb.collection('finance_entries').update(
        record.id,
        body: {
          'status': 'reported',
          'paid_at': null,
        },
      );
    }
  }

  Future<void> confirmJobPayment(String jobId) async {
    final existing = await _pb.collection('finance_entries').getFullList(
          filter: 'job_id = "$jobId"',
          batch: 200,
        );
    final paidAt = DateTime.now().toIso8601String();
    for (final record in existing) {
      await _pb.collection('finance_entries').update(
        record.id,
        body: {
          'status': 'paid',
          'paid_at': paidAt,
        },
      );
    }
  }

  Future<void> deletePendingEntriesForJob(String jobId) async {
    final existing = await _pb.collection('finance_entries').getFullList(
          filter:
              'job_id = "$jobId" && (status = "pending" || status = "reported")',
          batch: 200,
        );
    for (final record in existing) {
      await _pb.collection('finance_entries').delete(record.id);
    }
  }

  Future<void> _upsertEntry({
    required List<RecordModel> existing,
    required String jobId,
    required String tenantId,
    required String counterpartyTenantId,
    required String counterpartyName,
    required String type,
    required double amount,
    required String currency,
  }) async {
    RecordModel? match;
    try {
      match = existing.firstWhere(
        (record) =>
            record.data['tenant_id'] == tenantId && record.data['type'] == type,
      );
    } catch (_) {
      match = null;
    }

    final body = {
      'tenant_id': tenantId,
      'job_id': jobId,
      'type': type,
      'amount': amount,
      'currency': currency,
      'status': 'pending',
      'paid_at': null,
      'counterparty_tenant_id': counterpartyTenantId,
      'counterparty_name': counterpartyName,
    };

    if (match == null) {
      await _pb.collection('finance_entries').create(body: body);
      return;
    }

    await _pb.collection('finance_entries').update(match.id, body: body);
  }
}
