<?php

namespace App\Http\Controllers;

use App\Eventlog;
use App\Events\CreateSubtask;
use App\Events\SubtaskStatusChange;
use App\Http\Requests\StoreSubtask;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Subtask;
use App\Status;
use App\Notifications;
use App\Attachment;
use App\Task;
use App\Tasktag;
use Illuminate\Support\Facades\DB;
use ZipArchive;
use Laravelista\Comments\Comments\Comment;
use Laravelista\Comments\Events\CommentWasPosted;
use Laravelista\Comments\Events\CommentWasUpdated;
use Laravelista\Comments\Events\CommentWasDeleted;



class SubtasksController extends Controller
{
    public function index()
    {


    }


    /**
     * pre:busca notificaciones por id de subtarea,
     * post:cambia el estado (a leido) la notificacion de subtarea encontrada
     * @param $subtaskId
     */
    public function notificationsRead($subtaskId)
    {

        $notificaciones = Notifications::select('notifications.*')->join('eventlogs as  e', 'e.id', '=', 'notifications.eventlogs_id')
            ->where('notifications.user_to',Auth::user()->id)
            ->where('e.relation_id',$subtaskId)
            ->where('is_read',0)
            ->whereIn('notifications.type',['Subtask','SubtaskStatusChange','App\Subtask','AttachSubtask'])->get();


        $tasktags = Tasktag::select('id')->where('type','subtask')->where('relation_id',$subtaskId)->get();

        $tasktag_ids = array();
        foreach ($tasktags as $tasktag){

            array_push($tasktag_ids,$tasktag->id);

        }

        $notifTags = Notifications::select('notifications.*')->join('eventlogs as  e', 'e.id', '=', 'notifications.eventlogs_id')
            ->where('notifications.user_to',Auth::user()->id)
            ->where('is_read',0)
            ->whereIn('e.relation_id',$tasktag_ids)
            ->whereIn('e.type',['tasktag','untasktag'])->get();
//            ->whereIn('notifications.type',['tasktag','untasktag','InfoTaskTag','infoUntag'])->get();


        if(count($notificaciones) >0){

            foreach ($notificaciones as  $n){

                $n->is_read =1;
                $n->save();
            }
        }

        if(count($notifTags) >0){

            foreach ($notifTags as  $n) {

//                if ($n->eventlog->tasktag->type == 'subtask') {

                    $n->is_read = 1;
                    $n->save();
//                }
            }
        }

    }


    /**
     * @return bool|int
     */
    public function verifyTypeUser(){

           // TeamMember

           $TypeUser = (count(DB::table('user_has_roles')
            ->where('user_has_roles.user_id', '=', Auth::user()->id)
            ->where('user_has_roles.role_id', '=', "3")->get())>0?1:false);  


            if($TypeUser)  
                return $TypeUser;

           // TeamLeader, Supervisor o Administrador.

           $TypeUser = (count(DB::table('user_has_roles')
            ->where('user_has_roles.user_id', '=', Auth::user()->id)
            ->whereIn('user_has_roles.role_id', [1, 2, 4])->get())>0?2:false); 

           return $TypeUser;

    }



    public function addsubtaskAttach(Request $request){


        $added = 0;

        foreach ($request['attachtask'] as $key => $value) {

                DB::table('attach_subtask')->where('subtask_id', '=',$request['subtask'])
                                        ->where('attachment_id', '=',$value)->delete();
            
            $query = DB::table('attach_subtask')->insert(
                ['subtask_id' => $request['subtask'], 'attachment_id' => $value]
            );

        if($query)
            $added++;

        if(count($request['attachtask'])==$added)
            echo json_encode(array("status"=>"ok"));

        }

    }



    public function deleteAttachsubtask(Request $request){



            //  Inserto el comentario

            $comment                = new Comment();
            $comment->user_id       = Auth::user()->id;
            $comment->content_type  = 'App\\Subtask';
            $comment->content_id    = $request->task_id;
            $comment->unit_id       = $request->unit_id;
            $message                = ($request->activate=="true")?" ACTIVADO ":" ELIMINADO ";
            $rc                     = !empty($request->comment)?$request->comment:" -";
            $comment->comment       = 'El archivo "'.$request->name.'" fue '.$message.' - Motivo: '.$rc; 

            $comment->save();

            event(new CommentWasPosted($comment));


            // activar 

            if($request['activate'] == "true"){


                  DB::table('attach_subtask')->where('attachment_id','=',$request['attachitem'])->update(['active' => 1]);

                  DB::table('attach_task')->where('task_id','=',$request['task'])->where('attachment_id','=',$request['attachitem'])->update(['active' => 1]);

                  $delivered = 2;

                  if(DB::table('attach_task')->where('attachment_id','=',$request['attachitem'])->count() > 0){

                    // DB::table('attachments')->where('id', '=', $request['attachitem'])->update(['delivered' => 1]);

                     $delivered = 1;  // es derivado de tarea

                  }

     
                    echo json_encode(array("status"=>"ok","delivered"=>$delivered));
                    exit;       
            }

            // activar


            DB::table('attach_subtask')->where('subtask_id', '=', $request['subtask'])->where('attachment_id', '=', $request['attachitem'])->update(['active' => 0]);


            if((!empty($request['all_deleted']))&&($request['all_deleted']=="true")){

            //    DB::table('attachments')->where('id', '=', $request['attachitem'])->update(['delivered' => 0]);

             if(DB::table('attachments')->where('id','=',$request['attachitem'])->where('delivered','=',1)->count() > 0){

                //   elimina
                DB::table('attach_task')->where('task_id', '=',$request['task'])->where('attachment_id', '=',$request['attachitem'])->delete();
 
             }else{

                    DB::table('attach_task')->where('task_id', '=', $request['task'])->where('attachment_id', '=', $request['attachitem'])->update(['active' => 0]);  

             }
//  si es 1 elimina del task

                DB::table('attachments')->where('id', '=', $request['attachitem'])->update(['delivered' => 0]);

                // si es cero actualiza nomas,



            
            }        

            echo json_encode(array("status"=>"ok"));

    }




    public function deliverAttachsubtask(Request $request){



            DB::table('attachments')->where('id', '=', $request['attachitem'])->update(['delivered' => 1]);

            //  si existe updatea, si no inserta
            // este attach no existe en task , por eso se inserta updatea

            if(DB::table('attach_task')->where('attachment_id','=',$request['attachitem'])->where('task_id','=',$request['task'])->where('active','=','0')->get()->toArray()){

                 DB::table('attach_task')->where('attachment_id','=',$request['attachitem'])->where('task_id','=',$request['task'])->update(['active' => 1]);
                   echo json_encode(array("status"=>"ok"));

            }else{


                if(DB::table('attach_task')->insert(['attachment_id' => $request['attachitem'],'task_id' => $request['task']]))
                    echo json_encode(array("status"=>"ok"));

            }        

    }




    public function show($id)
    {


        $this->notificationsRead($id);

        $timeInSubtask =$this->countTimeInSubtask($id); //tiempo que tiene una subtarea desde que se creó hasta que finalizó

        $subtask      = Subtask::find($id);

        $subtask_item = DB::table('subtasks')
                        ->join('attach_subtask', 'subtasks.id', '=', 'attach_subtask.subtask_id')
                        ->join('attachments', 'attachments.id', '=', 'attach_subtask.attachment_id')
                        ->leftJoin('attach_task','attach_task.attachment_id','=','attach_subtask.attachment_id')
                        ->select('subtasks.task_id as id_task','attach_subtask.active','attach_subtask.subtask_id as sub_id','attachments.*','attach_task.id as can_delivery','attach_task.active as deliveredtaskdeleted')
                        ->where('subtasks.id','=',$id)
                        ->get();

        // dd($subtask[0]->id_task);

        $task    = Task::find($subtask->task_id); 

        $subtaskattach = array();

        if($subtask_item){

            foreach ($subtask_item  as $key => $value) {

                if($value->active == "1"){

                   array_push($subtaskattach, $value->id);

                }
            }

        }




        $array   = $this->etiquetarUsuarios($id,$subtask->assigned_id,$this->verifyTypeUser());    //  escapada


        $attachdelivered = array();
        $alltaskattach   = array();


       //  dd($task->attachments->toArray);


        if($task->attachments){  // si es de tipo subtarea

            //  guardo todos los attach de la tarea

            foreach ($task->attachments as $key => $value) {
               
                array_push($alltaskattach, $value->id);

            }


            foreach ($task->attachments as $key => $value) {

                if($value->pivot->active == "0"){

                    unset($task->attachments[$key]);

                }elseif ($value->delivered == "1") {

                    array_push($attachdelivered, $task->attachments[$key]->toArray());

                }      

            }

        }






        $args = array(

            'subtask'         => $subtask,
            'statuses'        => Status::where('status_type', '=', 'subtask')->get(),
            'users'           => $array['users'],
            'subtaskattach'   => $subtaskattach,
            'usersEtiq'       => $array['usersEtiq'],
            'task'            => $task,
            'subtask_item'    => $subtask_item,
            'attachdelivered' => $attachdelivered,
            'alltaskattach'   => $alltaskattach,
            'timeInSubtask'   => $timeInSubtask

        );

        return view('subtask.show', $args);
    }


    private function etiquetarUsuarios($id,$userAssigned,$typeUser = null)
    {

        //trae usuarios que  estan etiquetados en la esta tarea
        $userSubtag = Tasktag::select('user_id')->where('relation_id','=',$id)
                ->where('type','=','subtask')
                ->where('active','=',1)->get();


        $type1     = $this->toarrayDistinct(DB::table('user_has_roles')
                    ->whereIn('user_has_roles.role_id', [2,3])->get()->toArray());               
                    
        // todos muestra ?

        $type2     = $this->toarrayDistinct(DB::table('user_has_roles')->get()->toArray());  


        //trae usuarios para mostrar que no esten etiquetados


        if($typeUser == 1){

            $users = DB::table('users')
                    ->whereIn('id',$type1)
                    ->whereNotIn('id',$userSubtag)
                    ->where('id','<>',$userAssigned)
                    ->where('id','<>',Auth::user()->id)
                    ->orderBy('name', 'asc')
                    ->get();

        }else if($typeUser == 2){

           $users = DB::table('users')
                ->whereNotIn('id',$userSubtag)
                ->where('id','<>',$userAssigned)
                ->whereIn('id',$type2)
                ->where('id','<>',Auth::user()->id)
                ->orderBy('name', 'asc')
                ->get();

        }else{

            $users = DB::table('users')
            ->whereNotIn('id',$userSubtag)
            ->where('id','<>',$userAssigned)
            ->where('id','<>',Auth::user()->id)
            ->orderBy('name', 'asc')
            ->get();

        }           


        //trae usuarios etiquetados
        $task_tags = Tasktag::where('relation_id', '=', $id)->where('type','=','subtask')
                 ->where('active','=',1)->get();

        $usersEtiq = array();


        foreach ($task_tags as $tg)
        {
            $user = $tg->user->name;
            $usersEtiq[$tg->id] = array("name"=>$user);

        }

    //    dd($users);


        $args = array(

            'users' => $users,
            'usersEtiq' =>  $usersEtiq,
        );
        return  $args;
    }


    public function updateStatus(Request $request)
    {
//        dd($request->all());
        $subtask = Subtask::find($request->id);

        if($subtask->status_id  !=$request->status_id ) {

            $subtask->status_id = $request->status_id;
            $subtask->save();

            event(new SubtaskStatusChange($subtask));

            return redirect()->back()->with('message', 'Estado  actualizado!');
        }else{
            return redirect()->back();
        }

    }


    public function toarrayDistinct($data){

        if($data){

           $return = array();     

           foreach ($data as $key => $value) {
               array_push($return, $value->user_id);
           }
        }

        return ($return)?array_unique($return):false;
    }



    public function store(StoreSubtask $request)
    {


        $date = Carbon::parse($request->deadline);
        $date3 =$date->format('Y-m-d');
        $subtask = new Subtask();
        $subtask->title = $request->title;
        $subtask->description = $request->description;
        $subtask->status_id = 2;
        $subtask->task_id = $request->task_id;
        $subtask->assigned_id = $request->assigned_id;
        $subtask->deadline =$date3;
        $subtask->user_id = $request->user_id;
        $subtask->save();


        $attachmentsIds = json_decode($request->jsonIdAttachments);

        if($attachmentsIds)
        {
            foreach ($attachmentsIds as $attachment) {

               $query = DB::table('attach_subtask')->insert(
                    ['attachment_id' => $attachment->id, 'subtask_id' => $subtask->id]);

            }
        }
        event(new CreateSubtask($subtask));

        return redirect()->back()->with('message', 'Subtarea agregada!');

    }


 
    /** 
     * pre:recibe el id de la tarea para buscar archivos adjuntados 
     * return: zip de archivos 
     */ 
    public function subtaskDownload($id){ 
 
 
            $task        = Subtask::find($id); 
 
            $public_dir  = public_path(); 
 

        if($task->attachments){

            foreach ($task->attachments as $key => $value) {

                if($value->pivot->active == "0"){

                    unset($task->attachments[$key]);

                }      

            }


        }else{

            return redirect()->back()->with('message', 'Sin archivos para descargar.');

        }


 
        if(count($task->attachments)==1){ 
 
            $headers = array( 
                'Content-Type' => 'application/octet-stream', 
            ); 
 
            foreach($task->attachments as $p){
            
                return response()->download(public_path('/uploads/'.$p->filename), $p->filename, $headers);

            }

        }elseif(count($task->attachments)>1){ 
 
            $zipFileName = 'Subtask'.$id.'Attach'.time().'.zip'; 
 
            $zip         = new ZipArchive(); 
 
 
            if ($zip->open($public_dir . '/' . $zipFileName, ZipArchive::CREATE) === TRUE) { 
                // Add File in ZipArchive 
 
                foreach($task->attachments as $g){ 
                 
                    $zip->addFile(public_path('/uploads/'.$g->filename),$g->filename); 
                 
                } 
 
                // Close ZipArchive      
                $zip->close(); 
            } 
 
            $headers = array( 
                'Content-Type' => 'application/octet-stream', 
            ); 
            $filetopath=$public_dir.'/'.$zipFileName; 
            // Create Download Response 
            if(file_exists($filetopath)){ 
                
                // return response()->download($filetopath,$zipFileName,$headers); 


                $response = response()->download($filetopath,$zipFileName,$headers);
                $response->deleteFileAfterSend(true);

                return $response;


            } 
 
        }else{

                return redirect()->back()->with('message', 'Sin archivos para descargar.');

            } 
 
 
    }


    /**
     * @param $id de la subtarea
     * @return string tiempo de trabajo q se duró o que va teniendo una subrtarea
     */
    private function countTimeInSubtask($id){

        $date_created = '';
        $date_finish = '';
        $timeInSubtask = '';

        $events = Eventlog::where('relation_id','=',$id)->where('type','=','SubtaskStatusChange')->whereIn('content',['Cerrada','Cancelada'])->get();
        $eventsSubtask = Eventlog::where('relation_id','=',$id)->where('type','=','Subtask')->first();
        $date_created = $eventsSubtask->created_at;

        if(count($events) < 1){

            $date_finish =Carbon::now();

        }else{

            $date_finish = $events->last()->created_at; //busca la fecha del último evento encontrado

        }

        $diffDaysAux = $date_created->diffInDays($date_finish);

        if($diffDaysAux < 2) {

            if ($date_created->diffInHours($date_finish) < 2) {

                if($diffDaysAux == 0){
                    $timeInSubtask = '1 minutos';
                }else{
                    $timeInSubtask = $date_created->diffInHours($date_finish) . ' hora';
                }

            } else {
                $timeInSubtask = $date_created->diffInHours($date_finish) . ' horas';
            }

        }elseif ($diffDaysAux > 1 && $diffDaysAux < 31){
            $timeInSubtask = $date_created->diffInDays($date_finish) . ' días';
        }else{

            $timeInSubtask = $date_created->diffInMonths($date_finish) . ' meses';

        }

       return $timeInSubtask;
    }

}
