<?php

namespace App\Repositories;
use Illuminate\Support\Str;

use App\Models\CommunityTaskManagement;
use Illuminate\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;

class CommunityTaskManagementRepository
{
    public function __construct(CommunityTaskManagement $communityTaskManagement,
        Dispatcher $event,
        CommunityRepository $communityRepository,
        CommunityCategoryRepository $communityCategoryRepository,
        CommunityCategoryMembersRepository $communityCategoryMembersRepository,
        CommunityMemberRepository $communityMemberRepository,
        NotificationRepository $notificationRepository,
        UserRepository $userRepository,
        CommunityTaskManagementUsersRepository $communityTaskManagementUsersRepository,
        CommunitySpaceUsedRepository $communitySpaceUsedRepository,
        Filesystem $filesystem
    ) {
        $this->model = $communityTaskManagement;
        $this->communityRepository = $communityRepository;
        $this->communityCategoryRepository = $communityCategoryRepository;
        $this->communityCategoryMembersRepository = $communityCategoryMembersRepository;
        $this->communityMemberRepository = $communityMemberRepository;
        $this->notification = $notificationRepository;
        $this->userRepository = $userRepository;
        $this->communityTaskManagementUsersRepository = $communityTaskManagementUsersRepository;
        $this->communitySpaceUsedRepository = $communitySpaceUsedRepository;
        $this->file = $filesystem;
    }

    public function getTasks($community_id, $type, $limit = 5)
    {
        $user_id = \Auth::user()->id;
        if ($type != '') {
            return $this->model->where('crm_pushed', '=', 0)->where('community_id', '=', $community_id)->where('user_id', '=', $user_id)->where('task_priority', '=', $type)->orderBy('id', 'desc')->paginate($limit);
        } else {
            return $this->model->where('crm_pushed', '=', 0)->where('community_id', '=', $community_id)->where('user_id', '=', $user_id)->orderBy('id', 'desc')->paginate($limit);
        }
    }

    public function addTask($val, $community = null, $business = null, $product_id = 0)
    {
        $community_id = 0;

        $upload_community_id = 0;
        if ($community) {
            $community_id = $community->id;
            $upload_community_id = $community_id;
        }

        $business_id = 0;
        $business_user = 0;
        if ($business) {
            $business_id = $business->id;
            $business_user = $business->user_id;
            $upload_community_id = $business->community_id;
        }

        $expected = [
            'title' => '',
            'description' => '',
            'delivery_date' => '',
            'team_users' => '',
            'task_priority' => 0,
            'file_description' => '',
            'client' => '',
            'project' => '',
        ];

        extract($val = array_merge($expected, $val));

        $user = (empty($user)) ? \Auth::user() : $user;
        $CDNRepository = app('App\\Repositories\\CDNRepository');

        $task_file_path = '';
        $fileExt = '';
        $document_original_name = '';

        $upload_key = Str::random(20);

        if (request()->hasFile('documents')) {

            $mainFile = request()->file('documents');
            $fileExt = $mainFile->getClientOriginalExtension();
            $file_original_ext = $fileExt;
            $file_original_name = $mainFile->getClientOriginalName();
            $file_original_size = $mainFile->getSize();

            if (checkAvailableSpace($upload_community_id, $file_original_size) != 0) {
                $document_size = $mainFile->getSize();
                $userid = \Auth::user()->id;
                if ($community_id == 0) {
                    $filePath = 'uploads/business/'.$business_id.'/inquiry/';
                } else {
                    $filePath = 'uploads/community/'.$community_id.'/tasks/';
                }
                $this->file->makeDirectory(public_path().'/'.$filePath, 0777, true, true);
                $fileName = md5($mainFile->getClientOriginalName().time()).'.'.$fileExt;
                $file_path = $filePath.$fileName;
                $document_original_name = $mainFile->getClientOriginalName();
                $mainFile->move(public_path().'/'.$filePath, $fileName);
                $newFileName = $CDNRepository->upload(public_path().'/'.$file_path, $file_path);
                $CDNRepository->deleteThisFile(public_path().'/'.$file_path);
                $task_file_path = $newFileName;

                $fileArray = [
                    'community_id' => $upload_community_id,
                    'user_id' => \Auth::user()->id,
                    'file_path' => $task_file_path,
                    'file_name' => $file_original_name,
                    'file_type' => $file_original_ext,
                    'file_size' => $file_original_size,
                    'uploaded_date' => date('Y-m-d'),
                    'type' => 'task-management',
                    'type_id' => 0,
                    'sub_type_id' => 0,
                    'upload_key' => $upload_key,
                ];
                $this->communitySpaceUsedRepository->save($fileArray);
            }
        }

        $task = $this->model->newInstance();
        $task->user_id = $user->id;
        $task->community_id = $community_id;
        $task->title = $title;
        $task->description = $description;
        $task->file_path = $task_file_path;
        $task->file_type = $fileExt;
        $task->expected_delivery = date('Y-m-d H:i:s', strtotime($delivery_date));
        $task->target_users = $team_users;
        $task->task_priority = $task_priority;
        $task->file_description = $file_description;
        $task->file_original_name = $document_original_name;
        $task->business_id = $business_id;
        $task->product_id = $product_id;
        $task->business_user = $business_user;
        // $task->client=$client;
        $task->project = $project;
        $task->save();

        if ($task) {
            $this->communitySpaceUsedRepository->updateId($upload_key, $task->id);
        }

        $this->communityTaskManagementUsersRepository->add($task, $community);

        return $task;
    }

    public function getById($community_id, $taskId)
    {
        return $this->model->where('community_id', '=', $community_id)->where('id', '=', $taskId)->first();
    }

    public function findById($taskId)
    {
        return $this->model->where('id', '=', $taskId)->first();
    }

    public function getMyTasks($community_id, $type, $limit = 5)
    {
        $user_id = \Auth::user()->id;

        $user_id = \Auth::user()->id;
        if ($type != '') {

            $tasks = $this->model
                ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
                ->where('community_tasks.community_id', $community_id)
                ->where('community_tasks.task_priority', $type)
                ->where('community_tasks.crm_pushed', '=', 0);

            $tasks = $tasks->where(function ($tasks) use ($user_id) {
                $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                    ->orWhere('community_tasks.user_id', '=', $user_id);
            });

            return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
                ->orderBy('community_tasks.id', 'desc')
                ->groupBy('community_tasks.id')
                ->paginate($limit);

        } else {

            $tasks = $this->model
                ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
                ->where('community_tasks.community_id', $community_id);

            $tasks = $tasks->where('community_tasks.crm_pushed', '=', 0);

            $tasks = $tasks->where(function ($tasks) use ($user_id) {
                $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                    ->orWhere('community_tasks.user_id', '=', $user_id);
            });

            return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
                ->orderBy('community_tasks.id', 'desc')
                ->groupBy('community_tasks.id')
                ->paginate($limit);
        }
    }

    public function updateTaskStatus($id, $starttime, $endtime, $status)
    {
        if ($starttime) {
            $starttime = date('Y-m-d H:i:s', strtotime($starttime));
        }

        if ($endtime) {
            $endtime = date('Y-m-d H:i:s', strtotime($endtime));
        }

        $this->model->where('id', '=', $id)->update(['task_status' => $status, 'start_date' => $starttime, 'end_date' => $endtime]);

        $task = $this->findById($id);

        $teamUsers = $this->communityTaskManagementUsersRepository->getTeamByTask($id);
        if ($teamUsers) {
            $user_id = \Auth::user()->id;
            foreach ($teamUsers as $team) {
                $user = $team->user;
                if ($user) {
                    if ($user_id != $user->id) {
                        $this->notification->send($user->id, [
                            'path' => 'notification.community.task-status',
                            'type' => 'task-status',
                            'typeId' => $id,
                        ], $user_id, false, null, null, $task->community_id);
                    }
                }
            }
        }

        return $this->findById($id);
    }

    public function editTask($val, $community, $task, $business = null)
    {
        $expected = [
            'title' => '',
            'description' => '',
            'delivery_date' => '',
            'team_users' => '',
            'task_priority' => 0,
            'file_description' => '',
            'client' => '',
            'project' => '',
        ];

        $community_id = 0;
        $upload_community_id = 0;

        if ($community) {
            $community_id = $community->id;
            $upload_community_id = $community_id;
        }

        $business_id = 0;
        if ($business) {
            $business_id = $business->id;
            $upload_community_id = $business->community_id;
        }

        extract($val = array_merge($expected, $val));

        $user = (empty($user)) ? \Auth::user() : $user;
        $CDNRepository = app('App\\Repositories\\CDNRepository');

        $task_file_path = '';
        $fileExt = '';
        $document_original_name = '';

        $upload_key = Str::random(20);

        if (request()->hasFile('documents')) {

            $mainFile = request()->file('documents');
            $fileExt = $mainFile->getClientOriginalExtension();
            $file_original_ext = $fileExt;
            $file_original_name = $mainFile->getClientOriginalName();
            $file_original_size = $mainFile->getSize();

            if (checkAvailableSpace($upload_community_id, $file_original_size) != 0) {
                $document_size = $mainFile->getSize();
                $userid = \Auth::user()->id;
                if ($community_id == 0) {
                    $filePath = 'uploads/business/'.$business_id.'/inquiry/';
                } else {
                    $filePath = 'uploads/community/'.$community_id.'/tasks/';
                }
                $this->file->makeDirectory(public_path().'/'.$filePath, 0777, true, true);
                $fileName = md5($mainFile->getClientOriginalName().time()).'.'.$fileExt;
                $file_path = $filePath.$fileName;
                $document_original_name = $mainFile->getClientOriginalName();
                $mainFile->move(public_path().'/'.$filePath, $fileName);
                $newFileName = $CDNRepository->upload(public_path().'/'.$file_path, $file_path);
                $CDNRepository->deleteThisFile(public_path().'/'.$file_path);
                $task_file_path = $newFileName;

                $fileArray = [
                    'community_id' => $upload_community_id,
                    'user_id' => \Auth::user()->id,
                    'file_path' => $task_file_path,
                    'file_name' => $file_original_name,
                    'file_type' => $file_original_ext,
                    'file_size' => $file_original_size,
                    'uploaded_date' => date('Y-m-d'),
                    'type' => 'task-management',
                    'type_id' => 0,
                    'sub_type_id' => $task->id,
                    'upload_key' => $upload_key,
                ];
                $this->communitySpaceUsedRepository->save($fileArray);
            }
        }

        $task->title = $title;
        $task->description = $description;
        if ($task_file_path) {
            $task->file_path = $task_file_path;
            $task->file_original_name = $document_original_name;
            $task->file_type = $fileExt;
        }

        $task->expected_delivery = date('Y-m-d H:i:s', strtotime($delivery_date));
        $task->target_users = $team_users;
        $task->task_priority = $task_priority;
        $task->file_description = $file_description;
        // $task->client=$client;
        $task->project = $project;
        $task->save();

        $this->communityTaskManagementUsersRepository->add($task, $community);

        return $task;
    }

    public function getBusinessTasks($limit = 5)
    {
        $user_id = \Auth::user()->id;

        return $this->model->where('community_id', '=', 0)->where('business_id', '!=', 0)->where('product_id', '!=', 0)->where('user_id', '=', $user_id)->orderBy('id', 'desc')->paginate($limit);
    }

    public function getBusinessProductsTasks($business_id, $product_id, $limit = 5)
    {
        $user_id = \Auth::user()->id;

        return $this->model->where('community_id', '=', 0)
        // ->where('business_id', '!=', 0)
        // ->where('product_id', '!=', 0)
            ->where('business_id', '=', $business_id)
            ->where('product_id', '=', $product_id)
            ->orderBy('id', 'desc')
            ->paginate($limit);
    }

    public function getAllTasks($community_id)
    {
        $user_id = \Auth::user()->id;

        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
            ->orderBy('community_tasks.id', 'desc')
            ->groupBy('community_tasks.id')
            ->get();
    }
	
	public function getNewTasks($community_id)
    {
        $user_id = \Auth::user()->id;

		// Dashboard only needs a short list (title + priority). Avoid join + groupBy overhead by
		// using a subquery for assigned tasks.
		return $this->model
			->where('community_id', $community_id)
			->where('crm_pushed', '=', 0)
			->where(function ($q) use ($user_id) {
				$q->where('user_id', '=', $user_id)
					->orWhereIn('id', function ($sq) use ($user_id) {
						$sq->select('task_id')
							->from('community_tasks_users')
							->where('user_id', '=', $user_id);
					});
			})
			->orderBy('id', 'desc')
			->limit(5)
			->get(['id', 'title', 'task_priority', 'user_id']);
    }

    public function getTasksByStatus($community_id, $status)
    {
        $user_id = \Auth::user()->id;

        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)
            ->where('community_tasks.task_status', '=', $status)
            ->where('community_tasks.crm_pushed', '=', 0);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
            ->orderBy('community_tasks.id', 'desc')
            ->groupBy('community_tasks.id')
            ->get();
    }

    public function getTasksByStatusLatest($community_id, $status)
    {
        $user_id = \Auth::user()->id;

        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)
            ->where('community_tasks.task_status', '=', $status)
            ->where('community_tasks.crm_pushed', '=', 0);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
            ->orderBy('community_tasks.updated_at', 'desc')
            ->groupBy('community_tasks.id')
            ->get();
    }

    public function getTasksByStatusesLatest($community_id, array $statuses)
    {
        $user_id = \Auth::user()->id;

        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)
            ->whereIn('community_tasks.task_status', $statuses)
            ->where('community_tasks.crm_pushed', '=', 0);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        return $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
            ->orderBy('community_tasks.updated_at', 'desc')
            ->groupBy('community_tasks.id')
            ->get();
    }
	
	public function getTasksCount($community_id)
	{
		 $user_id = \Auth::user()->id;
		  
		 $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)           
            ->where('community_tasks.crm_pushed', '=', 0);

         $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
         });

         return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')->count();
	}
	
	public function getTasksCountByPriority($community_id,$pr)
	{
		 $user_id = \Auth::user()->id;
		  
		 $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)   
			->where('community_tasks.task_priority', $pr)         
            ->where('community_tasks.crm_pushed', '=', 0);

         $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
         });

         return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')->count();
	}

    public function getTasksCountsSummary($community_id)
    {
        $user_id = \Auth::user()->id;
        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)
            ->where('community_tasks.crm_pushed', '=', 0);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        // NOTE: selectRaw() strings are not prefix-rewritten; avoid explicit table names here.
        // We count DISTINCT task_id to avoid overcounting tasks with multiple team members.
        $row = $tasks->selectRaw(
            'COUNT(DISTINCT task_id) as total, '
            ."COUNT(DISTINCT CASE WHEN task_priority = 1 THEN task_id END) as low, "
            ."COUNT(DISTINCT CASE WHEN task_priority = 2 THEN task_id END) as urgent, "
            ."COUNT(DISTINCT CASE WHEN task_priority = 0 THEN task_id END) as normal"
        )->first();

        return [
            'total' => (int) ($row->total ?? 0),
            'low' => (int) ($row->low ?? 0),
            'urgent' => (int) ($row->urgent ?? 0),
            'normal' => (int) ($row->normal ?? 0),
        ];
    }

    public function changeTaskStatus($id, $status)
    {
        $status = $this->model->where('id', '=', $id)->update(['task_status' => $status]);

        return $status;
    }

    public function getOpenTasks($community_id)
    {
        $user_id = \Auth::user()->id;

        $tasks = $this->model
            ->join('community_tasks_users', 'community_tasks.id', '=', 'community_tasks_users.task_id')
            ->where('community_tasks.community_id', $community_id)
            ->where('community_tasks.task_status', '!=', 0)
            ->where('community_tasks.task_status', '!=', 3)
            ->where('community_tasks.crm_pushed', '=', 0);

        $tasks = $tasks->where(function ($tasks) use ($user_id) {
            $tasks = $tasks->where('community_tasks_users.user_id', '=', $user_id)
                ->orWhere('community_tasks.user_id', '=', $user_id);
        });

        return $tasks = $tasks->select('community_tasks.*', 'community_tasks.id as task_id', 'community_tasks.user_id as task_user_id')
            ->orderBy('community_tasks.id', 'desc')
            ->groupBy('community_tasks.id')
            ->get();
    }

    public function getMyAllTasks($community_id, $user_id)
    {
        return $this->model->where('crm_pushed', '=', 0)->where('community_id', '=', $community_id)->where('user_id', '=', $user_id)->orderBy('id', 'desc')->get();
    }

    public function getMyAllTasksById($community_id, $user_id, $id)
    {
        return $this->model->where('crm_pushed', '=', 0)->where('id', '=', $id)->where('community_id', '=', $community_id)->where('user_id', '=', $user_id)->orderBy('id', 'desc')->get();
    }
}

