<?php
class Installment extends Eloquent {

    /**
     * fillable fields in table
     * @return array
     */
    protected $fillable = [
        'customer_id', 
        'type_of_product',
        'model',
        'imie', 
        'product_name', 
        'total_price',
        'rate', 
        'duration', 
        'deposit', 
        'note', 
        'user_id', 
        'in_date',
        'loan_type'
    ];

    /**
     * Get Total price
     * @return float
     */
    public function getTotalPrice()
    {
        return $this->total_price;
    }

    /**
     * Get Rate
     * @return float
     */
    public function getRate()
    {
        return $this->rate / 100;
    }

    /**
     * Get Duration of payment term
     * @return integer number term
     */
    public function getDuration()
    {
        return $this->duration;
    }

    /**
     * Get Deposit
     * @return float
     */
    public function getDeposit()
    {
        return $this->deposit;
    }

    /**
     * Get Total Interest
     * @return float
     */
    public function getTotalInterest()
    {
        return $this->getPriciple() * $this->getRate() * $this->duration;
    }

    /**
     * Get Principle
     * @return float
     */
    public function getPriciple()
    {
        return $this->deposit > 0 ? $this->total_price - $this->deposit : $this->total_price;
    }

    /**
     * Get Future Value of payment
     * @return float
     */
    public function getFutureValue()
    {
        return $this->getPriciple() + $this->getTotalInterest();
    }

    /**
     * Get Monthly Principle
     * @return float
     */
    public function getMonthlyPriciple()
    {
        return round($this->getPriciple() / $this->duration, 2);
    }

    /**
     * Get Mothly Rate
     * @return float
     */
    public function getMonthlyRate()
    {
        return round($this->getTotalInterest() / $this->duration, 2);
    }

    /**
     * Get Monthly Payment
     * @return float
     */
    public function getMonthlyPayment()
    {
        return floor($this->getFutureValue() / $this->duration);
    }

    /**
     * Push all two decimal poin to first month
     *
     * @return float
     */
    public function addFirstMonth()
    {
        $result = $this->getFutureValue() - ($this->getMonthlyPayment() * $this->getDuration());
        return $result ? $result : 0;
    }

    /**
     * Get PayFirst Month
     *
     * @return float
     */
    public function getPayFirstMonth()
    {
        return $this->getMonthlyPayment() + $this->addFirstMonth();
    }

    /**
     * Get Rmaining Principle
     * @param  integer $termPaid
     * @return float
     */
    public function getRemainPrinciple($termPaid)
    {
        if ($termPaid < 3) {
            switch ($termPaid) {
              case 0:
                    return $this->getPriciple();
                break;
              case 1:
                    return $this->getPriciple() - ($this->getMonthlyPriciple() * $termPaid);
                break;
              case 2:
                    return $this->getPriciple() - ($this->getMonthlyPriciple() * $termPaid);
                break;
            }
        } else {
           return $this->getPriciple() - ($this->getMonthlyPriciple() * $termPaid);
        }
    }

    /**
     * Get Rate for first three months
     * @param  integer $termPaid
     * @return float
     */
    public function getRate3Moths($termPaid)
    {
        $nPaid = $termPaid;
        switch ($nPaid) {
            case 0:
                return $this->getMonthlyRate() * 3;
                break;
            case 1:
                return $this->getMonthlyRate() * 2;
                break;
            case 2:
                return $this->getMonthlyRate() * 1;
                break;
            default:
                return $this->getMonthlyRate() * 1;
                break;
        }
    }

    /**
     * Display Created Date
     * @return string
     */
    public function displayCreatedDate()
    {
        return format_date_installment($this->created_at);
    }

    /**
     * Display In Date
     * @return string
     */
    public function displayInDate()
    {
        return format_date_installment($this->in_date);
    }

    /**
     * Display buy date
     * @return [type] [description]
     */
    public function getInDate()
    {
        return new Carbon\Carbon($this->in_date);
    }

    /**
     * Convert this fields to carbon object
     * @return array
     */
    public function getDates()
    {
        return ['in_date', 'created_at', 'updated_at'];
    }

    /**
     * Get total Expense
     * @return float
     */
    public static function getTotalExpense()
    {
        return self::sum('total_price') - self::sum('deposit');
    }

    /**
     * Get current expense
     * @return float
     */
    public function getCurrentExpense()
    {
        return $this->total_price - $this->deposit;
    }

    /**
     * Display date
     * @return [type] [description]
     */
    public function displayDate() 
    {
        return $this->date_in < $this->created_at ? $this->displayInDate() : $this->displayCreatedDate();
    }

    /**
     * Installment By ID
     * @param  int $id
     * @return object    
     */
    public function scopeById($query, $id)
    {
        return $query->join('loan_customers as lc', 'installments.customer_id', '=', 'lc.id')
                    ->join("users as u", "u.id", "=", "installments.user_id")
                    ->select(
                        'installments.*',
                        'lc.full_name_kh',
                        'lc.full_name_en',
                        'lc.gender',
                        'lc.tel',
                        'u.first_name',
                        'u.last_name'
                    )->where('installments.id', $id)->first();
    }

    /**
     * Today to expense
     * @return float
     */
    public static function expensesToday()
    {
        $startToday = Carbon\Carbon::today();
        $endToday = Carbon\Carbon::today();
        $endToday->addHours(23)
                ->addMinutes(59)
                ->addSeconds(59);

        $total = self::whereBetween("in_date", [$startToday, $endToday])->sum('total_price') - self::whereBetween("in_date", [$startToday, $endToday])->sum('deposit');
        return $total;
    }

    /**
     * Get only emi installments
     * @param  object $query
     * @param  int $id   
     * @return object       
     */
    public function scopeEmiInstallment($query, $id)
    {
        return $query->where("loan_type", "emi")
                    ->where("customer_id", $id);
    }

    /**
     * Query Scope for join customer
     *
     * @param object $query
     * @return object
     */
    public function scopeCustomers($query)
    {
        return $query->join("loan_customers as lc", "installments.customer_id", "=", "lc.id");
    }

    /**
     * Select Fields Customer and Installment
     *
     * @param object $query
     * @return object
     */
    public function scopeSelectCustomer($query)
    {
        return $query->select(
                            'installments.*',
                            'lc.full_name_kh',
                            'lc.full_name_en',
                            'lc.gender',
                            'lc.tel'
                            );   
    }

    /**
     * Filter Customers 
     * In Installment Index
     *
     * @param [type] $query
     * @param [type] $pattern
     * @return void
     */
    public function scopeFilterCustomer($query, $pattern)
    {
        return $query->where(function ($q) use ($pattern) {
                    $q->where('lc.full_name_kh', 'LIKE', $pattern)
                            ->orWhere('lc.full_name_en', 'LIKE', $pattern)
                            ->orWhere('lc.tel', 'LIKE', $pattern);
            });
    }

    /**
     * Filter loan by date
     *
     * @param [type] $query
     * @param [type] $dates
     * @return void
     */
    public function scopeByLoanDate($query, $dates)
    {
        return $query->whereBetween("installments.in_date", $dates);
    }

    public function scopeByUser($query)
    {
        return $query->join("users", "users.id", "=", "installments.user_id");
    }
}