<?php
namespace App\Services\Payment;


use App\Models\ShoppingOrderMargin;
use App\Models\UserCreditMargin;
use App\Services\Payment\UserCredits;
use App\Services\UserHelper;
use App\Services\UserMarign;
use Carbon\Carbon;

class UserBot
{

    public $users;
    public $users_pending;

    public function __construct()
    {
   
        $this->users = [];
        $this->users_pending = [];
    }

   
    public function readUserHasCredits(){
        
        //user by m_sponsor_id die Partner Provisionen haben
        $usersWithPartnerCommission = $this->getUsersWithPartnerCommission(false);

        //user die manuelle Gutschriften haben
        $usersWithCreditMargin = $this->getUsersWithCreditMargin();

        //user die Shop Provisionen haben
        $usersWithShopCommission = $this->getUsersWithShopCommission(false);

          // Alle Benutzer zum Array hinzufügen
        $allUsers = $usersWithPartnerCommission->concat($usersWithCreditMargin)->concat($usersWithShopCommission);
        foreach ($allUsers as $user) {
            //prüfe ob der User Account noch aktiv ist
            if(UserHelper::isActiveAccountByID($user->user_id)){
                $this->addUser($user);
            }
        }
    }
    
    public function readUserHasPendingCredit(){
         //sponsor Users von Provisionen die bezahlt wurden die noch im pending sind
         $usersWithPartnerCommissionPending = $this->getUsersWithPartnerCommission(true);

         $usersWithShopCommissionPending = $this->getUsersWithShopCommission(true);

        // Alle Benutzer zum Array hinzufügen
         $allUsers = $usersWithPartnerCommissionPending->concat($usersWithShopCommissionPending);

        foreach ($allUsers as $user) {
            //prüfe ob der User Account noch aktiv ist
            if(UserHelper::isActiveAccountByID($user->user_id)){
                $this->addUserPending($user);
            }
        }
            
            
    }
    public function getUsers(){
        return $this->users;
    }
    public function getUsersPending(){
        return $this->users_pending;
    }

    private function addUser($user){
        // Prüfen, ob Benutzer bereits existiert
        if (!isset($this->users[$user->user_id])) {
            $this->users[$user->user_id] = $this->createUserCredit($user);
            $this->addCreditItems($user->user_id, false);
        }
    }

    private function addUserPending($user){
        // Prüfen, ob Benutzer bereits existiert
        if (!isset($this->users_pending[$user->user_id])) {
            $this->users_pending[$user->user_id] = $this->createUserCredit($user);
            $this->addCreditItems($user->user_id, true);
        }
    }

   

    private function addCreditItems($user_id, $isPending){
        // Partner Provisionen hinzufügen
        $this->addPartnerCommissionItems($user_id, $isPending);
        
        // Shop Provisionen hinzufügen
        $this->addShopCommissionItems($user_id, $isPending);
        
        // Wenn es nicht ausstehende Credits sind, füge manuelle Gutschriften hinzu
        if (!$isPending) {
            $this->addCreditMarginItems($user_id);
        }
    }

    private function addPartnerCommissionItems($user_id, $isPending){

        $shoppingOrderMargins = UserMarign::getPartnerCommissionItems($user_id, $isPending);
       
        if ($isPending) {
            $targetArray = 'users_pending';
        } else {
            $targetArray = 'users';
        }
                    
        foreach ($shoppingOrderMargins as $shoppingOrderMargin) {
            $entry = $this->createCreditEntry($shoppingOrderMargin);
            
            if ($shoppingOrderMargin->net_partner_commission) {
                $entry->price_formatted = $shoppingOrderMargin->getFormattedNetPartnerCommission();
                $entry->price = $shoppingOrderMargin->net_partner_commission;
            }
            
            $this->{$targetArray}[$user_id]->addItem($entry);
            
            if (!empty($entry->price)) {
                $this->{$targetArray}[$user_id]->total += $entry->price;
            }
        }
    }

    private function addShopCommissionItems($user_id, $isPending){

        $shoppingOrderMargins = UserMarign::getShopCommissionItems($user_id, $isPending);

        if ($isPending) {
            $targetArray = 'users_pending';
        } else {
            $targetArray = 'users';
        }
            
        foreach ($shoppingOrderMargins as $shoppingOrderMargin) {
            $entry = $this->createCreditEntry($shoppingOrderMargin);
            
            $entry->delete = $this->addDeleteButton($shoppingOrderMargin->id, 'shopping_order_margin');
            if ($shoppingOrderMargin->net_discount) {
                $entry->price_formatted = $shoppingOrderMargin->getFormattedNetDiscount();
                $entry->price = $shoppingOrderMargin->net_discount;
            }
            
            $this->{$targetArray}[$user_id]->addItem($entry);
            
            if (!empty($entry->price)) {
                $this->{$targetArray}[$user_id]->total += $entry->price;
            }
        }
    }

    private function addCreditMarginItems($user_id){

        $creditMargins = UserMarign::getUserCreditMarginByUserID($user_id);

        foreach ($creditMargins as $creditMargin) {
            $entry = new \stdClass();
            $entry->badge = '<i class="fa fa-plus-circle text-secondary"></i> ';
            $entry->link = '';//route('admin_credits_detail', [$creditMargin->id]);
            $entry->name = nl2br($creditMargin->message);
            $entry->reference = '';
            $entry->total = '';
            $entry->date = $creditMargin->created_at->format("d.m.Y");
            $entry->price_formatted = formatNumber($creditMargin->credit);
            $entry->price = $creditMargin->credit;
            $entry->delete = $this->addDeleteButton($creditMargin->id, 'user_credit_margin', $creditMargin->deleteTime());
            
            $this->users[$user_id]->addItem($entry);
            
            if (!empty($entry->price)) {
                $this->users[$user_id]->total += $entry->price;
            }
        }
    }

    private function createCreditEntry($shoppingOrderMargin){
        $entry = new \stdClass();
        $entry->badge = \App\Services\Payment::getPaymentForTypeBadge($shoppingOrderMargin->shopping_order);

        if ($shoppingOrderMargin->shopping_order->payment_for === 7 || $shoppingOrderMargin->shopping_order->payment_for === 8) {
            $entry->link = route('admin_sales_detail', [$shoppingOrderMargin->shopping_order->id]);
        } else {
            $entry->link = route('admin_sales_detail', [$shoppingOrderMargin->shopping_order->id]);
        }
        
        $entry->name = $shoppingOrderMargin->shopping_order->shopping_user->billing_firstname . " " . 
                      $shoppingOrderMargin->shopping_order->shopping_user->billing_lastname;
        $entry->reference = $shoppingOrderMargin->shopping_order->getLastShoppingPayment('reference');
        $entry->total = $shoppingOrderMargin->shopping_order->getFormattedTotalWithoutCredit() . " €";
        $entry->date = $shoppingOrderMargin->shopping_order->created_at->format("d.m.Y");
        
        return $entry;
    }

    private function addDeleteButton($id, $type, $deleteTime = false){
        if($type === 'shopping_order_margin'){
            return '<span class="no-line-break">
                        <a class="btn btn-danger btn-xs" href="'.route('admin_payments_credit_delete', [$id, $type]).'" onclick="return confirm(\'Wirklich löschen?\');">
                            <i class="ion ion-ios-trash"></i>
                        </a>
                    </span>';
        }
        if($type === 'user_credit_margin'){
            if($deleteTime){
                return '<span class="no-line-break">
                            <a class="btn btn-danger btn-xs" href="'.route('admin_payments_credit_delete', [$id, $type]).'" onclick="return confirm(\'Wirklich löschen?\');">
                                <i class="ion ion-ios-trash"></i>
                            </a> noch '. $deleteTime .' min.
                        </span>';
            }
        }
        return '';
    }

    /**
     * Gibt User mit Partner Provisionen zurück
     * 
     * @param bool $isPending True für künftige Provisionen, False für fällige Provisionen
     * @return \Illuminate\Database\Eloquent\Collection
     */
    private function getUsersWithPartnerCommission(bool $isPending)
    {
        $query = ShoppingOrderMargin::join('users', 'm_sponsor_id', '=', 'users.id')
            ->groupBy('m_sponsor_id')
            ->join('user_accounts', 'account_id', '=', 'user_accounts.id')
            ->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
            ->whereOrderPaid(true)
            ->whereOutPaid(false)
            ->whereCancellation(false)
            ->wherePartnerCommissionPaid(false)
            ->whereNotNull('partner_commission_pending_to');
            
        if ($isPending) {
            $query->where('partner_commission_pending_to', '>=', Carbon::now());
        } else {
            $query->where('partner_commission_pending_to', '<', Carbon::now());
        }
        
        return $query->get();
    }
    
    /**
     * Gibt User mit Shop Provisionen zurück
     * 
     * @param bool $isPending True für künftige Provisionen, False für fällige Provisionen
     * @return \Illuminate\Database\Eloquent\Collection
     */
    private function getUsersWithShopCommission(bool $isPending)
    {
        $query = ShoppingOrderMargin::join('users', 'user_id', '=', 'users.id')
            ->groupBy('user_id')
            ->join('user_accounts', 'account_id', '=', 'user_accounts.id')
            ->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
            ->whereOrderPaid(true)
            ->whereOutPaid(false)
            ->whereCancellation(false)
            ->whereMarginPaid(false)
            ->whereNotNull('margin_pending_to')
            ->whereIn('status', [7,8]);
            
        if ($isPending) {
            $query->where('margin_pending_to', '>=', Carbon::now());
        } else {
            $query->where('margin_pending_to', '<', Carbon::now());
        }
        
        return $query->get();
    }
    
    /**
     * Gibt User mit manuellen Gutschriften zurück
     * 
     * @return \Illuminate\Database\Eloquent\Collection
     */
    private function getUsersWithCreditMargin()
    {
        return UserCreditMargin::join('users', 'user_id', '=', 'users.id')
        ->join('user_accounts', 'account_id', '=', 'user_accounts.id')
        ->select('user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
        ->wherePaid(false)
        ->get();
    }

    /**
     * Erstellt ein neues UserCredits-Objekt
     * 
     * @param object $user Benutzerdaten
     * @return UserCredits
     */
    private function createUserCredit($user)
    {
        $userCredit = new UserCredits();
        $userCredit->email = $user->email;
        $userCredit->first_name = $user->first_name;
        $userCredit->last_name = $user->last_name;
        $userCredit->user_id = $user->user_id;
        $userCredit->total = 0;
        
        return $userCredit;
    }
}