<?php

namespace App;

use App\Extensions\CustomCompanyBillableTrait;
use App\Repositories\PreferenceRepository;
use App\Repositories\RoleRepository;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class Company extends Model
{

    use Notifiable, CustomCompanyBillableTrait;

    protected $fillable = [
        "name", "slogan", "logo_url", "cif", "address", "city", "county", "country", "phone", "email", "fact_name",
        "fact_address_line1", "fact_address_line2", "fact_zipcode", "fact_city", "fact_county", "fact_country_code",
        "fact_prefix", "fact_serie", "stripe_public_key", "stripe_private_key", "zipcode"
    ];

    protected $appends = ["active_plan", "fiscal_address","usage", "is_stripe_active"];

    protected $hidden = ["stripe_payment_method_id", "stripe_private_key", "stripe_id"];

    protected $casts = [
        "is_stripe_active" => "boolean"
    ];

    /**
     * ATRIBUTS FICTICIS
     */
    public function getActivePlanAttribute() {
        return Subscription::where([
            ["company_id", $this->id],
            ["start_date", "<=", Carbon::now()],
            ["end_date", ">=", Carbon::now()]
        ])->first();
    }

    public function getFiscalAddressAttribute() {
        return $this->fact_address_line1 . " " .
            ($this->fact_address_line2 ? $this->fact_address_line2 . ", "  : "") .
            $this->fact_city . ", " .
            $this->fact_zipcode . " " .
            $this->fact_county . " " .
            $this->fact_country_code;
    }

    public function getUsageAttribute() {
        $n_admins = 0;
        $n_athletes = 0;
        $n_boxes = 0;
        $n_coaches = 0;

        foreach ($this->boxes as $box) {
            $u = $box->usage;
            $n_admins += $u['n_admins'];
            $n_athletes += $u['n_athletes'];
            $n_coaches += $u['n_coaches'];
        }

        $n_boxes = count($this->boxes);

        return [
            "n_admins" => $n_admins,
            "n_athletes" => $n_athletes,
            "n_boxes" => $n_boxes,
            "n_coaches" => $n_coaches,
        ];
    }

    public function getIsStripeActiveAttribute() {
        return $this->stripe_public_key!=null && $this->stripe_private_key!=null;
    }


    /**
     * RELACIONS
     */

    public function subscriptions() {
        return $this->hasMany("App\Subscription")->orderByDesc("start_date")->orderByDesc("id");
    }

    public function roles() {
        return $this->hasMany("App\Role", "company_id", "id");
    }

    public function boxes() {
        return $this->hasMany("App\Box", "company_id", "id");
    }

    public function owner() {
        return $this->belongsTo("App\User", "owner_id");
    }

    public function pricing(){
        return $this->hasMany("App\Pricing", "company_id", "id");
    }

    public function discounts(){
        return $this->hasMany("App\Discount", "company_id", "id");
    }

    public function invoices(){
        return $this->hasMany("App\Invoice", "company_id", "id");
    }

    public function calendar_templates() {
        return $this->hasManyThrough("App\CalendarTemplate", "App\Box");
    }

    public function payments() {
        return $this->hasManyThrough("App\Payment", "App\Box");
    }

    public function user_subscriptions() {
        return $this->hasManyThrough("App\UserSubscription", "App\Pricing")->with("user");
    }

    public function training_rooms() {
        return $this->hasManyThrough("App\TrainingRoom", "App\Box");
    }

    public function training_sessions() {
        return $this->hasManyThrough("App\TrainingSession", "App\Box");
    }

    public function company_orders() {
        return $this->hasManyThrough("App\CompanyOrder", "App\Subscription");
    }

    public function news() {
        return $this->hasMany("App\News");
    }

    public function stripe_users() {
        return $this->hasMany("App\StripeUser");
    }

    public function userBenchmarks() {
        $res = [];
        foreach($this->boxes as $box) {
            foreach($box->userBenchmarks as $b) {
                $res[] = $b;
            }
        }
        return $res;
    }

    public function usersSubscribedByRol() {
        $super_admin = 0;
        $company_admin = 0;
        $box_admin = 0;
        $coach = 0;
        $athlete = 0;

        foreach($this->boxes as $box) {
            foreach($box->activeUserSubscriptions() as $s) {
                switch (RoleRepository::find($s->role_id)->slug) {
                    case "athlete": //Almenys és atleta
                        $athlete += 1;
                        break;
                    case "coach": //Almenys es coach
                        $coach += 1;
                        break;
                    case "box_admin": //Almenys es box admin
                        $box_admin += 1;
                        break;
                    case "company_admin": //Almenys es company admin
                        $company_admin += 1;
                        break;
                    case "super_admin": //es super user
                        $super_admin += 1;
                        break;
                    default:
                        abort(401, "Role to check provided is not valid. " . RoleRepository::find($s->role_id)->name);
                        break;
                }
            }
        }
        return [
            "athlete" => $athlete,
            "coach" => $coach,
            "box_admin" => $box_admin,
            "company_admin" => $company_admin,
            "super_admin" => $super_admin,
        ];
    }

    public function canCreate($role_id) {
        if(!$this->active_plan) return false;
        $capacity = $this->active_plan->plan->getCapacity();
        $use = $this->usersSubscribedByRol();

        $rol = RoleRepository::find($role_id)->slug;

        if ( ($rol == 'company_admin' || $rol == 'box_admin') && (!$capacity['admin'] || ( $capacity['admin'] > ($use['box_admin']+$use['company_admin'])) ) ) return true;
        else if ( $rol == 'coach' && (!$capacity['coach'] || $capacity['coach']>$use['coach']) ) return true;
        else if ( $rol == 'athlete' && (!$capacity['athlete'] || $capacity['athlete']>$use['athlete']) ) return true;
        else return false; // Te en compte si esta intentant crear un super admin
    }

    public function box_orders() {
        return $this->hasManyThrough("App\BoxOrder", "App\Box")->orderByDesc("updated_at");
    }

    public function boxProducts() {
        return $this->hasManyThrough("App\BoxProduct", "App\Box");
    }

    public function boxProductVariants() {
        $res = [];
        foreach($this->boxes as $box) {
            foreach($box->boxProductVariants as $pv) {
                $res[] = $pv;
            }
        }
        return $res;
    }

    public function boxProductImages() {
        $res = [];
        foreach($this->boxes as $box) {
            foreach($box->boxProductImages as $pi) {
                $res[] = $pi;
            }
        }
        return $res;
    }


    /*****************************************************************************
     *                          LARAVEL CASHIER
     ***************************************************************************/
    /*public function taxPercentage() {
        return PreferenceRepository::find("fact_vat_prcnt")->value;
    }*/

    /*****************************************************************************
     *                           NOTIFICATIONS
     ****************************************************************************/
    public function routeNotificationForMail($notification) {
        return $this->email;
    }


}
