<?php

namespace App\Repositories;

use PDF;
use Storage;
use App\Models\Attribute;
use App\Services\Invoice;
use App\Libraries\InvoicePDF;
use App\Models\ShoppingOrder;
use App\Services\MyPDFMerger;
use App\Services\UserService;
use App\Repositories\BaseRepository;

class InvoiceRepository extends BaseRepository {

    private $invoice_date;
    private $invoice_number;
    private $filename;
    private $dir;

    private $delivery_dir;
    private $delivery_filename;


    public function __construct(ShoppingOrder $model)
    {
        $this->model = $model;
    }

    public function create($request = [])
    {
        //need invoice $data
        $number = Invoice::getInvoiceNumber();
        $this->invoice_date = isset($request['invoice_date']) ? $request['invoice_date'] : $this->model->created_at->format("d.m.Y");
        $invoice_send_mail = isset($request['invoice_send_mail']) ? true: false;
        $this->invoice_number = Invoice::createInvoiceNumber($number, $this->invoice_date);
        $this->dir = Invoice::getInvoiceStorageDir($this->invoice_date);
        $this->filename = Invoice::makeInvoiceFilename($this->invoice_number);
        $this->delivery_dir = Invoice::getDeliveryStorageDir($this->invoice_date);
        $this->delivery_filename = Invoice::makeDeliveryFilename($this->invoice_number);

        $this->makePDF();

        $invoice_file = [
                'filename' => $this->filename,
                'dir' => $this->dir,
                'disk' => 'public',
                'invoice_number' => $this->invoice_number,
                'invoice_date' => $this->invoice_date,
        ];

        $delivery_file = [
            'filename' => $this->delivery_filename,
            'dir' => $this->delivery_dir,
            'disk' => 'public',
            'number' => $this->invoice_number,
            'date' => $this->invoice_date,
        ];
        $this->model->invoice = $invoice_file;
        $this->model->delivery = $delivery_file;
        $this->model->invoice_number = $this->invoice_number;
        $this->model->save();
        Invoice::makeNextInvoiceNumber();

        if($invoice_send_mail){
           Invoice::sendInvoiceMail($this->model);
        }
        return true;
    }

    public function update($request = []){
        if(isset($this->model->invoice['filename'])){
            $this->invoice_date = isset($request['invoice_date']) ? $request['invoice_date'] : Invoice::getDate($this->model);
            $invoice_send_mail = isset($request['invoice_send_mail']) ? true: false;
            $this->invoice_number = Invoice::getNumber($this->model);
            $this->dir = Invoice::getDir($this->model);
            $this->filename = Invoice::getFilename($this->model);
            
         
            $this->delivery_dir = Invoice::getDeliveryDir($this->model);
            $this->delivery_filename = Invoice::getDeliveryFilename($this->model);

            $this->makePDF();

            $invoice_file = [
                'filename' => $this->filename,
                'dir' => $this->dir,
                'disk' => 'public',
                'invoice_number' => $this->invoice_number,
                'invoice_date' => $this->invoice_date,
            ];
            $delivery_file = [
                'filename' => $this->delivery_filename,
                'dir' => $this->delivery_dir,
                'disk' => 'public',
                'number' => $this->invoice_number,
                'date' => $this->invoice_date,
            ];

            $this->model->invoice = $invoice_file;
            $this->model->delivery = $delivery_file;
            $this->model->invoice_number = $this->invoice_number;
            $this->model->save();

            if($invoice_send_mail){
                Invoice::sendInvoiceMail($this->model);
             }
             return true;
        }
        return null;
    }

    private function makePDF(){
        $data = [
            'shopping_order' => $this->model,
            'invoice_date' => $this->invoice_date,
            'invoice_number' => $this->invoice_number,
        ];

        if($this->model->auth_user_id){
            UserService::checkUserTaxShippingCountry($this->model->auth_user, $this->model->country_id);
            $data = array_merge($data, UserService::getYardInfo());
        }    
        
        $data['delivery_items'] = $this->prepairForDelivery();

        if(!Storage::disk('public')->exists( $this->dir )){
            Storage::disk('public')->makeDirectory($this->dir); //creates directory
        }
        if(!Storage::disk('public')->exists( $this->delivery_dir )){
            Storage::disk('public')->makeDirectory($this->delivery_dir); //creates directory
        }
        $path = Storage::disk('public')->path('');

        $pdf_file = new InvoicePDF('pdf.invoice');
        $pdf_file->create($data, $this->filename, 'save', $path.$this->dir);
        $pdfMerger = new MyPDFMerger();
        $pdfMerger->addPDF($path.$this->dir.$this->filename);
        $file = $pdfMerger->myMerge('string', $this->filename, 'template_invoice_de');
        Storage::disk('public')->put($this->dir.$this->filename, $file);

        $pdf_file = new InvoicePDF('pdf.delivery');
        $pdf_file->create($data, $this->delivery_filename, 'save', $path.$this->delivery_dir);
        $pdfMerger = new MyPDFMerger();
        $pdfMerger->addPDF($path.$this->delivery_dir.$this->delivery_filename);
        $file = $pdfMerger->myMerge('string', $this->delivery_filename, 'template_delivery_de');
        Storage::disk('public')->put($this->delivery_dir.$this->delivery_filename, $file);
        
    }
    //sort white label products
    private function prepairForDelivery(){
        $shopping_order = $this->model;
        $wl_items = [];
        $items = [];
        $counter = 1;
        $count = 10000;
        foreach($shopping_order->shopping_order_items as $shopping_order_item){
            $labels = [];
            $sorter = 0;
            if($shopping_order_item->product->whitelabel){

                 //get white label default etikett (s)
                 //ist ausschlaggebend für die etikettierung, ob 1 oder mehr etiketten
                 if($shopping_order_item->product->whitelabel_images){
                    foreach($shopping_order_item->product->whitelabel_images as $whitelabel_image){
                        $labels[] = $whitelabel_image;
                    }
                }
                //has white label user etikett
                if($shopping_order->auth_user){
                    $whitelabel_product = $shopping_order->auth_user->whitelabel_products()->where('product_id', '=', $shopping_order_item->product->id)->first();
                    if($whitelabel_product && $whitelabel_product->whitelabel_images){
                        foreach($whitelabel_product->whitelabel_images as $whitelabel_image){
                            if($whitelabel_image->attributes && is_array($whitelabel_image->attributes)){
                                foreach($labels as $key => $label){
                                        foreach($whitelabel_image->attributes as $attribute){
                                            if(in_array($attribute, $label->attributes)){
                                                //found and overwrite
                                                if(!$this->model->user_white_label){
                                                    $this->model->user_white_label = true;
                                                    $this->model->save();
                                                }
                                                $labels[$key] = $whitelabel_image;
                                            }
                                        }
                                }
                            }
                        }
                    }
                }
                foreach($labels as $key=>$label){
                    //label hat attribue 
                    $varinats = []; 
                    if($label->attributes && is_array($label->attributes)){
                        foreach($label->attributes as $attribute){
                            if($attribute = Attribute::find($attribute)){
                                if(!isset($varinats[$attribute->value])){
                                    $temp = explode('#', $attribute->value);
                                    $sorter = $temp[1] > $sorter ? $temp[1] : $sorter;
                                    $label->varinat = [
                                            'key'   =>  $attribute->value,
                                            'id'    => $attribute->id,
                                            'vol'   => (float) $temp[0],
                                            'size'  => (float) $temp[1],
                                            'name'   => $label->product_id ? 'Standard' : $attribute->name,
                                            ];
                                }
                            }
                        }    
                    }else{
                        //sonst auf standard zurückgreifen
                        if($shopping_order_item->product->attribute_variants){
                            foreach($shopping_order_item->product->attribute_variants as $attribute_variant){
                                if(!isset($varinats[$attribute_variant->attribute->value])){
                                    $temp = explode('#', $attribute_variant->attribute->value);
                                    $sorter = $temp[1] > $sorter ? $temp[1] : $sorter;
                                    $label->varinat = [
                                            'key'   =>  $attribute_variant->attribute->value,
                                            'id'    => $attribute_variant->attribute->id,
                                            'vol'   => (float) $temp[0],
                                            'size'  => (float) $temp[1],
                                            'name'  =>  'Standard',
                                        ];
                                }
                            }
                        }
                    }              
                }
                //sorten of white label products
                $sorter = intval((float) $sorter * 100 + $counter++);
                $shopping_order_item->labels = $labels;
                $wl_items[$sorter] = $shopping_order_item; 
            }else{
                $items[$count++] = $shopping_order_item;
            }
        }
        //kleine zuerst
        ksort($wl_items);
        return array_merge($wl_items, $items);
    }
}