<?php

namespace Modules\Target\Services;

use Illuminate\Support\Facades\DB;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Modules\Target\Interfaces\TargetRepositoryInterface;
use Modules\Target\Models\Target;
use Modules\MainService\Views\ViewFactory;
use Modules\Product\Services\ProductService;
use Modules\Target\Enums\TargetLengthEnum;
use Modules\User\Enums\UserRoleEnum;
use Modules\User\Services\UserService;

class TargetService
{
    public function __construct(
        private TargetRepositoryInterface $targetRepository,
        private ProductService $productService,
        private UserService $userService,
        private ViewFactory $viewFactory
    ){}

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

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

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

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

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

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

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

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


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

        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['groupBy'])
        {
            if($request['groupBy'] == 'month')
            {
                return $builder->select(
                        'targets.month',
                        DB::raw('SUM(targets.target) as total_target')
                    )
                    ->groupBy('targets.month')
                    ->get()
                    ->keyBy('month')     
                    ->toArray();
            }
            else
            {
                $builder->select(
                    'targets.year',
                    'targets.product_id',
                    'targets.employee_id',
                    DB::raw('SUM(targets.target) as total_target')
                )->groupBy('year', 'product_id', 'employee_id');
                if(@$request['total_target'])
                {
                    $builder->having('total_target',  $request['total_target']);
                }
            }
        }
        if (@$request['orderBy'])
        {
            if($request['orderBy']['key'] == 'employee')
            {
                $builder
                    ->join('users AS us', 'targets.employee_id', 'us.id')
                    ->addSelect(DB::raw('ANY_VALUE(us.name) as employee_name'));
                if (!@$request['groupBy'])
                {
                    $builder->addSelect('targets.*');
                }
                $builder->orderBy('employee_name', $request['orderBy']['value']);
            }
            elseif($request['orderBy']['key'] == 'product')
            {
                $builder
                    ->join('product_descriptions AS cd', 'targets.product_id', 'cd.product_id')
                    ->addSelect(DB::raw('ANY_VALUE(cd.title) as product_name'));
                    if (!@$request['groupBy'])
                    {
                        $builder->addSelect('targets.*');
                    }
                    $builder->orderBy('product_name', $request['orderBy']['value']);
            }
            else
            {
                $builder->orderBy($request['orderBy']['key'],$request['orderBy']['value']);
            }
        }
        else
        {
            if(!@$request['groupBy'])
            {
                $builder->orderBy('year', 'DESC');
            }
        }



        if (@$request['paginate']) {
            $targets= $builder->paginate(50);
        }
        elseif(@$request['sum'])
        {
            $targets = $builder->sum($request['sum']);
        }
        else
        {
            $targets=$builder->get();
        }
        return $targets;
    }

    public function checkItem($id)
    {
        $target = $this->targetRepository->checkItem($id);
        return $target;
    }


    public function getMonths(array $request)
    {
        return $this->targetRepository->getMonths($request);
    }


    public function getTarget(array $request)
    {
        $res = [];
        $months = [];
        foreach($request['length'] as $row)
        {
            $months = array_merge($months,TargetLengthEnum::months($row));
        }
        foreach($request['product_id'] as $product_id)
        {
            $product = $this->productService->getItem($product_id);
            $res[$product_id]['product_id'] = $product_id;
            $res[$product_id]['product'] = $product->currentDescription->title ?? null;
            foreach($months as $month)
            {
                $target = $this->targetRepository->getTarget([
                    'product_id'=>$product_id,
                    'year'=>$request['year'],
                    'month'=>$month,
                    'employee_id'=>$request['employee_id']
                ]);
                $res[$product_id]['months'][$month]['target'] = $target->target ?? '';
            }
        }
        return $res;
    }

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

    public function getItemTrashed($id)
    {
        $target = $this->targetRepository->getItemTrashed($id);
        return $target;
    }

    public function create(array $request)
    {
        $months = [];
        foreach($request['length'] as $row)
        {
            $months = array_merge($months,TargetLengthEnum::months($row));
        }
        $data =
        [
            'employee_id'=>$request['employee_id'],
            'year'=>$request['year'],
            'month'=>$months,
            'product_id'=>$request['product_id'],
        ];
        $this->targetRepository->deleteYearMonth($data);
        foreach($request['products'] as $product_id => $product)
        {
            foreach($product['months'] as $month=>$row)
            {
                if($row['target'])
                {
                    $data =
                    [
                        'year'=>$request['year'],
                        'month'=>$month,
                        'employee_id'=>$request['employee_id'],
                        'product_id'=>$product_id,
                        'target'=>$row['target'],
                    ];
                    $this->targetRepository->create($data);
                }
            }
        }

    }
    public function update(array $request,int $id): target
    {
        $target = $this->checkItem($id);
        $target = $this->targetRepository->update($request,$target);
        return $target;
    }

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

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