<?php

namespace App\Libraries\undeposited_funds;

use App\Models\UndepositedFundsModel;

/**
 * Orchestrates the pull‑and‑cross‑reference workflow for Undeposited Funds.
 */
class NewLibrary
{
    protected UndepositedFundsLibrary $ufLib;

    public function __construct()
    {
        $this->ufLib = new UndepositedFundsLibrary();
    }

    /**
     * Pulls data from QBO and cross‑references existing deposits.
     *
     * @param string      $action       e.g. pull_undeposited · pull_deposits
     * @param bool        $isConnected  Credentials present?
     * @param string      $fromDate     Y‑m‑d
     * @param string      $toDate       Y‑m‑d
     * @param string|null $realmId
     * @param string|null $accessToken
     *
     * @return string|null  Error text or null on success
     */
    public function pullAndCrossReference(
        string $action,
        bool   $isConnected,
        string $fromDate,
        string $toDate,
        ?string $realmId,
        ?string $accessToken
    ): ?string {
        try {
            if ($action === 'pull_undeposited' && $isConnected) {
                $uf = new UndepositedFundsModel();

                // Pull every UF‑eligible transaction type
                $this->ufLib->pullPayments      ($realmId, $accessToken, $fromDate, $toDate, $uf);
                $this->ufLib->pullSalesReceipts ($realmId, $accessToken, $fromDate, $toDate, $uf);
                $this->ufLib->pullRefundReceipts($realmId, $accessToken, $fromDate, $toDate, $uf);
                $this->ufLib->pullCreditMemos   ($realmId, $accessToken, $fromDate, $toDate, $uf);
                $this->ufLib->pullJournalEntries($realmId, $accessToken, $fromDate, $toDate, $uf);

                // Pull the actual Deposit masters (for cross‑reference)
                $this->ufLib->pullDeposits($realmId, $accessToken, $fromDate, $toDate);
                $this->crossReferenceDeposits();
            }

            if ($action === 'pull_deposits' && $isConnected) {
                $this->ufLib->pullDeposits($realmId, $accessToken, $fromDate, $toDate);
                $this->crossReferenceDeposits();
            }
        } catch (\Throwable $e) {
            $msg = ($action === 'pull_deposits')
                ? 'Error while pulling deposits: '
                : 'Error while pulling data: ';
            return $msg . $e->getMessage();
        }

        return null;
    }

    /**
     * Marks UF rows as deposited when they already appear inside a Deposit.
     * (Runs after fresh pulls.)
     */
    public function crossReferenceDeposits(): void
    {
        $db = \Config\Database::connect();
        $db->query("
            UPDATE undeposited_funds uf
            JOIN deposits_made_lines dml ON dml.linked_txn_id = uf.qb_txn_id
            JOIN deposits_made       dm  ON dm.id            = dml.deposits_made_id
            SET uf.is_deposited   = 1,
                uf.deposit_txn_id = dm.qb_deposit_id,
                uf.deposit_date   = dm.deposit_date
            WHERE uf.is_deposited = 0
        ");
    }
}
