<?php

namespace App\Http\Controllers;

use App\Repositories\DemandeRepository;
use Illuminate\Http\Request;
use App\Commune;
use App\Adresse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use App\Message;
use App\Demande;
use Carbon\Carbon;
use App\Document;
use App\User;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
use App\Societe;
use Illuminate\Routing\Route;
use App\Statut;
use App\Paiement;


class DemandeController extends Controller
{
    //
    protected $demandeRepository;
    public function __construct(DemandeRepository $demandeRepository)
    {
        $this->demandeRepository = $demandeRepository;
        $this->middleware('auth');
        $this->middleware('verified');
        //Carbon::setUTF8(true);
        Carbon::setLocale(config('app.locale'));
        setlocale(LC_TIME, 'fr_FR.UTF-8');// Ne fonctionne pas en local mais c'est ...normal :/ fonctionne sur ubuntu
        //setlocale(LC_ALL, ''); sur windows
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        //
        //
        $statuts = Statut::all();
        if (Auth::user()->prestataire)
            return redirect(route('interventions.index'));
        
        if (request()->route()->getName() == 'factures.index'){
            $demandes = Demande::whereNotNull('user_id')->where('facture','=',1)->orderby('demandes.created_at','desc');
            if($request->datedeb)
                $demandes = $demandes->where('date_facture','>=',$request->datedeb);
            if($request->datefin)
                $demandes = $demandes->where('date_facture','<=',$request->datefin.' 23:59');
            if($request->user){
                $demandes = $demandes->where('user_id','=',$request->user);
            }
            /*if($request->statut_id)
                $demandes = $demandes->join('demande_statut','demandes.id','=','demande_id')->where('statut_id','=',$request->statut_id);*/
            $demandes = $demandes->paginate(5)->appends(["datedeb"=>$request->datedeb,"datefin"=>$request->datefin,"user"=>$request->user]);
            return view('demandes.indexfactures', compact('demandes','statuts'));
        }
        else        
            $demandes = $this->demandeRepository->getPaginate(5,$request);
        
        //if($request->datedeb || $request->datefin)
        $demandes = $demandes->appends(["datedeb"=>$request->datedeb,"datefin"=>$request->datefin,"status"=>$request->status]);
        if ($request->user)
            $demandes = $demandes->appends(['user'=>$request->user]);
        //$demandes = Demande::with('messages.user')->orderby('created_at','desc')->get();
        
        return view('demandes.index', compact('demandes','statuts'));
    }
    
    public function indexUser(){
        //$demandes = Demande::with('messages.user')->orderby('created_at','desc')->get();
        if (Auth::user()->assistant || Auth::user()->admin)
            $demandes = Demande::orderby('created_at','desc')->get();
        else
            $demandes = auth()->user()->demandes()->orderby('created_at','desc')->get();
        
        return view('demandes.index', compact('demandes'));
    }
    
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
        $adresses = Auth::user()->adresses->all();
        return view('demandes.create',
            compact('adresses'));
    }
    
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
        $request->flash();
        if (!$this->validate($request, [
            "message"    => 'required|max:1024',
            "libelle"       => 'required|max:191',
            'adresse_id' => 'max:191',
            "documents.*" => 'mimetypes:image/jpeg,image/jpg,image/png,document/pdf,application/pdf'
        ]))
            return redirect(route('demandes.create'))->withInput();
        $inputs = array_merge($request->all(),
            [
                'user_id' => Auth::id()
            ]);
            
        $demande = $this->demandeRepository->store($inputs);
        
        //Créer le premier message
        
        if ($request->has('message') || $request->has('documents'))
        {
            $message = $demande->messages()->create(['user_id'=>Auth::id(),'text' => $request->message]);
            if ($request->hasFile('documents')){
                foreach($request->file('documents') as $fichier)
                
                {
                    
                    /* $name=$file->getClientOriginalName();
                    
                    $file->move(public_path().'/files/', $name);
                    
                    $data[] = $name;*/
                    
                    $path = basename($fichier->store('documents'));
                    $document = Document::create([
                        "libelle" => $fichier->getClientOriginalName(),//'message_' . $message->id,
                        "nom_fichier" => $path,//$fichier->getClientOriginalName(),
                        "url" => '',
                        "type_mime" => $fichier->clientExtension()
                    ]);
                    $documents[] = $document->id;
                }
                
                
                $message->documents()->attach($documents);
            }
        }
        
        
        
        //return redirect(route('demandes.show',$demande->id));
        return redirect(route('demandes.show',$demande->id))->with("message","Votre message a été posté. Une notification a été envoyée aux administrateurs.");
        //return redirect(route('home'))->with('message',"La demande " . $demande->id ." a été créée");
    }
    
    public function messageLu(Request $request){
        $msgId = $request->id;
        if($msgId)
            $message = Message::find(substr($msgId,1))->update(['lu'=>'1']);
        return response()->json(['result'=>'haha']);
    }
    
    
    
    
    /**
     * Interroge le serveur uniskip pour savoir si la transaction est ok
     */
    private function uniskipQRVerif($demande){
        $data1 = [
            'creditemail' => config('payments.uniskip.merchant'),
            'password' => config('payments.uniskip.password'),
            'label' => $demande->transaction_id,
        ];
        $curl = curl_init();
        
        $ok = curl_setopt_array($curl, array(
            CURLOPT_URL => "https://".config('payments.uniskip.api_url').config('payments.uniskip.QR.verifier_endpoint'),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30000,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_POST=>1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $data1,
            CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json',
                'Accept: application/json'
            )
        ));
        
        $content = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);
        
        
        if ($err)
            return null;
            else
                $reponse = json_decode($content,true);
                
                if ($reponse['status']=='ok' && $reponse['devise']=='EUR')
                {
                   return ["mode"=>"QR","done"=>true];
                }
                else
                {
                    return ["mode"=>"QR","done"=>false];
                }
    }
    
    /**
     * Interroge le serveur uniskip pour savoir si la transaction est ok
     * méthode appelée à intervalle regulier par JS
     * dans la page uniskip payment
     */
    public function uniskipCBVerif($demande){
        
        $data1 = [
            'id' => substr($demande->transaction_id,4),
            'etape' => '6',
        ];
        $curl = curl_init();
        
        $ok = curl_setopt_array($curl, array(
            CURLOPT_URL => "https://".config('payments.uniskip.api_url').config('payments.uniskip.CB.verifier_endpoint'),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30000,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_POST=>1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $data1,
            CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json',
                'Accept: application/json'
            )
        ));
        
        $content = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);
        
        if ($err)
            return null;
            else
                $reponse = json_decode($content,true);


        if ((($reponse['statut']=='4') //Accepté par débiteur
            && ($reponse['resultat_transaction']=='1') //Débit effectué
            && ($reponse['devise']=='EUR')
            && ($reponse['email_a_crediter']==config('payments.uniskip.merchant'))
            )
            )
        {
            return ["mode"=>"CB","done"=>true];
            
        }
        else return ["mode"=>"CB","done"=>false];
    }
    
    
    private function transactionEffectuee ($demande){
        $societe = Societe::first();
        if ($societe->email_uniskip && $societe->motdepasse_uniskip)
            config([
                'payments.uniskip.merchant'=>$societe->email_uniskip,
                'payments.uniskip.password'=>$societe->motdepasse_uniskip]);
            
        if (
            (substr($demande->transaction_id,0,3) == "UQR" && $paiement = $this->uniskipQRVerif($demande))
            || (substr($demande->transaction_id,0,3) == "UCB" && $paiement = $this->uniskipCBVerif($demande))
            )
            //une transaction uniskip a été effectuée mais pas enregistrée
            return $paiement;
        else
            return false;
    }
    
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $demande = $this->demandeRepository->getById($id);
        
        if (!Auth::user()->isAdmin()
            && !Auth::user()->assistant
            && Auth::id()!=$demande->user_id)
            return abort(403, 'Unauthorized action.');
        
            
        //--Gestion des erreurs d'enregistrement des paiements
            //Si pas d'entrée dans la table des paiements
            //mais qu'il existe une transaction dans demande
            // ET que cette transaction a été validée chez uniskip
        
        
        $valider_paiement = (!Paiement::where('transaction_id','=',$demande->transaction_id)->first())
                    ?$this->transactionEffectuee($demande)
                    :false;
        
        if ($demande->transaction_id
            && ($valider_paiement && $valider_paiement['done'] == true)
            )
            //une transaction a été initiée et a abouti
            //mais la confirmation n'a pas été récupérée (validée chez prestataire 
            //et le paiement n'a pas été enregistré en base
        {
            
            //$valider_paiement = true;
            return view('demandes.show', compact('demande','valider_paiement'));
        }
        
        if ($demande->intervention
            && !$demande->isPaid())//->exists())
            return $this->afficheDemandeAvecDevis($demande);
        
        
            
        return view('demandes.show',
            compact('demande'));
    }
    
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function voirDevis($id)
    {
        
        $demande = $this->demandeRepository->getById($id);
        //$prestataires = User::where('prestataire','=',1)->get();
        return $this->afficheDevis($demande);
    }
    
    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
        $demande = $this->demandeRepository->getById($id);
        //
        return view('demandes.edit',  compact('demande'));
    }
    
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        
        if (!$this->validate($request, [
            "message"    => 'required|max:1024',
            "documents.*" => 'mimetypes:image/jpeg,image/jpg,image/png,document/pdf,application/pdf'
        ]))
            return $this->edit($id);
            
        $demande = $this->demandeRepository->update($id, $request->all());
        
        if ($request->has('message') || $request->has('documents'))
        {
            //le client a validé le devis
            if ($demande->statuts->last() && $demande->statuts->last()->id=="DEVISEE" && $request->bpadevis=='on')
            {
                $demande->statuts()->attach(['statut_id'=>'BPA']);
                $message = $demande->messages()->create(['user_id'=>Auth::id(),'text' => "J'accepte sans réserve le devis qui m'est proposé"]);
            }
            else if ($request->is_rapport && Auth::user()->isAdmin())
                $message = $demande->messages()->create([
                    'user_id'=>Auth::id(),
                    'text' => $request->message,
                    'rapport_flag' => true]);
            else  
            $message = $demande->messages()->create(['user_id'=>Auth::id(),'text' => $request->message]);
            
            if ($request->hasFile('documents')){
                foreach($request->file('documents') as $fichier)
                {
                    
                   /* $name=$file->getClientOriginalName();
                    
                    $file->move(public_path().'/files/', $name);
                    
                    $data[] = $name;*/
                    
                    $path = basename($fichier->store('documents'));
                    $document = Document::create([
                        "libelle" => $fichier->getClientOriginalName(),//'message_' . $message->id,
                        "nom_fichier" => $path,//$fichier->getClientOriginalName(),
                        "url" => '',
                        "type_mime" => $fichier->clientExtension()
                    ]);
                    $documents[] = $document->id;
                }
                $message->documents()->attach($documents);
            }
        }
        
        return redirect(route('demandes.show',$demande->id))->with("message","Votre message a été posté. Une notification a été envoyée au destinataire.");
    }
    
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
    
    
    private function arrondir($nombre,$decimales=2){
        return round($nombre,2);
    }
    
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function afficheDemandeAvecDevis($demande,$vuePDF=false)
    {
        //
        //return view('caisse.tickets.show',compact('ticket'));
        
        
        
        //Récupérer les infos de ma société
        //Stockée dans les données du user gerant
        //$gerant_societe = User::where('gerant','=',1)->first();
        $res = $this->infosDevis($demande);
        $ligne_demandes = $res['ligne_demandes'];
        $totalDemandeHT = $res['totalDemandeHT'];
        $totalDemandeTTC = $res['totalDemandeTTC'];
        $totauxTVA = $res['totauxTVA'];
        if ($vuePDF){
            $pdf = App::make('dompdf.wrapper');
            $pdf->loadView('demandes.showRapportPDF', compact('demande','ligne_demandes','totalDemandeHT','totalDemandeTTC','totauxTVA'));
            
            return $pdf->stream();
            
        } else
            return view('demandes.show', compact('demande','ligne_demandes','totalDemandeHT','totalDemandeTTC','totauxTVA'));
        
       
        
    }
    
    public function afficheDevis($demande,$vuePDF=false)
    {
        $res = $this->infosDevis($demande);
        $ligne_demandes = $res['ligne_demandes'];
        $totalDemandeHT = $res['totalDemandeHT'];
        $totalDemandeTTC = $res['totalDemandeTTC'];
        $totauxTVA = $res['totauxTVA'];
        if ($vuePDF){
            $pdf = App::make('dompdf.wrapper');
            $pdf->loadView('demandes.showRapportPDF', compact('demande','ligne_demandes','totalDemandeHT','totalDemandeTTC','totauxTVA'));
            
            return $pdf->stream();
            
        } else
            return view('demandes.showdevis', compact('demande','ligne_demandes','totalDemandeHT','totalDemandeTTC','totauxTVA'));
    }
    
    private function infosDevis($demande){
        $totalDemandeHT = 0;
        $totalDemandeTTC = 0;
        $totauxTVA=[];
        $ligne_demandes=array();
        
        foreach ($demande->ligne_demandes as $ligne_demande){
            $t= [];
            $t["libelle"] = $ligne_demande["libelle"];
            $t["montant_ht"] = $ligne_demande["montant_ht"];
            
            $puttc = $this->arrondir($ligne_demande->montant_ht * (1+$ligne_demande->taux_tva/100));
            $t["montant_ttc"] = $puttc;
            $t["taux_tva"] = $ligne_demande->taux_tva;
            $montantTVA = $this->arrondir($ligne_demande->montant_ht *  $ligne_demande->taux_tva/100);
            $t["montant_tva"] = $montantTVA;
            
            $ligne_demandes[] = $t;
            $totalProduitHT = $this->arrondir($ligne_demande->montant_ht);
            $totalProduitTTC = $this->arrondir($totalProduitHT*(1+$ligne_demande->taux_tva/100));
            $totalDemandeHT += $totalProduitHT;
            $totalDemandeTTC += $totalProduitTTC;
            $totalDemandeTTC = $this->arrondir($totalDemandeTTC);
            if(!array_key_exists("".$ligne_demande->taux_tva, $totauxTVA))
                $totauxTVA["".$ligne_demande->taux_tva] = $montantTVA;
            else
                $totauxTVA["".$ligne_demande->taux_tva] += $montantTVA;
        }
        
        //A ce stade on enregistre le total ttc dans demande
        //c'est le dernier montant affiché qui doit être archivé dans la table demande
        $demande->total_ttc = $totalDemandeTTC;
        $demande->save();
        
        return [
            'ligne_demandes'=> $ligne_demandes,
            'totalDemandeHT'=> $totalDemandeHT,
            'totalDemandeTTC' => $totalDemandeTTC,
            'totauxTVA' => $totauxTVA
        ];
    }
    
    public function showFacture($id){
        $demande = $this->demandeRepository->getById($id);
        $res = $this->infosDevis($demande);
        $ligne_demandes = $res['ligne_demandes'];
        $totalDemandeHT = $res['totalDemandeHT'];
        $totalDemandeTTC = $res['totalDemandeTTC'];
        $totauxTVA = $res['totauxTVA'];
        //dd($totauxTVA);
        //return view('demandes.show', compact('demande','ligne_demandes','totalDemandeHT','totalDemandeTTC','totauxTVA'));
        
        $societe = Societe::first();
        //DB::connection()->enableQueryLog();
        $image = DB::table('documents')
                ->join('document_message','documents.id','=','document_message.document_id')
                ->join('messages','document_message.message_id','=','messages.id')
                ->where('demande_id','=',$demande->id)
                ->where('documents.libelle','=','signature_devis')
                ->orderBy('messages.created_at','desc')
                ->first();
        
        $pdf = App::make('dompdf.wrapper');
        $pdf->loadView('demandes.showFacturePDF', 
            compact('societe','demande','ligne_demandes',
                    'totalDemandeHT','totalDemandeTTC','totauxTVA','image'));
        
        return $pdf->stream();
    }
    
    
    public function showFactureArtisan($id){
        $demande = $this->demandeRepository->getById($id);
        
        $societe = Societe::first();
        //DB::connection()->enableQueryLog();
        
        $montant_prestation_ht = round($demande->intervention->montant_prestation_ht,2);
        $montant_tva = $societe->tva_travaux->taux * $montant_prestation_ht/100;
        $montant_prestation_ttc = $montant_prestation_ht + $montant_tva;
        
        
        $pdf = App::make('dompdf.wrapper');
        $pdf->loadView('demandes.showFactureArtisanPDF',
            compact('societe','demande','montant_prestation_ht','montant_tva','montant_prestation_ttc'));
            
            return $pdf->stream();
    }
    
    public function showRapport($id){
        Carbon::setUTF8(true);
        Carbon::setLocale(config('app.locale'));
        setlocale(LC_ALL, '');
        $demande = $this->demandeRepository->getById($id);
        //$prestataires = User::where('prestataire','=',1)->get();
        if ($demande->intervention
            && $demande->statuts()->find('DEVISEE'))//->exists())
            return $this->afficheDemandeAvecDevis($demande,true);

        
        $pdf = App::make('dompdf.wrapper');
        $pdf->loadView('demandes.showRapportPDF',
            compact('demande'));
            
            return $pdf->stream();
    }
    
    
    public function voirDocument($id){
        $document = Document::find($id);
        $path = storage_path('app/documents/' . $document->nom_fichier);
        
        if (!File::exists($path)) {
            abort(404);
        }
        //$file = File::get($path);
        $type = File::mimeType($path);
        $nom_fichier = 'documents/'. $document->nom_fichier;
        
        
        return Storage::download($nom_fichier, $document->libelle, [
          'Content-Type' => $type,
          'Content-Disposition' => 'inline; filename="'.$document->libelle.'"'
        ]);
        
        //dd($document);
    }
    
    private function addSignatureToMessage($output,$libelle='signature'){
        $document = Document::create([
            "libelle" => $libelle,//'message_' . $message->id,
            "nom_fichier" => 'tmp_signature.png',//$fichier->getClientOriginalName(),
            "url" => '',
            "type_mime" => 'png'
        ]);
        $new_name = $document->id.'.png';
        $document->update(['nom_fichier' => $new_name]);
        
        require_once public_path().'/signature-to-image-master/signature-to-image.php';
        
        $json = $output; // From Signature Pad
        $img = sigJsonToImage($json,['imageSize' => [298, 155]]);
        
        $path = imagepng($img, storage_path().'/app/documents/'.$new_name);
        
        
        //$path = basename($img->store('documents'));
        imagedestroy($img);
        return $document;
        
    }
    
    /* public function payer(Request $request){
        //DB::enableQueryLog();
        $demande = $this->demandeRepository->getById($request->demande_id);
        Session::put('demande_id',$demande->id);
                
        if ($request->bpadevis!='on' || $request->cgv!='on' )
            return redirect(route('demandes.show',$demande->id))->withErrors(["cocher"=>"Vous devez accepter le Bon pour accord et les CGV pour pouvoir continuer"]);
            
            if ($demande->statuts->last()->id == 'DEVISEE'){
                //dd(DB::getQueryLog(),$id,$request->all());
                
                $demande->statuts()->attach(['statut_id'=>'EN_PAIEMENT']);
                
                $message = $demande->messages()->create(['user_id'=>Auth::id(),'text' => "J'accepte sans réserve le devis qui m'est proposé"]);
                //Ajout de la signature manuscrite si elle exsite
                if ($request->output){
                    $message->documents()->attach($this->addSignatureToMessage($request->output,'signature_devis'));
                }
                
                
                return
                //redirect(route('demandes.show',$demande->id));//
                redirect(route('choixpaiement',$demande->id));
            }
            else if ($demande->statuts->last()->id == 'EN_PAIEMENT'){
                //Exécuter le paiement
                //transwaction vers CB
                return  //redirect(route('demandes.show',$demande->id));
                redirect(route('choixpaiement'));
            }
            else if ($demande->statuts->last()->id == 'LIVREE')
                //dd(DB::getQueryLog(),$id,$request->all());
                return  //redirect(route('demandes.show',$demande->id));
                redirect(route('choixpaiement'));
            else
                return redirect(route('demandes.show',$demande->id))->withErrors(["statut_demande"=>"statut non valide"]);
    } */
    
    public function receptionner(Request $request){
        if ($request->checkPV!='on')
            return redirect(route('demandes.show',$demande->id))->with("message","Merci de valider le procès verbal de réception.");
        $demande =$this->demandeRepository->getById($request->demande_id);
        if ($demande->isPaid()){
            $demande->statuts()->attach(['statut_id'=>'LIVREE']);
            $demande->intervention->update(['scoring' => $request->scoring]);
            //on crée un message automatique pour le client
            $message = $demande->messages()->create(['user_id'=>Auth::id(),
                'text' => "Je valide la réception définitive des travaux."
            ]);
            if ($request->output){
                $message->documents()->attach($this->addSignatureToMessage($request->output,'signature_reception'));
            }
            return redirect(route('demandes.show',$demande->id))->with("message","PV réception validé. Merci de régler le solde");
        }
        else
            return redirect(route('demandes.show',$demande->id))->withErrors(["statut_demande"=>"statut non valide"]);
    }
    
            
    
    /*
    public function validerBpa($id){
        $demande =$this->demandeRepository->getById($id);
        if ($demande->statuts->last()->id == 'BPA'){
            $demande->statuts()->attach(['statut_id'=>'BPA_OK']);
            return redirect(route('demandes.show',$demande->id))->with("message","Bon pour accord validé.");
        }
        else 
            return redirect(route('demandes.show',$demande->id))->withErrors(["statut_demande"=>"statut non valide"]);
    }
    */
        
}
