<?php

namespace App\Http\Controllers;

use App\Mail\SendFactureMail;
use App\Models\Devis;
use App\Models\DevisStatus;
use App\Models\Document;
use App\Models\Dossier;
use App\Models\Facture;
use App\Models\Montant;
use App\Models\Notification;
use App\Models\Observation;
use App\Models\Step;
use App\Models\TypeDocument;
use App\Models\TypeFacture;
use Image;
use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Client\Request as ClientRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;

class FactureController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index($id)
    {

        $this->authorize('viewAny', Facture::class);
        $devis = Devis::where('dossier_id', $id)->where(function ($query) {
            $query->where('devis_status_id', 2)
                ->orWhere('devis_status_id', 7);
        })->count();
        if ($devis == 0) {
            return redirect()->back()->with('error', 'Besoin ou Attente Accord de Devis');
        }
        $factures = Facture::where('dossier_id', $id)->with('status', 'dossier', 'typefacture')->latest()->get();

        return view('facture.index', compact('factures', 'id'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create($id)
    {
        $this->authorize('create', Devis::class);

        $dossier = Dossier::whereId($id)->with('devis')->firstOrFail();
        // $count = Facture::where('dossier_id', $id)->count();
        // if ($count > 0) {
        //     return redirect()->route('Facture.show', $dossier->id)->with('error', 'Facture  ');
        // }
        if ($dossier->update != 0 && Auth::user()->role_id != 4 || $dossier->dossier_status_id == 3 && Auth::user()->role_id != 4) {
            return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Dossier est interdit de le modifier Envoyer une demande a Admin ');
        }
        $devis = Devis::where('dossier_id', $id)->where(function ($query) {
            $query->where('devis_status_id', 2)
                ->orWhere('devis_status_id', 7);
        })->count();
        if ($devis == 0) {
            return redirect()->back()->with('error', 'Besoin ou Attente Accord de Devis');
        }


        // $types = TypeFacture::all();

        // if($dossier->devis){
        //     return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Merci de Traiter Un devis Avant La facture');
        // }
        // $step = DB::table('step_dossier')
        //     ->where('dossier_id', $dossier->id)
        //     ->latest()->first();
        // if (Auth::user()->id != $step->user_id) {
        //     return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Vous avez pas le droit de apporter des modification a ce dossier maintenant');
        // }
        return view('facture.create', compact('dossier'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->authorize('create', Facture::class);
        try {

            $validator = Validator::make(
                $request->all(),
                [
                    'files' => 'nullable|array|required_without:filesmo',
                    'files.*' => 'mimes:jpg,jpeg,png,pdf',
                    'filesmo' => 'nullable|array|required_without:files',
                    'filesmo.*' => 'mimes:jpg,jpeg,png,pdf',
                    // 'type_facture_id' => 'required|exists:type_factures,id',
                    'montant_facture' => 'required|numeric',
                    'date' => 'required|date',
                ],
                [
                    'files.*.mimes' => 'Seuls les fichiers au format jpg, jpeg, png, pdf sont acceptés.',
                    'filesmo.*.mimes' => 'Seuls les fichiers au format jpg, jpeg, png, pdf sont acceptés.',
                    'files.required_without' => 'Le champ facture piece est obligatoire lorsque le champ facture MO est vide.',
                    'filesmo.required_without' => 'Le champ facture MO est obligatoire lorsque le champ facture piece est vide.',
                    'montant_facture.required' => 'Le montant de la facture est obligatoire.',
                    'montant_facture.numeric' => 'Le montant de la facture doit être un nombre.',
                    'date.required' => 'La date est obligatoire.',
                    'date.date' => 'La date doit être une date valide.',
                ]
            );

            if ($validator->fails()) {
                return redirect()->back()->withErrors($validator)->withInput();
            }

            $dossier = Dossier::whereId($request->dossier_id)->firstOrFail();
            if ($dossier->update != 0 && Auth::user()->role_id != 4 || $dossier->dossier_status_id == 3 && Auth::user()->role_id != 4) {
                return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Dossier est interdit de le modifier Envoyer une demande a Admin ');
            }
            // $devis = Devis::where('dossier_id', $dossier->id)->where(function ($query) {
            //     $query->where('devis_status_id', 2)->Orwhere('devis_status_id', 7);
            // })->count();


            // if ($devis == 0) {
            //     return redirect()->back()->with('error', 'Besoin ou Attente Accord de Devis');
            // }
            $facture = Facture::where('dossier_id', $dossier->id)->count();
            if ($facture > 0) {
                $oldfacture = Facture::where('dossier_id', $dossier->id)
                    ->latest()
                    ->first();
                if ($oldfacture && $oldfacture->devis_status_id == 4) {
                    return redirect()->back()->with('error', 'Vous ne pouvez pas créer une facture quand une facture est en cours. Veuillez traiter la facture existante.');
                }
            }
            $doc = Document::where('dossier_id', $dossier->id)->where('type_document_id', 6)->count();
            // upload files normal
            if ($doc == 0) {
                $status = DevisStatus::whereId(9)->first();
            } else {
                $status = DevisStatus::whereId(4)->first();
            }
            $facturecount = Facture::where('dossier_id', $request->dossier_id)->count();
            $c = $facturecount + 1;
            $facture = Facture::create([
                'montant_facture' => $request->montant_facture,
                'dossier_id' => $request->dossier_id,
                'devis_status_id' => $status->id,
                'date_reception' => $request->date,
                'facture' => $c,
                'type_facture_id' => 5
            ]);
            $type = TypeDocument::whereId(8)->firstOrFail();
            $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);

            if ($request->file('files')) {
                $files = $request->file('files');
                foreach ($files as $file) {
                    if ($file->getMimeType() != 'application/pdf') {
                        $filename = uniqid() . '.' . File::extension($file->getClientOriginalName());
                        $path3 = $file->storeAs('documents/' . $dossier->ref . '/' . $type->type, $filename, 's3');
                        // Store the file in the disk
                        $doc = Document::create([
                            'path' => $path3,
                            'type_document_id' => $type->id,
                            'dossier_id' => $dossier->id,
                            'facture_mo' => 0
                        ]);

                        $facture->document()->attach($doc->id);
                    }
                }
                //convert pdf to image and store the images
                if (isset($request->pdfs)) {
                    $array = explode(",", $request->pdfs);
                    for ($i = 1; $i < count($array); $i += 2) {
                        $image = base64_decode($array[$i]);
                        $filename = uniqid() . '.' . 'png';
                        Storage::disk('s3')->put('documents/' . $dossier->ref . '/' . $type->type . '/' . $filename, $image);
                        $path = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;
                        $do = Document::create([
                            'path' => $path,
                            'dossier_id' => $dossier->id,
                            'type_document_id' => $type->id,
                            'facture_mo' => 0

                        ]);
                        $facture->document()->attach($do->id);
                    }
                }
            }

            if ($request->file('filesmo')) {
                $filesmo = $request->file('filesmo');
                foreach ($filesmo as $file) {
                    if ($file->getMimeType() != 'application/pdf') {
                        $filename = uniqid() . '.' . File::extension($file->getClientOriginalName());
                        $path3 = $file->storeAs('documents/' . $dossier->ref . '/' . $type->type, $filename, 's3');
                        // Store the file in the disk
                        $doc = Document::create([
                            'path' => $path3,
                            'type_document_id' => $type->id,
                            'dossier_id' => $dossier->id,
                            'facture_mo' => 1

                        ]);

                        $facture->document()->attach($doc->id);
                    }
                }
                //convert pdf to image and store the images
                if (isset($request->mopdfs)) {
                    $array = explode(",", $request->mopdfs);
                    for ($i = 1; $i < count($array); $i += 2) {
                        $image = base64_decode($array[$i]);
                        $filename = uniqid() . '.' . 'png';
                        Storage::disk('s3')->put('documents/' . $dossier->ref . '/' . $type->type . '/' . $filename, $image);
                        $path = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;
                        $do = Document::create([
                            'path' => $path,
                            'dossier_id' => $dossier->id,
                            'type_document_id' => $type->id,
                            'facture_mo' => 1

                        ]);
                        $facture->document()->attach($do->id);
                    }
                }
            }

            Montant::updateOrCreate(
                ['dossier_id' => $request->dossier_id],
                [
                    'facture_id' => $facture->id,
                ]
            );

            $step = Step::whereId(8)->first();
            $dossier = Dossier::whereId($facture->dossier_id)->first();
            $dossier->step()->attach($step, ['user_id' => Auth::user()->id]);


            $step2 = Step::whereId(9)->first();
            $dossier->step_id = $step2->id;
            $dossier->update();
            $dossier->step()->attach($step2, ['user_id' => Auth::user()->id]);

            // $status = DevisStatus::whereId(4)->first();
            // $facture->facturestatus()->attach($status, ['user_id' => $id->user_id]);
            $user = User::where('role_id', 2)->withCount('step')
                ->whereHas('typecompany', function ($query) use ($dossier) {
                    $query->where('company_id', $dossier->company_id)->where('type_expertise_id', $dossier->type_expertise_id);
                })
                ->whereHas('seuil', function ($query) use ($request) {
                    $query->where('max', '>=', $request->montant_facture)->where('min', '<=', $request->montant_facture);
                })->orderBy('step_count', 'asc')
                ->first();
            if (!$user) {
                $user = User::where('role_id', 4)->first();
            }

            if (Auth::check()) {
                $body = "Une Nouveau Facture est Créer" . $dossier->ref . " et Affecter :" . $user->name;
            } else {
                $body = "Une Nouveau Facture est Créer par Visiteur et Affecter :" . $dossier->ref;
            }
            Notification::create([
                'user_id' => Auth::user()->id,
                'dossier_id' => $dossier->id,
                'body' => $body
            ]);

            \App\Services\SidebarCache::clear();
            return redirect()->route('home')->with('success', 'Facture créer avec Succés.');
        } catch (\Exception $e) {

            return redirect()->route('home')->with('error', 'An error occurred');
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Facture  $facture
     * @return \Illuminate\Http\Response
     */
    public function show($id, Request $request)
    {
        $this->authorize('view', Facture::class);

        $facture = Facture::whereId($id)->with('status', 'facturestatus', 'dossier', 'montant')->firstOrFail();
        $dossier = Dossier::whereId($facture->dossier_id)->with('document', 'document.typedocument', 'devis')
            ->with('document', function ($query) {
                $query->whereHas('typedocument', function ($query) {
                    $query->where('is_pdf', 0);
                });
            })->firstOrFail();
        $montant = Montant::where('dossier_id', $facture->dossier_id)->first();
        $typedocuments = TypeDocument::where('is_pdf', '0')->whereHas('document', function ($query) use ($dossier) {
            $query->where('dossier_id', $dossier->id);
        })->get();
        if (!$montant) {
            Montant::updateOrCreate(['dossier_id' => $dossier->id], [
                'facture_id' => $facture->id,
            ]);
        } else {
            if ($montant->facture_id == null) {
                Montant::updateOrCreate(['dossier_id' => $dossier->id], [
                    'facture_id' => $facture->id,
                ]);
            }
        }

        if ($request->doc_id) {
            $document = Document::whereId($request->doc_id)->where('dossier_id', $dossier->id)->whereIn('type_document_id', [8, 30])->first();
        } else {
            $document = Document::where('dossier_id', $dossier->id)->where('type_document_id', 8)->latest()->first();
        }


        $devises = Devis::where('dossier_id', $dossier->id)->where(function ($query) {
            $query->where('devis_status_id', 2)
                ->orWhere('devis_status_id', 7);
        })->with('document')->get();
        $docfacture = Document::where('dossier_id', $facture->dossier_id)->where(function ($query) {
            $query->where('type_document_id', 8);
        })->with('facture')->get();
        $observations = Observation::where('dossier_id', $facture->dossier_id)->get();

        return view('facture.show', compact('facture', 'observations', 'typedocuments', 'montant', 'document', 'docfacture', 'dossier', 'devises'));
    }

    public function status(Request $request, $id)
    {
        $this->authorize('update', Facture::class);

        $facture = Facture::whereId($id)->with('document')->first();
        $dossier = Dossier::whereId($facture->dossier_id)->with('montant')->firstOrFail();
        if ($dossier->update != 0 && Auth::user()->role_id != 4 || $dossier->dossier_status_id == 3 && Auth::user()->role_id != 4) {
            return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Dossier est interdit de le modifier Envoyer une demande a Admin ');
        }

        if ($request->input('action') == "accord") {

            $facture->devis_status_id = 2;
            $facture->update();
            $now = now();
            $text = $dossier->ref . " : Facture Accord par " . Auth::user()->name . " le " . $now;

            $count = 0;
            foreach ($facture->document as $d) {
                if ($d->edited == 1) {
                    $count++;
                }
            }
            $status = DevisStatus::whereId(2)->first();
            $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
            // foreach ($facture->document as $doc) {
            //     $doc->type_document_id = 30;
            //     $doc->update();
            // }
            $step = Step::whereId(10)->first();
            $dossier->step()->attach($step, ['user_id' => Auth::user()->id]);
            $step = Step::whereId(11)->first();
            $stepuser = DB::table('step_dossier')
                ->where('dossier_id', $dossier->id)
                ->where('step_id', 1)
                ->first();
            $dossier->step_id = $step->id;
            $dossier->update();
            $dossier->step()->attach($step, ['user_id' => $stepuser->user_id]);
            $body = "Accord Facture :" . $facture->dossier->ref;
            Notification::create([
                'user_id' => Auth::user()->id,
                'dossier_id' => $facture->dossier->id,
                'body' => $body
            ]);

            foreach ($facture->document as $doc) {
                if ($count == 0) {
                    $imageContent = Storage::disk('s3')->get($doc->path);
                    $img = Image::make($imageContent);
                    $watermarkWidth = $img->width() * 15 / 100;
                    $watermarkHeight = $img->height() * 15 / 100;
                    $watermark = Image::make(public_path('/img/amea2.png'))->resize($watermarkHeight, $watermarkWidth)->opacity(70);
                    $watermark2 = Image::make(public_path('/img/sign.png'))->resize($watermarkHeight, $watermarkWidth)->opacity(70);

                    $img->insert($watermark, 'top-left', 15, 15);
                    $img->insert($watermark2, 'bottom-right', 10, 10);

                    $img->text($text, 80, 30, function ($font) {
                        $font->file(public_path('fonts/gnuolane.ttf'));
                        $font->size(18);
                        $font->color('#000000');
                        $font->align('bottom');
                        $font->valign('right');
                        $font->angle(0);
                    });
                    $type = TypeDocument::whereId(30)->first();
                    $filename = uniqid() . '.' . 'png';
                    Storage::disk('s3')->put('documents/' . $dossier->ref . '/' . $type->type . '/' . $filename, $img->stream());
                    $path3 = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;
                    // Store the file in the disk
                    $docu = Document::create([
                        'path' => $path3,
                        'type_document_id' => $type->id,
                        'dossier_id' => $dossier->id,
                    ]);
                    $facture->document()->attach($docu->id);
                } else {
                    if ($doc->edited == 1) {
                        $imageContent = Storage::disk('s3')->get($doc->path);
                        $img = Image::make($imageContent);
                        $watermarkWidth = $img->width() * 15 / 100;
                        $watermarkHeight = $img->height() * 15 / 100;
                        $watermark = Image::make(public_path('/img/amea2.png'))->resize($watermarkHeight, $watermarkWidth)->opacity(70);
                        $watermark2 = Image::make(public_path('/img/sign.png'))->resize($watermarkHeight, $watermarkWidth)->opacity(70);

                        $img->insert($watermark, 'top-left', 15, 15);
                        $img->insert($watermark2, 'bottom-right', 10, 10);

                        $img->text($text, 80, 30, function ($font) {
                            $font->file(public_path('fonts/gnuolane.ttf'));
                            $font->size(18);
                            $font->color('#000000');
                            $font->align('bottom');
                            $font->valign('right');
                            $font->angle(0);
                        });
                        $type = TypeDocument::whereId(30)->first();
                        $filename = uniqid() . '.' . 'png';
                        Storage::disk('s3')->put('documents/' . $dossier->ref . '/' . $type->type . '/' . $filename, $img->stream());
                        $path3 = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;
                        // Store the file in the disk
                        $docu = Document::create([
                            'path' => $path3,
                            'type_document_id' => $type->id,
                            'dossier_id' => $dossier->id,
                        ]);
                        $facture->document()->attach($docu->id);
                    }
                }
            }
            \App\Services\SidebarCache::clear();
            return redirect()->route('home')->with('success', 'Facture Accord');
        } else
            if ($request->input('action') == "rejeter") {
                $request->validate([
                    'observation' => 'required',
                ]);
                Observation::create([
                    'observation' => $request->observation,
                    'dossier_id' => $facture->dossier_id,
                    'user_id' => Auth::user()->id
                ]);
                $facture->devis_status_id = 1;
                $facture->update();
                $status = DevisStatus::whereId(1)->first();
                $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
                $body = " Facture Rejeter :" . $facture->dossier->ref;
                Notification::create([
                    'user_id' => Auth::user()->id,
                    'dossier_id' => $facture->dossier->id,
                    'body' => $body
                ]);
                \App\Services\SidebarCache::clear();
                return redirect()->route('home')->with('success', 'Facture est Rejeter');
            } else
                if ($request->input('action') == "avis") {

                    $facture->devis_status_id = 3;
                    $facture->update();
                    $status = DevisStatus::whereId(3)->first();
                    $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
                    $body = "Demande Avis sur Facture :" . $facture->dossier->ref;
                    Notification::create([
                        'user_id' => Auth::user()->id,
                        'dossier_id' => $facture->dossier->id,
                        'body' => $body
                    ]);
                    \App\Services\SidebarCache::clear();
                    return redirect()->route('home')->with('success', 'Facture Avis');
                }
        if ($request->input('action') == "retraiter") {
            $facture->devis_status_id = 5;
            $facture->update();
            foreach ($facture->document as $doc) {
                $doc->edited = 0;
                $doc->update();
            }
            $status = DevisStatus::whereId(5)->first();
            $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
            $body = "Retraiter Facture :" . $facture->dossier->ref;
            Notification::create([
                'user_id' => Auth::user()->id,
                'dossier_id' => $facture->dossier->id,
                'body' => $body
            ]);
            \App\Services\SidebarCache::clear();
            return redirect()->route('home')->with('success', 'Facture a Retraiter');
        }
        // if ($request->input('action') == 'envoyer') {
        //     if ($facture->devis_status_id == 2) {

        //         $facture->devis_status_id = 7;
        //         $facture->update();
        //         $status = DevisStatus::whereId(7)->first();
        //         $facture->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
        //         $body = "Facture Envoyer :" . $facture->dossier->ref;
        //         Notification::create([
        //             'user_id' => Auth::user()->id,
        //             'dossier_id' => $facture->dossier->id,
        //             'body' => $body
        //         ]);
        //         return redirect()->route('Dossier.show', $dossier->id)->with('success', 'Facture est Envoyer');
        //     }
        //     return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Facture besoin accord avant envoi');
        // }

        return redirect()->back();
    }
    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Facture  $facture
     * @return \Illuminate\Http\Response
     */
    public function edit(Facture $facture)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Facture  $facture
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Facture $facture)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Facture  $facture
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if (Auth::user()->role_id == 4) {
            $facture = Facture::whereId($id)->firstOrFail();
            if ($facture->devis_status_id == 4 || $facture->devis_status_id == 9) {
                $docfac = DB::table('document_facture')->where('facture_id', $facture->id)->get();
                DB::table('facture_status')->where('facture_id', $facture->id)->delete();
                DB::table('document_facture')->where('facture_id', $facture->id)->delete();
                foreach ($docfac as $d) {
                    $doc = Document::whereId($d->document_id)->first();
                    $doc->delete();
                }
                $montant = Montant::where('dossier_id', $facture->dossier_id)->first();
                $montant->facture_id = null;
                $montant->update();
                $facture->delete();
                \App\Services\SidebarCache::clear();
                return redirect()->back()->with('success', 'Facture Supprimer Avec Succés');
            } else {
                return redirect()->back()->with('error', 'Facture est deja en traitement');
            }
        }
    }
}
