import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart';
import '../../domain/repositories/bank_account_repository.dart';

/// Implementation of [BankAccountRepository] that integrates with Data Connect.
class BankAccountRepositoryImpl implements BankAccountRepository {
  /// Creates a [BankAccountRepositoryImpl].
  const BankAccountRepositoryImpl({
    required this.dataConnect,
    required this.firebaseAuth,
  });

  /// The Data Connect instance.
  final ExampleConnector dataConnect;
  /// The Firebase Auth instance.
  final auth.FirebaseAuth firebaseAuth;

  @override
  Future<List<BankAccount>> getAccounts() async {
    final String staffId = _getStaffId();
    
    final QueryResult<GetAccountsByOwnerIdData, GetAccountsByOwnerIdVariables>
        result = await dataConnect
            .getAccountsByOwnerId(ownerId: staffId)
            .execute();
    
    return result.data.accounts.map((GetAccountsByOwnerIdAccounts account) {
      return BankAccountAdapter.fromPrimitives(
        id: account.id,
        userId: account.ownerId,
        bankName: account.bank,
        accountNumber: account.accountNumber,
        last4: account.last4,
        sortCode: account.routeNumber,
        type: account.type is Known<AccountType> ? (account.type as Known<AccountType>).value.name : null,
        isPrimary: account.isPrimary,
      );
    }).toList();
  }

  @override
  Future<void> addAccount(BankAccount account) async {
    final String staffId = _getStaffId();

    final QueryResult<GetAccountsByOwnerIdData, GetAccountsByOwnerIdVariables>
        existingAccounts = await dataConnect
            .getAccountsByOwnerId(ownerId: staffId)
            .execute();
    final bool hasAccounts = existingAccounts.data.accounts.isNotEmpty;
    final bool isPrimary = !hasAccounts;

    await dataConnect.createAccount(
      bank: account.bankName,
      type: AccountType.values.byName(BankAccountAdapter.typeToString(account.type)),
      last4: _safeLast4(account.last4, account.accountNumber),
      ownerId: staffId,
    )
    .isPrimary(isPrimary)
    .accountNumber(account.accountNumber)
    .routeNumber(account.sortCode)
    .execute();
  }

  /// Helper to get the logged-in staff ID.
  String _getStaffId() {
    final auth.User? user = firebaseAuth.currentUser;
    if (user == null) {
      throw Exception('User not authenticated');
    }
    
    final String? staffId = StaffSessionStore.instance.session?.staff?.id;
    if (staffId == null || staffId.isEmpty) {
      throw Exception('Staff profile is missing or session not initialized.');
    }
    return staffId;
  }

  /// Ensures we have a last4 value, either from input or derived from account number.
  String _safeLast4(String? last4, String accountNumber) {
    if (last4 != null && last4.isNotEmpty) {
      return last4;
    }
    if (accountNumber.isEmpty) {
      return '0000';
    }
    if (accountNumber.length < 4) {
      return accountNumber.padLeft(4, '0');
    }
    return accountNumber.substring(accountNumber.length - 4);
  }
}
