<?php
/**
  * Ahead WebSoft Technologies Pvt Ltd.
  * @copyright  Copyright 2006-2026 Ahead WebSoft Technologies Pvt Ltd.
  * @license    https://www.socialengine.com/policies
*/
class Payment_Model_Package extends Core_Model_Item_Abstract
{
    protected $_searchTriggers = false;

    protected $_modifiedTriggers = false;

    protected $_level;

    protected $_product;

    public function hasDuration()
    {
        return ( $this->duration > 0 && $this->duration_type != 'forever' );
    }

    public function isFree()
    {
        return ( $this->price <= 0 );
    }

    public function isOneTime()
    {
        return ( $this->recurrence <= 0 || $this->recurrence_type == 'forever' );
    }

    public function getLevel()
    {
        if( empty($this->level_id) ) {
        return null;
        }
        if( null === $this->_level ) {
        $this->_level = Engine_Api::_()->getItem('authorization_level', $this->level_id);
        }
        return $this->_level;
    }

    public function getProduct()
    {
        if( null === $this->_product ) {
        $productsTable = Engine_Api::_()->getDbtable('products', 'payment');
        $this->_product = $productsTable->fetchRow($productsTable->select()
            ->where('extension_type = ?', 'payment_subscription')
            ->where('extension_id = ?', $this->getIdentity())
            ->limit(1));
        // Create a new product?
        if( !$this->_product ) {
            $this->_product = $productsTable->createRow();
            $this->_product->setFromArray($this->getProductParams());
            $this->_product->save();
        }
        }

        return $this->_product;
    }

    public function getProductParams()
    {
        return array(
        'title' => $this->title,
        'description' => $this->description,
        'price' => $this->price,
        'extension_type' => 'payment_subscription',
        'extension_id' => $this->package_id,
        );
    }

    public function getPackageDescription($param = false) {
    
      $translate = Zend_Registry::get('Zend_Translate');
      $view = Zend_Registry::get('Zend_View');
      
      //Check for admin panel
      if($param) {
        $currency = Engine_Api::_()->getApi('settings', 'core')->getSetting('payment.currency', 'USD');
        $priceStr =  Engine_Api::_()->payment()->getCurrencyPrice($this->price,$currency,'','');
      } else {
        $currency = Engine_Api::_()->payment()->getCurrentCurrency();
        $priceStr =  Engine_Api::_()->payment()->getCurrencyPrice($this->price,'','','');
      }
      
      // Plan is free
      if( $this->price == 0 ) {
        $str = $translate->translate('Free');
      }

      // Plan is recurring
      else if( $this->recurrence > 0 && $this->recurrence_type != 'forever' ) {
        // Make full string
        if( $this->recurrence == 1 ) { // (Week|Month|Year)ly
          if( $this->recurrence_type == 'day' ) {
            $typeStr = $translate->translate('daily');
          } else {
            $typeStr = $translate->translate($this->recurrence_type . 'ly');
          }
          $str = sprintf($translate->translate('%1$s %2$s'), $priceStr, $typeStr);
        } else { // per x (Week|Month|Year)s
          $typeStr = $translate->translate(array($this->recurrence_type, $this->recurrence_type . 's', $this->recurrence));
          $str = sprintf($translate->translate('%1$s per %2$s %3$s'), $priceStr,
          $this->recurrence, $typeStr); // @todo currency
        }
      }
      // Plan is one-time
      else {
        $str = sprintf($translate->translate('One-time fee of %1$s'), $priceStr);
      }
      
      // Add duration, if not forever
      if( $this->duration > 0 && $this->duration_type != 'forever' ) {
        $typeStr = $translate->translate(array($this->duration_type, $this->duration_type . 's', $this->duration));
        $str = sprintf($translate->translate('%1$s for %2$s %3$s'), $str, $this->duration, $typeStr);
      }

      return $str;
    }

    public function getGatewayIdentity()
    {
        return $this->getProduct()->sku;
    }

    public function getGatewayParams()
    {
        $params = array();

        // General
        $params['name'] = $this->title;
        $params['price'] = $this->price;
        $params['description'] = $this->description;
        $params['vendor_product_id'] = $this->getGatewayIdentity();
        $params['tangible'] = false;

        // Non-recurring
        if( $this->recurrence_type == 'forever' ) {
        $params['recurring'] = false;
        }

        // Recurring
        else {
        $params['recurring'] = true;
        $params['recurrence'] = $this->recurrence . ' ' . ucfirst($this->recurrence_type);

        // Duration
        if( $this->duration_type == 'forever' ) {
            $params['duration'] = 'Forever';
        } else {
            $params['duration'] = $this->duration . ' ' . ucfirst($this->duration_type);
        }
        }

        return $params;
    }

    public function getExpirationDate($rel = null)
    {
        if( null === $rel ) {
            $rel = time();
        }

        // If it's a one-time payment or a free package with no duration, there
        // is no expiration
        if( ($this->isOneTime() || $this->isFree()) && !$this->hasDuration() ) {
        return false;
        }

        // If this is a free or one-time package, the expiration is based on the
        // duration, otherwise the expirations is based on the recurrence
        $interval = null;
        $interval_type = null;
        if( $this->isOneTime() || $this->isFree() ) {
        $interval = $this->duration;
        $interval_type = $this->duration_type;
        } else {
        $interval = $this->recurrence;
        $interval_type = $this->recurrence_type;
        }

        // This is weird, it should have been handled by the statement at the top
        if( $interval == 'forever' ) {
        return false;
        }

        // Calculate when the next payment should be due
        switch( $interval_type ) {
        case 'day':
            $part = Zend_Date::DAY;
            break;
        case 'week':
            $part = Zend_Date::WEEK;
            break;
        case 'month':
            $part = Zend_Date::MONTH;
            break;
        case 'year':
            $part = Zend_Date::YEAR;
            break;
        default:
            throw new Engine_Payment_Exception('Invalid recurrence_type');
            break;
        }

        $relDate = new Zend_Date($rel);
        $relDate->add((int) $interval, $part);

        return $relDate->toValue();
    }

    public function getAdditionalExpirationDate($rel = null)
    {
        if( null === $rel ) {
        $rel = time();
        }

        // If it's a one-time payment or a free package with no duration, there
        // is no expiration
        if(($this->isOneTime() || $this->isFree()) && !$this->hasDuration() ) {
            return false;
        }

        // If this is a free or one-time package, the expiration is based on the
        // duration, otherwise the expirations is based on the recurrence

        // This is weird, it should have been handled by the statement at the top
        if( $interval == 'forever' ) {
        return false;
        }

        $relDate = new Zend_Date($rel);
        $relDate->add((int) $this->extra_day, Zend_Date::DAY);

        return $relDate->toValue();
    }

    public function getReminderDate($rel = null)
    {
        if( null === $rel ) {
        $rel = time();
        }

        // If it's a one-time payment or a free package with no duration, there
        // is no expiration
        if(($this->isOneTime() || $this->isFree()) && !$this->hasDuration() ) {
        return false;
        }

        // If this is a free or one-time package, the expiration is based on the
        // duration, otherwise the expirations is based on the recurrence
        $interval = null;
        $interval_type = null;
        if($this->isOneTime() || $this->isFree() ) {
        return false;
        } else {
        $interval = $this->reminder_email;
        $interval_type = $this->reminder_email_type;
        }

        // This is weird, it should have been handled by the statement at the top
        if( $interval == 'forever' ) {
        return false;
        }

        // Calculate when the next payment should be due
        switch( $interval_type ) {
        case 'day':
            $part = Zend_Date::DAY;
            break;
        case 'week':
            $part = Zend_Date::WEEK;
            break;
        case 'month':
            $part = Zend_Date::MONTH;
            break;
        case 'year':
            $part = Zend_Date::YEAR;
            break;
        default:
            throw new Engine_Payment_Exception('Invalid reminder_email_type');
            break;
        }

        $relDate = new Zend_Date($rel);
        $relDate->sub((int) $interval, $part);

        return $relDate->toValue();
    }

  public function getTotalBillingCycleCount()
  {
    // One-time
    if( $this->isOneTime() ) {
      return 1;
    }
    // Indefinite
    else if( !$this->hasDuration() ) {
      return null;
    }
    // Calculate
    else {
      $multiplier = null;
      switch( $this->recurrence_type . '-' . $this->duration_type ) {
        case 'day-day':
        case 'week-week':
        case 'month-month':
        case 'year-year':
          $multiplier = 1;
          break;

        case 'day-week':
          $multiplier = 7;
          break;
        case 'day-month':
          $multiplier = 30; // Not accurate
          break;
        case 'day-year':
          $multiplier = 365; // Not accurate
          break;
        case 'week-month':
          $multiplier = 4; // Not accurate
          break;
        case 'week-year':
          $multiplier = 52; // Not accurate
          break;
        case 'month-year':
          $multiplier = 12;
          break;

        case 'week-day':
          $multiplier = 1 / 7;
          break;
        case 'month-day':
          $multiplier = 1 / 30;
          break;
        case 'month-week':
          $multiplier = 1 / 4;
          break;
        case 'year-day':
          $multiplier = 1 / 365;
          break;
        case 'year-week':
          $multiplier = 1 / 52;
          break;
        case 'year-month':
          $multiplier = 1 / 12;
          break;
        default:
          // Sigh, what should we do here?
          break;
      }
      return ceil($this->duration * $multiplier / $this->recurrence);
    }
  }

  protected function _postInsert()
  {
    // Update product
    $product = $this->getProduct();
    $product->setFromArray($this->getProductParams());
    $product->save();

    parent::_postInsert();
  }

  protected function _postUpdate()
  {
    // Update product
    $product = $this->getProduct();
    $product->setFromArray($this->getProductParams());
    $product->save();

    parent::_postUpdate();
  }
  
  public function isPackageRecurrence() {

    if($this->recurrence_type == 'week' && $this->recurrence > 53) {
      return false;
    } else if($this->recurrence_type == 'year'  && $this->recurrence > 1) {
      return false;
    } else if($this->recurrence_type == 'month'  && $this->recurrence > 12) {
      return false;
    }
    return true;
  }
}
