<?php

class CRM_Grant_BAO_GrantBudget extends CRM_Grant_DAO_GrantBudget {

  /**
   * Build Fiscal year option list.
   *
   */
  public static function getFiscalyear() {
    $from = date("Y", strtotime(date('Y') . ' - ' . GRANT_SCHOLARSHIP_YEAR_DIFF . ' years'));
    $to = date("Y", strtotime(date('Y') . ' + ' . GRANT_SCHOLARSHIP_YEAR_DIFF . ' years'));
    return array_combine(range($to, $from), range($to, $from));
  }

  /**
   * Get grant budget for fiscal year and financial type.
   *
   * @param $params array
   *
   * @return array
   */
  public static function getGrantBudget($params) {
    $fiscalYear = $params['fiscal_year'];
    if (empty($fiscalYear)) {
      $fiscalYear = date('Y');
    }
    $grantBudget = [];
    $paidStatusID = CRM_Core_PseudoConstant::getKey(
      'CRM_Grant_DAO_Grant',
      'status_id',
      'Paid'
    );

    $config = CRM_Core_Config::singleton();
    $mkTime = mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], $fiscalYear);
    $fiscalStartDate = date('Y-m-d', $mkTime);
    $fiscalEndDate = date('Y-m-d', strtotime($fiscalStartDate . '+ 1 year'));

    $qParams = [
      1 => [$fiscalYear, 'String'],
      2 => [$fiscalStartDate, 'String'],
      3 => [$fiscalEndDate, 'String'],
      4 => [$paidStatusID, 'Integer'],
    ];

    $where = '';
    if (!empty($params['financial_type_id'])) {
      $where = 'WHERE cft.id = %5';
      $qParams[5] = [$params['financial_type_id'], 'Integer'];
    }
    $grantBudgetTableName = CRM_Grant_DAO_GrantBudget::getTableName();
    $sql = "SELECT cgb.id, cft.name, IFNULL(cgb.budget, 0) AS budget,
        SUM(IFNULL(cg." . GRANT_AMOUNT_CHECK_FIELD . ", 0)) as total_amount_granted,
        cft.id AS financial_type_id
      FROM civicrm_financial_type cft
        INNER JOIN " . GRANT_SCHOLARSHIP_CUSTOM_TABLE_NAME . " gs
          ON gs.entity_id = cft.id
          AND gs." . GRANT_SCHOLARSHIP_CUSTOM_FIELD . " = 1
        LEFT JOIN " . $grantBudgetTableName . " cgb
          ON cgb.financial_type_id = cft.id AND cgb.fiscal_year = %1
        LEFT JOIN civicrm_grant cg
          ON cg.financial_type_id = cft.id AND cg.status_id IN (%4)
          AND cg." . GRANT_DATE_CHECK_FIELD . " >= %2
          AND cg." . GRANT_DATE_CHECK_FIELD . " < %3
      {$where}
      GROUP BY cft.id
      ORDER BY cft.name";
    $result = CRM_Core_DAO::executeQuery($sql, $qParams);

    while ($result->fetch()) {
      $grantBudget[] = [
        'id' => $result->id,
        'name' => $result->name,
        'budget' => CRM_Utils_Money::format($result->budget),
        'total_amount_granted' => CRM_Utils_Money::format($result->total_amount_granted),
        'balance_amount' => CRM_Utils_Money::format(($result->budget - $result->total_amount_granted)),
        'financial_type_id' => $result->financial_type_id,
      ];
    }
    return $grantBudget;
  }

  /**
   * Validate grant.
   *
   * @param $params array
   *
   * @return bool
   */
  public static function checkBudget($params, $grantId) {
    $year = date('Y', strtotime($params[GRANT_DATE_CHECK_FIELD]));
    $grantBudget = civicrm_api3('GrantBudget', 'getbudget', [
      'financial_type_id' => $params['financial_type_id'],
      'fiscal_year' => $year,
    ]);
    $grantBudget = reset($grantBudget['values']);
    $isError = FALSE;
    if ($grantBudget) {
      $balanceAmount = CRM_Utils_Rule::cleanMoney($grantBudget['balance_amount']);
      $amountGranted = CRM_Utils_Rule::cleanMoney($params[GRANT_AMOUNT_CHECK_FIELD]);
      if ($grantId) {
        $oldGrantValues = civicrm_api3('Grant', 'getsingle', [
          'return' => [GRANT_AMOUNT_CHECK_FIELD, 'financial_type_id', GRANT_DATE_CHECK_FIELD],
          'id' => $grantId,
        ]);
        if ($oldGrantValues['financial_type_id'] == $params['financial_type_id']
          && $year == date('Y', strtotime($oldGrantValues[GRANT_DATE_CHECK_FIELD]))
        ) {
          $amountGranted -= $oldGrantValues[GRANT_AMOUNT_CHECK_FIELD];
        }
      }
      if ($balanceAmount < $amountGranted) {
        $isError = TRUE;
      }
    }
    return [$isError, $grantBudget];
  }

}