<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Vente;
use App\Models\VenteClient;
use App\Models\FactureGlobale;

use DB;

class InvoiceController extends Controller
{
    
    public function generateInvoice($id)
    {
      
        $order= Vente::find($id);
        //Si commande introuvable ou pas de ligne vente, retour
        if(empty($order) || !$order->ligneventes)
        {
           return back()->with(['error'=>"Commande introuvable ou pas de ligne vente"]);
        }
		
        //Infos de facture
        $facture['user_id']=$order->user_id;
        $facture['user_name']=$order->nom_user;
        $facture['type']='FV';
        $facture['cifu']='';
        $facture['cname']='';
        $facture['old_ref']='';
        if($order->nomcli!="" && $order->ifu_client !="")
        {
            $facture['cifu']=$order->ifu_client;
            $facture['cname']=$order->nomcli;
        }

        $facture['aib']=0;
        $facture['remise']=0;
		//dd($facture);
        //1. Initialisation de la facture
        //$inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type'], $facture['aib'], $facture['cifu'], $facture['cname'], $facture['old_ref']);
        $inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type']);
		//dd($inv_init);
		$inv_init =(array)json_decode($inv_init);
		//dd($inv_init);
        if ($inv_init['status'] == 'success') {
            //Récupération du token de la facture
            $token = $inv_init['token'];
            //Remise (0 par défaut)
            $discount = ((int)$facture['remise']>0) ? $facture['remise'] : 0;

            /*5. Enregistrer les produits*/
            $produits = $order->ligneventes;

            foreach ($produits as $k => $pdt) {
                //insert_pdt: token, nom_pdt, description_pdt, code_taxe, prix, qté, remise
				if($pdt->produit){
					 $insert_pdt = $this->add_product_to_invoice($token, $pdt->produit->designation , '',
                    'E', $pdt->pv, $pdt->qte, $discount);
					$insert_pdt =(array)json_decode($insert_pdt);
					//Si l'un des produits n'a pas pu être enregistrer, on annule la facture
					if ($insert_pdt['status'] == 'error') {
						$this->cancel_invoice($token);
						return back()->with(['error'=>"Erreur d'insertion du produit ".$pdt->produit->designation]);
					}
				}
            }

            /*6. Vérifier le total */
            //si la commande ne passe pas ou le total ne correspond pas
            $total = $this->get_invoice_total($token);
            $total =(array)json_decode($total);
            $total_data = (array)$total['data'];

            if ($total['status'] == 'error') {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de recupération du total"]);
           }else{
                $facture=array_merge($facture, $total_data);
            }

            /*8. Confirmer la facture*/
            $confirm = $this->confirm_invoice($token);
            $confirm =(array)json_decode($confirm);
            if ($confirm['status'] == 'success') {
                //Si la facture est confirmée, on enregistre les infos de retour
                $inv_data = (array)$confirm['data'];
                $up_data = [
                    'nim' => $inv_data['nim'],
                    'date' => $inv_data['dt'],
                    'sig' => $inv_data['sig'],
                    'compteur'=> $inv_data['fc'].'/'. $inv_data['tc'].' '.$facture['type'],
                    'display_sig' => substr(chunk_split($inv_data['sig'], 4, "-"), 0, 29),
                    'type_fac' => $inv_data['tc'],
                    'num_fac' => $inv_data['fc'],
                    'qrcode' => 'F;' . $inv_data['nim'] . ';' . $inv_data['sig'] . ';' . $inv_data['ifu'] . ';' . $inv_data['dt'],
                ];

                $facture = array_merge($facture, $up_data);

                $order->update([
                    'nim'=>$facture['nim'],
                    //'date_mef'=>$facture['date'],
                    'date_mef'=>now(),
                    'sig'=>$facture['sig'],
                    'type_fac'=>$facture['type_fac'],
                    'compteur'=>$facture['compteur'],
                    'num_fac'=>$facture['num_fac'],
                    'qrcode'=>$facture['qrcode'],
                    'display_sig'=>$facture['display_sig'],
                    'mvb'=>$facture['mvb'],
                    'mvc'=>$facture['mvc'],
                    'mvd'=>$facture['mvd'],
                    'mve'=>$facture['mve'],
                    'mvf'=>$facture['mvf'],
                    'mts'=>$facture['mts'],
                    'mv'=>$facture['mv'],
                ]);

                return back()->with(['status'=>"Facture générée avec succès."]);

            } else {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de confirmation de la facture"]);
            }
        } else {
			
            return back()->with(['error'=>"Erreur d'initialisation de la facture"]);
			
        }
    }


    //
	public function retrive_mcf_service($url, $method = 'GET', $data = [])
    {
        $link = "http://127.0.0.1:5000/" . $url;
        try {
            $curl = curl_init($link);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLINFO_HEADER_OUT, true);

            if ($method == 'POST') {
                curl_setopt($curl, CURLOPT_POST, true);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }

            $response = curl_exec($curl);
            curl_close($curl);
            return $response;

        } catch (Exception $e) {
            return ['status' => 'error', 'status_code' => 500, 'message' => $e->getMessage()];
        }
    }
	//
	function get_device_state()
    {
        return $this->retrive_mcf_service('device-state');
    }
	//
	function get_invoice_total($token)
    {
        return $this->retrive_mcf_service('invoice-total/' . $token);
    }
	//
	function cancel_invoice($token)
    {
        return $this->retrive_mcf_service('cancel-invoice/' . $token, 'POST');
    }
	//
	function confirm_invoice($token)
    {
        return $this->retrive_mcf_service('confirm-invoice/' . $token, 'POST');
    }
    
    //définition de la méthode de paiement
	function set_payment_method($token, $type = 'E', $amount = '')
    {
        $data = [
            'type' => $type,
            'amount' => $amount
        ];
        return $this->retrive_mcf_service('set-payment-method/' . $token, 'POST', $data);
    }
	//
	function add_product_to_invoice($token, $name, $desc, $tax, $price, $qty = 1, $discount = 0, $spec_tax = '', $spec_tax_desc = '')
    {
        $data = [
            'name' => $name,
            'desc' => $desc,
            'tax' => $tax,
            'quantity' => $qty,
            'spec_tax' => $spec_tax,
            'spec_tax_desc' => $spec_tax_desc,
            'orig_price' => '',
            'orig_price_desc' => '',
        ];

        if ($discount > 0) {
            $data["price"] = round($price * (1 - ($discount / 100)), 0, PHP_ROUND_HALF_UP);
            $data["orig_price"] = $price;
            $data["orig_price_desc"] = 'Remise de ' . $discount . '%';
        } else {
            $data["price"] = $price;
        }
        return $this->retrive_mcf_service('add-product/' . $token, 'POST', $data);
    }
	//
	function init_invoice($user_id, $user_name, $invoice_type, $aib = 0, $customer_ifu = '', $customer_name = '', $old_ref = '')
    {
        $data = [
            'cashier_id' => $user_id,
            'cashier_name' => $user_name,
            'invoice_type' => $invoice_type,
            'old_ref' => $old_ref,
            'customer_ifu' => $customer_ifu,
            'customer_name' => $customer_name,
            'aib' => $aib,
        ];
        return $this->retrive_mcf_service('create-invoice', 'POST', $data);
    }
	
	//GENERATION VENTECLIENT FACTURE
	public function generateInvoice2($id)
    {
      
        $order= VenteClient::find($id);
        //Si commande introuvable ou pas de ligne vente, retour
        if(empty($order) || !$order->ligneventesclient)
        {
           return back()->with(['error'=>"Commande introuvable ou pas de ligne vente"]);
        }
		
        //Infos de facture
        $facture['user_id']=$order->user_id;
        $facture['user_name']=$order->nom_user;
        $facture['type']='FV';
        $facture['cifu']='';
        $facture['cname']='';
        $facture['old_ref']='';
        if($order->nom_client!="" && $order->ifu_client !="")
        {
            $facture['cifu']=$order->ifu_client;
            $facture['cname']=$order->nom_client;
        }

        $facture['aib']=0;
        $facture['remise']=0;
		//dd($facture);
        //1. Initialisation de la facture
        //$inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type'], $facture['aib'], $facture['cifu'], $facture['cname'], $facture['old_ref']);
        $inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type']);
		$inv_init =(array)json_decode($inv_init);
		//dd($inv_init);
        if ($inv_init['status'] == 'success') {
            //Récupération du token de la facture
            $token = $inv_init['token'];
            //Remise (0 par défaut)
            $discount = ((int)$facture['remise']>0) ? $facture['remise'] : 0;

            /*5. Enregistrer les produits*/
            $produits = $order->ligneventesclient;

            foreach ($produits as $k => $pdt) {
                //insert_pdt: token, nom_pdt, description_pdt, code_taxe, prix, qté, remise
				if($pdt->produit){
					 $insert_pdt = $this->add_product_to_invoice($token, $pdt->produit->designation , '',
                    'E', $pdt->pv, $pdt->qte, $discount);
					$insert_pdt =(array)json_decode($insert_pdt);
					//Si l'un des produits n'a pas pu être enregistrer, on annule la facture
					if ($insert_pdt['status'] == 'error') {
						$this->cancel_invoice($token);
						return back()->with(['error'=>"Erreur d'insertion du produit ".$pdt->produit->designation]);
					}
				}
            }

            /*6. Vérifier le total */
            //si la commande ne passe pas ou le total ne correspond pas
            $total = $this->get_invoice_total($token);
            $total =(array)json_decode($total);
            $total_data = (array)$total['data'];

            if ($total['status'] == 'error') {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de recupération du total"]);
           }else{
                $facture=array_merge($facture, $total_data);
            }

            /*8. Confirmer la facture*/
            $confirm = $this->confirm_invoice($token);
            $confirm =(array)json_decode($confirm);
            if ($confirm['status'] == 'success') {
                //Si la facture est confirmée, on enregistre les infos de retour
                $inv_data = (array)$confirm['data'];
                $up_data = [
                    'nim' => $inv_data['nim'],
                    'date' => $inv_data['dt'],
                    'sig' => $inv_data['sig'],
                    'compteur'=> $inv_data['fc'].'/'. $inv_data['tc'].' '.$facture['type'],
                    'display_sig' => substr(chunk_split($inv_data['sig'], 4, "-"), 0, 29),
                    'type_fac' => $inv_data['tc'],
                    'num_fac' => $inv_data['fc'],
                    'qrcode' => 'F;' . $inv_data['nim'] . ';' . $inv_data['sig'] . ';' . $inv_data['ifu'] . ';' . $inv_data['dt'],
                ];

                $facture = array_merge($facture, $up_data);

                $order->update([
                    'nim'=>$facture['nim'],
                    'date_mef'=>now(),
                    'sig'=>$facture['sig'],
                    'type_fac'=>$facture['type_fac'],
                    'compteur'=>$facture['compteur'],
                    'num_fac'=>$facture['num_fac'],
                    'qrcode'=>$facture['qrcode'],
                    'display_sig'=>$facture['display_sig'],
                    'mvb'=>$facture['mvb'],
                    'mvc'=>$facture['mvc'],
                    'mvd'=>$facture['mvd'],
                    'mve'=>$facture['mve'],
                    'mvf'=>$facture['mvf'],
                    'mts'=>$facture['mts'],
                    'mv'=>$facture['mv'],
                ]);

                return back()->with(['status'=>"Facture générée avec succès."]);

            } else {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de confirmation de la facture"]);
            }
        } else {
			
            return back()->with(['error'=>"Erreur d'initialisation de la facture"]);
			
        }
    }
	//
	//GENERATION FACTURE GLOBALE
	public function generateInvoice3($id)
    {
      
        $order= FactureGlobale::find($id);
        //Si commande introuvable ou pas de ligne vente, retour
        if(empty($order) || !$order->lignefactureglobales)
        {
           return back()->with(['error'=>"Commande introuvable ou pas de ligne vente"]);
        }
		
        //Infos de facture
        $facture['user_id']=$order->user_id;
        $facture['user_name']=$order->nom_user;
        $facture['type']='FV';
        $facture['cifu']='';
        $facture['cname']='';
        $facture['old_ref']='';
        if($order->nom_client!="" && $order->ifu_client !="")
        {
            $facture['cifu']=$order->ifu_client;
            $facture['cname']=$order->nom_client;
        }

        $facture['aib']=0;
        $facture['remise']=0;
		//dd($facture);
        //1. Initialisation de la facture
        //$inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type'], $facture['aib'], $facture['cifu'], $facture['cname'], $facture['old_ref']);
        $inv_init = $this->init_invoice($facture['user_id'], $facture['user_name'],$facture['type']);
		$inv_init =(array)json_decode($inv_init);
		//dd($inv_init);
        if ($inv_init['status'] == 'success') {
            //Récupération du token de la facture
            $token = $inv_init['token'];
            //Remise (0 par défaut)
            $discount = ((int)$facture['remise']>0) ? $facture['remise'] : 0;

            /*5. Enregistrer les produits*/
            $produits = $order->lignefactureglobales;

            foreach ($produits as $k => $pdt) {
                //insert_pdt: token, nom_pdt, description_pdt, code_taxe, prix, qté, remise
				if($pdt->service){
					 $insert_pdt = $this->add_product_to_invoice($token, $pdt->service->designation , '',
                    'E', $pdt->pv, $pdt->qte, $discount);
					$insert_pdt =(array)json_decode($insert_pdt);
					//Si l'un des produits n'a pas pu être enregistrer, on annule la facture
					if ($insert_pdt['status'] == 'error') {
						$this->cancel_invoice($token);
						return back()->with(['error'=>"Erreur d'insertion du produit ".$pdt->service->designation]);
					}
				}
            }

            /*6. Vérifier le total */
            //si la commande ne passe pas ou le total ne correspond pas
            $total = $this->get_invoice_total($token);
            $total =(array)json_decode($total);
            $total_data = (array)$total['data'];

            if ($total['status'] == 'error') {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de recupération du total"]);
           }else{
                $facture=array_merge($facture, $total_data);
            }

            /*8. Confirmer la facture*/
            $confirm = $this->confirm_invoice($token);
            $confirm =(array)json_decode($confirm);
            if ($confirm['status'] == 'success') {
                //Si la facture est confirmée, on enregistre les infos de retour
                $inv_data = (array)$confirm['data'];
                $up_data = [
                    'nim' => $inv_data['nim'],
                    'date' => $inv_data['dt'],
                    'sig' => $inv_data['sig'],
                    'compteur'=> $inv_data['fc'].'/'. $inv_data['tc'].' '.$facture['type'],
                    'display_sig' => substr(chunk_split($inv_data['sig'], 4, "-"), 0, 29),
                    'type_fac' => $inv_data['tc'],
                    'num_fac' => $inv_data['fc'],
                    'qrcode' => 'F;' . $inv_data['nim'] . ';' . $inv_data['sig'] . ';' . $inv_data['ifu'] . ';' . $inv_data['dt'],
                ];

                $facture = array_merge($facture, $up_data);

                $order->update([
                    'nim'=>$facture['nim'],
                    'date_mef'=>now(),
                    'sig'=>$facture['sig'],
                    'type_fac'=>$facture['type_fac'],
                    'compteur'=>$facture['compteur'],
                    'num_fac'=>$facture['num_fac'],
                    'qrcode'=>$facture['qrcode'],
                    'display_sig'=>$facture['display_sig'],
                    'mvb'=>$facture['mvb'],
                    'mvc'=>$facture['mvc'],
                    'mvd'=>$facture['mvd'],
                    'mve'=>$facture['mve'],
                    'mvf'=>$facture['mvf'],
                    'mts'=>$facture['mts'],
                    'mv'=>$facture['mv'],
                ]);

                return back()->with(['status'=>"Facture générée avec succès."]);

            } else {
                $this->cancel_invoice($token);
                return back()->with(['error'=>"Erreur de confirmation de la facture"]);
            }
        } else {
			
            return back()->with(['error'=>"Erreur d'initialisation de la facture"]);
			
        }
    }

}
