<?php

namespace Modules\ContactList\Services;

use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Modules\ContactList\Interfaces\ContactListRepositoryInterface;
use Modules\ContactList\Models\ContactList;
use Modules\MainService\Views\ViewFactory;
use Modules\User\Enums\UserRoleEnum;
use Illuminate\Support\Facades\DB;
use App\Jobs\SendMailJob;
use Modules\ContactList\Mails\LeadAssignMail;
use Modules\ContactList\Mails\NotifyManagerMail;

class ContactListService
{
    private string $veiwDirectoryMail = 'admin.contact_lists.mails.';
    public function __construct(
        private ContactListRepositoryInterface $contactListRepository,
        private ViewFactory $viewFactory
    ){}

    public function renderView($request = [])
    {
        $request['contact_lists'] = $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->contactListRepository->get($request);

        if (@$request['title'])
        {
            $builder->where('sd.title', 'LIKE', '%'.$request['title'].'%');
        }

        if (@$request['address'])
        {
            $builder->where('sd.address', 'LIKE', '%'.$request['address'].'%');
        }

        if (@$request['email'])
        {
            $builder->where('contact_lists.email', 'LIKE', '%'.$request['email'].'%');
        }

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


        if (@$request['company_website'])
        {
            $builder->where('contact_lists.company_website', 'LIKE', '%'.$request['company_website'].'%');
        }


        if (@$request['role'])
        {
            $builder->where('contact_lists.role', 'LIKE', '%'.$request['role'].'%');
        }

        if (@$request['note'])
        {
            $builder->where('contact_lists.note', 'LIKE', '%'.$request['note'].'%');
        }

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

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

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

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

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

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

        if (@$request['sector_ids'])
        {
            $builder->whereHas('company',function ($query) use($request){
                $query->whereIn('sector_id',$request['sector_ids']);
            });
        }

        if (@$request['sector_id'])
        {
            $builder->whereHas('company',function ($query) use($request){
                $query->where('sector_id',$request['sector_id']);
            });
        }

        if (isset($request['is_top_customer']))
        {
            $builder->where('contact_lists.is_top_customer', $request['is_top_customer']);
        }

        if(@$request['employeeFilter'])
        {
            if($request['employeeFilter']->role == UserRoleEnum::Head_Department->value)
            {
                $builder->where(function ($q) use ($request) {
                    $q->where('added_by', $request['employeeFilter']->id)
                    ->orWhereHas('added', function ($query) use ($request) {
                        $query->where('manager_id', $request['employeeFilter']->id);
                    });
                });
            }
            else
            {
                // $builder->where('added_by',$request['employeeFilter']->id);
            }
        }

        if (isset($request['decision_maker_status']))
        {
            $builder->where('contact_lists.decision_maker_status', $request['decision_maker_status']);
        }
        if (@$request['type'])
        {
            $builder->where('contact_lists.status', $request['type']);
        }

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

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

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

        if (@$request['orderBy'])
        {
            if($request['orderBy']['key'] == 'company_id')
            {
                $builder
                    ->join('company_descriptions AS cd', 'contact_lists.company_id', 'cd.company_id')
                    ->where('local', LaravelLocalization::getCurrentLocale())
                    ->addSelect('cd.title as company_name')
                    ->orderBy('company_name', $request['orderBy']['value']);
            }
            elseif($request['orderBy']['key'] == 'country_id')
            {
                $builder
                    ->join('country_descriptions AS cd', 'contact_lists.country_id', 'cd.country_id')
                    ->where('local', LaravelLocalization::getCurrentLocale())
                    ->addSelect('cd.title as country_name')
                    ->orderBy('country_name', $request['orderBy']['value']);
            }
            elseif($request['orderBy']['key'] == 'employee_id')
            {
                $builder
                    ->join('users AS cd', 'contact_lists.employee_id', 'cd.id')
                    ->addSelect('cd.name as employee_name')
                    ->orderBy('employee_name', $request['orderBy']['value']);
            }
            else
            {
                $builder->orderBy($request['orderBy']['key'],$request['orderBy']['value']);
            }
        }
        else
        {
            $builder->orderBy('id','DESC');
        }

        if (@$request['paginate'])
        {
            $contact_lists= $builder->paginate(50);
        }
        elseif(@$request['groupBy'])
        {
            if($request['groupBy'] == 'month')
            {
                $contact_lists = $builder
                    ->select(
                        DB::raw('MONTH(contact_lists.created_at) as month'),
                        DB::raw('COUNT(*) as count')
                    )
                    ->groupBy(DB::raw('MONTH(contact_lists.created_at)'))
                    ->reorder()
                    ->get()
                    ->keyBy('month')
                    ->toArray();
            }
        }
        elseif(@$request['count'])
        {
            $contact_lists = $builder->count();
        }
        elseif (@$request['groupCompany'])
        {
            $contact_lists = $builder->get()->groupBy(function($item) {
                return $item->company->currentDescription->title;
            });

        }
        else
        {
            $contact_lists=$builder->get();
        }
        return $contact_lists;
    }
    public function checkItem($id)
    {
        $contactList = $this->contactListRepository->checkItem($id);
        return $contactList;
    }

    public function getItem($id)
    {
        $contactList = $this->contactListRepository->getItem($id);

        return $contactList;
    }

    public function phones($id)
    {
        return $this->contactListRepository->phones($id);
    }

    public function getItemTrashed($id)
    {
        $contactList = $this->contactListRepository->getItemTrashed($id);
        return $contactList;
    }

    public function create(array $request): ContactList
    {
        $contactList = $this->contactListRepository->create($request);
        $this->contactListRepository->saveData($request,$contactList->id);
        $this->contactListRepository->saveDataPhone($request,$contactList->id);

        $this->LeadAssign($contactList,$contactList->employee->email);
        if($contactList->employee->manager_id)
        {
            $this->NotifyManager($contactList,$contactList->employee->manager->email);
        }
        return $contactList;
    }
    public function update(array $request,int $id): ContactList
    {
        $contactList = $this->checkItem($id);
        $old_employee_id = $contactList->employee_id;
        $contactList = $this->contactListRepository->update($request,$contactList);
        if(@$request['title_en'])
        {
            $this->contactListRepository->saveData($request,$contactList->id);
            $this->contactListRepository->saveDataPhone($request,$contactList->id);
        }
        if($request['employee_id'] != $old_employee_id)
        {
            $this->LeadAssign($contactList,$contactList->employee->email);
            if($contactList->employee->manager_id)
            {
                $this->NotifyManager($contactList,$contactList->employee->manager->email);

            }
        }

        return $contactList;
    }

    public function NotifyManager($contactList,$email)
    {
        SendMailJob::dispatch
        (
            $email,
            NotifyManagerMail::class,
            $this->veiwDirectoryMail.'notify_manager',
            'New Lead Added by Your Team',
            $contactList,
        );
    }

    public function LeadAssign($contactList,$email)
    {
            SendMailJob::dispatch
            (
                $email,
                LeadAssignMail::class,
                $this->veiwDirectoryMail.'new_assign',
                'New Lead Assigned to You',
                $contactList,
            );
    }

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

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