<?php

namespace App\Http\Controllers\api;

use App\Http\Controllers\Controller;
use App\Models\Demande;
use App\Models\Device;
use App\Models\Devis;
use App\Models\DevisStatus;
use App\Models\Document;
use App\Models\Dossier;
use App\Models\Facture;
use App\Models\Garage;
use App\Models\Meeting;
use App\Models\Notification;
use App\Models\Observation;
use App\Models\Rendezvous;
use App\Models\StatusRendezvous;
use App\Models\Step;
use App\Models\TypeDocument;
use App\Models\TypeRendezvous;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class ApiController extends Controller
{
    // api for searching dossier

    /**
     * GET Dossier For Laarbi
     * @urlParam ref string required .
     */

    public function dossier($ref)
    {
        try {
            $dossier = Dossier::where('ref', $ref)->with('insured', 'step', 'garage', 'vehiculemodel.brand', 'opponent', 'guarantee', 'company', 'status')->first();
            return response()->json($dossier);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * GET Dossier For Ysf
     * @urlParam matricule string required .
     */
    public function getdossier($matricule)
    {
        try {
            $dossiers = Dossier::where('matricule', 'like', '%' . $matricule . '%')->orWhere('new_matricule', 'like', '%' . $matricule . '%')->with('insured', 'garage', 'vehiculemodel.brand', 'opponent', 'guarantee', 'company', 'status')->get();
            $count = Dossier::where('matricule', 'like', '%' . $matricule . '%')->orWhere('new_matricule', 'like', '%' . $matricule . '%')->count();
            foreach ($dossiers as $dossier) {
                $dossier->count = $count;
            }
            return response()->json($dossiers);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     *  Dossier For Ysf
     * @urlParam id int required .
     */
    public function getDossierWithDocs($id)
    {
        try {
            // $dossier = Dossier::whereId($id)->with('insured', 'vehiculemodel.brand', 'company', 'status')->with('document', function ($query) {
            //     $query->with('typedocument')->whereHas('typedocument', function ($query) {
            //         $query->whereHas('user', function ($query) {
            //             $query->where('user_id',Auth::user()->id);
            //         });
            //     });
            // })->firstOrFail();

            $types = TypeDocument::whereHas('document', function ($query) use ($id) {
                $query->where('dossier_id', $id);
            })->with('document', function ($query) use ($id) {
                $query->where('dossier_id', $id);
            })->whereHas('user', function ($query) {
                $query->where('user_id', Auth::user()->id);
            })->get();

            foreach ($types as $type) {
                foreach ($type->document as $doc) {
                    $doc->path = Storage::disk('s3')->temporaryUrl($doc->path, now()->addMinutes(180));
                }
            }

            return response()->json($types);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function getref($id)
    {
        try {
            $meeting = Meeting::whereId($id)->with('dossier')->first();
            return response()->json([
                'ref' => $meeting->dossier->ref
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function getdocuments($id)
    {
        $documents = Document::whereHas('typedocument', function ($query) {
            $query->where('is_pdf', 0)->where('id', '!=', 9)->latest();
        })->where('dossier_id', $id)->get();
        foreach ($documents as $doc) {
            $doc->path = Storage::disk('s3')->temporaryUrl($doc->path, now()->addMinutes(30));
        }
        return response()->json($documents);
    }

    public function update($id, Request $request)
    {
        try {
            $meeting = Meeting::whereId($id)->with('dossier')->first();
            $dossier = Dossier::whereId($meeting->dossier->id)->firstOrFail();
            $validate = Validator::make(
                $request->all(),
                [
                    'numero_chassis' => 'min:17|max:17|nullable',
                    'kilometrage' => 'nullable'
                ]
            );

            if ($validate->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validate->errors()
                ], 401);
            }
            if ($dossier->dossier_status_id == 2) {
                if ($request->numero_chassis) {
                    $dossier->numero_chassis = $request->numero_chassis;
                    $dossier->update();
                }
                if ($request->kilometrage) {
                    $dossier->kilometrage = $request->kilometrage;
                    $dossier->update();
                }

                return response()->json([
                    'status' => true,
                    'message' => 'Successfully',
                ], 200);
            } else {
                return response()->json([
                    'status' => false,
                    'message' => 'dossier cloturer'
                ], 401);
            }
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }


    /**
     * Check Device Mac Address
     * @queryParam mac_address string required .
     */

    public function check(Request $request)
    {
        try {
            $validate = Validator::make(
                $request->all(),
                [
                    'mac_address' => 'required'
                ]
            );

            if ($validate->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validate->errors()
                ], 401);
            }
            $device = Device::where('mac_address', $request->mac_address)->first();
            if ($device) {
                return response()->json([
                    'status' => true,
                    'message' => 'Successfully',
                ], 200);
            } else {
                return response()->json([
                    'status' => false,
                ], 401);
            }
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function upload(Request $request, $id)
    {
        try {
            $validate = Validator::make(
                $request->all(),
                [
                    'img' => 'required'
                ]
            );

            if ($validate->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validate->errors()
                ], 401);
            }
            $meet = Meeting::whereId($id)->with('dossier')->firstOrFail();
            if ($meet->meeting_status_id != 2) {
                return response()->json([
                    'status' => false,
                    'message' => 'Meeting est deja Cloturer ou Reporter'
                ], 401);
            }
            if (Auth::user()->id != $meet->user_id) {
                return response()->json([
                    'status' => false,
                    'message' => 'Meeting Not for you'
                ], 401);
            }
            $dossier = Dossier::whereId($meet->dossier->id)->first();
            if ($meet->type == 2) {
                $type = TypeDocument::whereId(5)->first();
                // $body = "A Ajouter Photo Expertise Avant  :" . $meet->dossier->ref;
                // $devis = Devis::where('dossier_id', $dossier->id)->where('devis_status_id', 9)->get();
                // $devicount = count($devis);
                // if ($devicount > 0) {
                //     $status = DevisStatus::whereId(4)->first();
                //     foreach ($devis as $d) {
                //         $d->devis_status_id = $status->id;
                //         $d->update();
                //         $d->devisstatus()->attach($status, ['user_id' => Auth::user()->id]);
                //     }
                // }
            }
            if ($meet->type == 5) {
                $type = TypeDocument::whereId(7)->first();
                // $body = "A Ajouter Photo Expertise En Cours:" . $meet->dossier->ref;
            }
            if ($meet->type == 10) {
                $type = TypeDocument::whereId(6)->first();
                // $body = "A Ajouter Photo Expertise Aprés :" . $meet->dossier->ref;
                // $facture = Facture::where('dossier_id', $dossier->id)->where('devis_status_id', 9)->get();
                // $facturecount = count($facture);
                // if ($facturecount > 0) {
                //     $status = DevisStatus::whereId(4)->first();
                //     foreach ($facture as $f) {
                //         $f->devis_status_id = $status->id;
                //         $f->update();
                //         $f->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
                //     }
                // }
            }

            DB::beginTransaction();
            try {
                $array = explode(",", $request->img);
                foreach ($array as $key) {
                    $image = base64_decode($key);
                    $filename = uniqid() . '.' . 'png';
                    Storage::disk('s3')->put('documents/' . $dossier->ref . '/' . $type->type . '/' . $filename, $image);
                    $path = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;

                    Document::create([
                        'path' => $path,
                        'dossier_id' => $dossier->id,
                        'type_document_id' => $type->id
                    ]);
                }

                DB::commit();
            } catch (\Exception $ex) {
                DB::rollback();
                return response()->json(['error' => $ex->getMessage()], 500);
            }
            return response()->json([
                'status' => true,
                'message' => 'success'
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function cloturer($id)
    {
        $meet = Meeting::whereId($id)->with('dossier')->firstOrFail();
        $dossier = Dossier::whereId($meet->dossier->id)->first();

        if ($meet->meeting_status_id != 2) {
            return response()->json([
                'status' => false,
                'message' => 'Meeting est deja Cloturer ou Reporter'
            ], 401);
        }
        if (Auth::user()->id != $meet->user_id) {

            return response()->json([
                'status' => false,
                'message' => 'Meeting Not for you'
            ], 401);
        }

        if ($meet->type == 2) {
            $devis = Devis::where('dossier_id', $dossier->id)->where('devis_status_id', 9)->get();
            $devicount = count($devis);
            if ($devicount > 0) {
                $status = DevisStatus::whereId(4)->first();
                foreach ($devis as $d) {
                    $d->devis_status_id = $status->id;
                    $d->update();
                    $d->devisstatus()->attach($status, ['user_id' => Auth::user()->id]);
                }
            }
        }

        if ($meet->type == 10) {

            $facture = Facture::where('dossier_id', $dossier->id)->where('devis_status_id', 9)->get();
            $facturecount = count($facture);
            if ($facturecount > 0) {
                $status = DevisStatus::whereId(4)->first();
                foreach ($facture as $f) {
                    $f->devis_status_id = $status->id;
                    $f->update();
                    $f->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
                }
            }
        }

        $body = "A Ajouter Photo Expertise :" . $meet->dossier->ref;
        Notification::create([
            'user_id' => Auth::user()->id,
            'dossier_id' => $meet->dossier->id,
            'body' => $body
        ]);
        // Meeting::withoutEvents(function ($meet) { });
        $meet->meeting_status_id = 3;
        $meet->date_fin = now();
        $meet->update();

        return response()->json([
            'status' => true,
            'message' => 'success'
        ], 200);
    }
    /**
     * Laarbi All Garages
     */

    public function garages()
    {
        try {
            $garages = Garage::whereNotNull('url')->with('garageservice')->get();
            return response()->json($garages);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Get Meetings of user
     */

    public function meeting()
    {
        try {
            $meetings = Meeting::where('user_id', Auth::user()->id)->where('meeting_status_id', 2)->with('dossier', 'dossier.insured', 'dossier.company', 'dossier.typeexpertise', 'meetingstatus', 'dossier.opponent', 'garage')->latest()->get();
            return response()->json($meetings);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * show meeting
     * @urlParam id int required .
     */

    public function showmeeting($id)
    {
        try {
            $meetings = Meeting::whereId($id)->with('dossier', 'dossier.insured', 'dossier.company', 'dossier.typeexpertise', 'meetingstatus', 'dossier.opponent', 'garage', 'dossier.vehiculemodel.brand', 'dossier.observation')->firstOrFail();
            return response()->json($meetings);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function getstatus($id)
    {
        try {
            $meetings = Meeting::whereId($id)->with('meetingstatus')->firstOrFail();
            return response()->json($meetings->meetingstatus->status);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    public function updatetoken(Request $request)
    {
        try {
            $user = User::whereId(Auth::user()->id)->first();
            $user->device_key = $request->key;
            $user->update();
            return response()->json([
                'status' => true,
                'message' => 'Successfully',
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    //agent observation
    /**
     * create Observation
     * @queryParam observation string required .
     * @queryParam  type_observation_id int required
     * @queryParam dossier_id int required
     */
    public function observation(Request $request)
    {
        try {
            $validateobsv = Validator::make(
                $request->all(),
                [
                    'observation' => 'required',
                    'dossier_id' => 'required',
                ]
            );

            if ($validateobsv->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateobsv->errors()
                ], 401);
            }
            $dossier = Dossier::whereId($request->dossier_id)->first();

            Observation::create([
                'observation' => $request->observation,
                'user_id' => Auth::user()->id,
                'dossier_id' =>  $dossier->id,
            ]);
            $body = "Agent " . Auth::user()->name . " a Créer une Observation Meeting " . $dossier->ref;
            Notification::create([
                'user_id' =>  Auth::user()->id,
                'dossier_id' => $dossier->id,
                'body' => $body
            ]);

            return response()->json([
                'status' => true,
                'message' => 'Successfully',
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }


    // public function api(Request $request)
    // {
    //     $image = base64_decode(request('image'));
    //     return $image;
    // }
    /**
     * create Demande de Meet
     * @queryParam motif string required .
     * @queryParam dossier_id int required
     * @queryParam user_id int required
     *
     */
    public function Demande(Request $request)
    {
        try {
            $validateobsv = Validator::make(
                $request->all(),
                [
                    'motif' => 'required',
                    'dossier_id' => 'required',
                ]
            );

            if ($validateobsv->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateobsv->errors()
                ], 401);
            }
            $dossier = Dossier::whereId($request->dossier_id)->firstOrFail();
            if ($dossier->dossier_status_id != 2) {
                return response()->json([
                    'status' => false,
                    'message' => '',
                ], 401);
            }

            $motif = "Merci de me Assigner Un Meeting Motif: " . $request->motif;
            Notification::create([
                'dossier_id' => $request->dossier_id,
                'user_id' => Auth::user()->id,
                'body' => $motif
            ]);

            return response()->json([
                'status' => true,
                'message' => 'Successfully',
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * show Dossier
     * @urlParam id int required .
     */
    public function showdossier($id)
    {
        try {
            $dossier = Dossier::whereId($id)->with('insured', 'garage', 'vehiculemodel.brand', 'opponent', 'guarantee', 'company', 'status', 'observation', 'status', 'mode',   'opponent.vehiculemodel.brand')->firstOrFail();
            return response()->json($dossier);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Update Meeting Status
     * @queryParam status_id int required
     * @urlParam meeting_id int required
     */
    public function status($meeting_id, Request $request)
    {

        try {
            $meeting = Meeting::findOrFail($meeting_id);
            $dossier = Dossier::whereId($meeting->dossier_id)->first();

            if ($request->status_id != 3) {
                return response()->json([
                    'status' => false,
                ], 401);
            }
            if ($meeting->user_id != Auth::user()->id) {
                return response()->json([
                    'status' => false,
                ], 401);
            }
            if ($meeting->meeting_status_id == 2) {
                $meeting->meeting_status_id = $request->status_id;
                $meeting->update();
                if ($meeting->type == 2) {
                    $type = TypeDocument::whereId(5)->first();
                    $body = "A Ajouter Photo Expertise Avant  :" . $meeting->dossier->ref;
                    $devis = Devis::where('dossier_id', $dossier->id)->where('devis_status_id', 9)->get();
                    $devicount = count($devis);
                    if ($devicount > 0) {
                        $status = DevisStatus::whereId(4)->first();
                        foreach ($devis as $d) {
                            $d->devis_status_id = $status->id;
                            $d->update();
                            $d->devisstatus()->attach($status, ['user_id' => Auth::user()->id]);
                        }
                    }
                }

                if ($meeting->type == 10) {
                    $type = TypeDocument::whereId(6)->first();
                    $body = "A Ajouter Photo Expertise Aprés :" . $meeting->dossier->ref;
                    $facture = Facture::where('dossier_id', $meeting->dossier->id)->where('devis_status_id', 9)->get();
                    $facturecount = count($facture);
                    if ($facturecount > 0) {
                        $status = DevisStatus::whereId(4)->first();
                        foreach ($facture as $f) {
                            $f->devis_status_id = $status->id;
                            $f->update();
                            $f->facturestatus()->attach($status, ['user_id' => Auth::user()->id]);
                        }
                    }
                }

                $dossier = Dossier::whereId($meeting->dossier_id)->first();
                $step = Step::whereId(3)->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]);

                return response()->json([
                    'status' => true
                ]);
            } else {
                return response()->json([
                    'status' => false,
                ], 401);
            }
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Get Docs Type
     */
    public function typedocument()
    {
        try {
            $typedocuments  = TypeDocument::all();
            return response()->json($typedocuments);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
    /**
     * Update Meeting Status
     * @queryParam file int required
     * @queryParam dossier_id int required
     * @queryParam type_document_id int required
     */
    public function document(Request $request)
    {
        try {
            $meeting = Meeting::whereId($request->meeting_id)->firstOrFail();
            $dossier = Dossier::whereId($meeting->dossier_id)->firstOrFail();
            // if ($request->img) {
            //     DB::transaction(function ($request , $dossier) {


            //         $array = explode(",", $request->img);
            //         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;
            //             Document::create([
            //                 'path' => $path,
            //                 'dossier_id' => $dossier->id,
            //                 'type_document_id' => $type->id
            //             ]);
            //         }
            //     });
            // }
            $body = "a Ajouter des nouveaux Document au dossier Ref :";
            Notification::create([
                'user_id' => Auth::user()->id,
                'dossier_id' => $dossier->id,
                'body' => $body
            ]);

            if ($meeting->type == 2) {
                // $step2 = DB::table('step_dossier')
                //     ->where('dossier_id', $dossier->id)
                //     ->where('step_id', 4)
                //     ->latest()->first();
                $step = Step::whereId(3)->first();
                $dossier->step()->attach($step, ['user_id' => Auth::user()->id]);
                $meeting->meeting_status_id = 3;
                $meeting->update();
            }
            return response()->json();
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }


    /**
     * Update Meeting Status
     * @queryParam matricule string required
     */

    public function search(Request $request)
    {
        try {
            $meetings =  Meeting::where('user_id', Auth::user()->id)->whereHas('dossier', function ($query) use ($request) {
                $query->where('matricule', $request->matricule)->orWhere('new_matricule', $request->matricule);
            })->with('dossier', 'dossier.insured', 'dossier.observation', 'dossier.observation.user', 'dossier.opponent', 'dossier.company')->latest()->get();

            return response()->json($meetings);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Create RDV
     * @queryParam ref  required
     * @queryParam type_rendezvous_id  required
     * @queryParam motif string required
     *
     */
    public function store(Request $request)
    {
        try {

            $validate = Validator::make(
                $request->all(),
                [
                    'ref' => 'required|exists:dossiers,ref',
                    'type_rendezvous_id' => 'required|exists:type_rendezvouses,id',
                    'motif' => 'required'
                ]
            );

            if ($validate->fails()) {
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validate->errors()
                ], 401);
            }
            $dossier = Dossier::where('ref', $request->ref)->first();
            $type = TypeRendezvous::whereId($request->type_rendezvous_id)->firstOrFail();

            if ($type->for_direction) {
                $getuser = User::where('role_id', 4)->first();
                $user = $getuser->id;
                $body = "Un Rendez Vous est Créer :" . $dossier->ref;
                Notification::create([
                    'user_id' =>  $user,
                    'dossier_id' => $dossier->id,
                    'body' => $body
                ]);
            } else {
                $step = DB::table('step_dossier')
                    ->select('user_id')
                    ->where('step_dossier.step_id', 1)
                    ->where('step_dossier.dossier_id', $dossier->id)
                    ->get();

                $user = $step[0]->user_id;

                $body = "Un Rendez Vous est Créer :" . $dossier->ref;
                Notification::create([
                    'user_id' =>  $user,
                    'dossier_id' => $dossier->id,
                    'body' => $body
                ]);
            }
            Rendezvous::create([
                'ref' => $request->ref,
                'motif' => $request->motif,
                'type_rendezvous_id' => $request->type_rendezvous_id,
                'status_rendezvous_id' => 1,
                'user_id' => $user
            ]);
            return response()->json([
                'status' => true,
                'message' => "Success"
            ], 500);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * GET RDV Type
     */

    public function typerendezvous()
    {
        try {
            $types = TypeRendezvous::all();
            return response()->json($types);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
    /**
     * Laarbi GET status RDV
     */

    public function statusrendezvous()
    {
        try {
            $status = StatusRendezvous::all();
            return response()->json($status);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
}
