<?php

namespace Modules\DailyLog\Services;

use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Modules\DailyLog\Interfaces\DailyLogRepositoryInterface;
use Modules\DailyLog\Models\DailyLog;
use Modules\MainService\Views\ViewFactory;
use Illuminate\Support\Facades\DB;
use Modules\DailyLog\Enums\DailyLogTypeEnum;
use Modules\User\Enums\UserRoleEnum;
use Modules\DailyLog\Mails\ContactReminderMail;


class DailyLogService
{
    private string $veiwDirectoryMail = 'admin.daily_logs.mails.';
    public function __construct(
        private DailyLogRepositoryInterface $dailyLogRepository,
        private ViewFactory $viewFactory
    ){}

    public function renderView($request = [])
    {
        $request['daily_logs'] = $this->get($request);
        return $this->render($request);
    }

    public function render($request = [])
    {
        return $this->viewFactory
            ->render($request['view'])
            ->renderView($request);
    }

    public function get(array $request = [])
    {
        $builder = $this->dailyLogRepository->get($request);

        if (@$request['contact_list'])
        {
            $builder->whereHas('contactList.currentDescription', function ($query) use ($request) {
                $query->where('title','LIKE','%'.$request['contact_list'].'%');
            });
        }

        if (@$request['employee'])
        {
            $builder->whereHas('employee', function ($query) use ($request) {
                $query->where('name','LIKE','%'.$request['employee'].'%');
            });
        }

        if (@$request['date'])
        {
            $builder->where('date', $request['date']);
        }

        if (@$request['objective'])
        {
            $builder->where('objective', $request['objective']);
        }

        if (@$request['type'])
        {
            $builder->where('type', $request['type']);
        }
        if(@$request['expire_date'])
        {
            $builder->where('next_contact','>=',$request['expire_date']);
        }
        if(@$request['type_contact'])
        {
            $builder->whereHas('contactList', function ($query) use ($request) {
                $query->where('status' , $request['type_contact']);
            });
        }
        if (@$request['next_action'])
        {
            $builder->where('next_action', $request['next_action']);
        }

        if (@$request['estimated_sale'])
        {
            $builder->where('estimated_sale', $request['estimated_sale']);
        }

        if (@$request['next_contact'])
        {
            $builder->where('next_contact', $request['next_contact']);
        }

        if (@$request['date_from'])
        {
            $builder->whereDate('created_at', '>=', $request['date_from']);
        }

        if (@$request['date_to'])
        {
            $builder->whereDate('created_at', '<=', $request['date_to']);
        }

        if (isset($request['status']))
        {
            if (@$request['status'] == 0)
            {
                $builder->onlyTrashed();
            }
        }

        if (@$request['orderBy'])
        {
            if($request['orderBy']['key'] == 'contact_list')
            {
                $builder
                    ->join('contact_list_descriptions AS cd', 'daily_logs.contact_list_id', 'cd.contact_list_id')
                    ->select('cd.title as contact_list_name','daily_logs.*')
                    ->orderBy('contact_list_name', $request['orderBy']['value']);
            }
            elseif($request['orderBy']['key'] == 'employee')
            {
                $builder
                    ->join('users AS us', 'daily_logs.employee_id', 'us.id')
                    ->select('us.name as employee_name','daily_logs.*')
                    ->orderBy('employee_name', $request['orderBy']['value']);
            }
            else
            {
                $builder->orderBy($request['orderBy']['key'],$request['orderBy']['value']);
            }
        }
        else
        {
            $builder->orderBy('id','DESC');
        }

        if (@$request['paginate']) {
            $daily_logs= $builder->paginate(50);
        }
        elseif(@$request['groupBy'])
        {
            if($request['groupBy'] == 'month')
            {
                $daily_logs = $builder
                    ->select(
                        DB::raw('MONTH(date) as month'),
                        DB::raw('COUNT(*) as count')
                    )
                    ->groupBy(DB::raw('MONTH(date)'))
                    ->reorder()
                    ->get()
                    ->keyBy('month')
                    ->toArray();
            }
            elseif($request['groupBy'] == 'type')
            {
                $daily_logs = $builder
                    ->select(
                        'type',
                        DB::raw('COUNT(*) as count')
                    )
                    ->groupBy('type')
                    ->get()
                    ->sortByDesc('count')
                    ->keyBy('type')
                    ->toArray();
            }
            elseif($request['groupBy'] == 'employeesCommunication')
            {
                $select = [
                    'users.id as employee_id',
                    'users.name',
                ];

                foreach (DailyLogTypeEnum::values() as $value) {
                    $select[] = DB::raw("SUM(daily_logs.type = {$value}) as type_{$value}");
                }

                $daily_logs = DB::table('users')
                    ->leftJoin('daily_logs', 'users.id', '=', 'daily_logs.employee_id')
                    ->whereNull('users.deleted_at')
                    ->whereIn('users.role',UserRoleEnum::employees())
                    ->select($select)
                    ->groupBy('users.id', 'users.name')
                    ->orderBy('users.name')
                    ->get();
            }
        }
        elseif (@$request['groupSector'])
        {
            $daily_logs = $builder->get()->groupBy(function($item) {
                return $item->sector->currentDescription->title;
            });

        }
        else
        {
            $daily_logs=$builder->get();
        }
        return $daily_logs;
    }

    public function checkItem($id)
    {
        return $this->dailyLogRepository->checkItem($id);
    }

    public function getItem($id)
    {
        return $this->dailyLogRepository->getItem($id);
    }

    public function getItemTrashed($id)
    {
        return $this->dailyLogRepository->getItemTrashed($id);
    }

    public function create(array $request): DailyLog
    {
        return $this->dailyLogRepository->create($request);
    }
    public function update(array $request,int $id): DailyLog
    {
        $dailyLog = $this->checkItem($id);
        $dailyLog = $this->dailyLogRepository->update($request,$dailyLog);
        return $dailyLog;
    }

    public function sendReminder($dailyLog)
    {
            SendMailJob::dispatch
            (
                $dailyLog->employee->email,
                ContactReminderMail::class,
                $this->veiwDirectoryMail.'contact_reminder',
                'Follow-Up Reminder — '.($dailyLog->contactList->currentDescription->title ?? '' ),
                $dailyLog,
            );
    }

    public function updateLock($id)
    {
        $dailyLog = $this->checkItem($id);
        $this->update(['lock'=>($dailyLog->lock?0:1)],$id);
    }

    public function destroy(int $id): void
    {
        $dailyLog = $this->checkItem($id);
        if ($dailyLog)
        {
            $this->dailyLogRepository->destroy($dailyLog);
        }
        else
        {
            $dailyLog = $this->getItemTrashed($id);
            $this->dailyLogRepository->restore($dailyLog);
        }
    }
    public function destroyAll(array $request): void
    {
        if ($request['status'] == 1)
        {
            $this->dailyLogRepository->destroyAll($request['ids']);
        }
        else
        {
            $this->dailyLogRepository->restoreAll($request['ids']);
        }
    }
}
