<?php

namespace Modules\UserManagement\Service;


use App\Service\BaseService;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Modules\UserManagement\Repository\UserLevelRepositoryInterface;
use Modules\UserManagement\Service\Interface\CustomerLevelServiceInterface;

class CustomerLevelService extends BaseService implements CustomerLevelServiceInterface
{
    protected $customerLevelRepository;

    public function __construct(UserLevelRepositoryInterface $customerLevelRepository)
    {
        parent::__construct($customerLevelRepository);
        $this->customerLevelRepository = $customerLevelRepository;
    }

    public function index(array $criteria = [], array $relations = [], array $whereHasRelations = [], array $orderBy = [], ?int $limit = null, ?int $offset = null, array $withCountQuery = [], array $appends = [], array $groupBy = []): Collection|LengthAwarePaginator
    {
        $data = [];
        if (array_key_exists('status', $criteria) && $criteria['status'] !== 'all') {
            $data['is_active'] = $criteria['status'] == 'active' ? 1 : 0;
        }
        $data['user_type'] = CUSTOMER;

        $searchData = [];
        if (array_key_exists('search', $criteria) && $criteria['search'] != '') {
            $searchData['fields'] = ['name'];
            $searchData['value'] = $criteria['search'];
        }

        return $this->customerLevelRepository->getBy(criteria: $data, searchCriteria: $searchData, relations: $relations, orderBy: $orderBy, limit: $limit, offset: $offset, withCountQuery: $withCountQuery); // TODO: Change the autogenerated stub
    }

    public function create(array $data): ?Model
    {
        $storeData = [
            'sequence' => $data['sequence'],
            'name' => $data['name'],
            'reward_type' => $data['reward_type'],
            'targeted_ride' => $data['targeted_ride'] ?? 0,
            'targeted_ride_point' => $data['targeted_ride_point'] ?? 0,
            'targeted_amount' => $data['targeted_amount'] ?? 0,
            'targeted_amount_point' => $data['targeted_amount_point'] ?? 0,
            'targeted_cancel' => $data['targeted_cancel'] ?? 0,
            'targeted_cancel_point' => $data['targeted_cancel_point'] ?? 0,
            'targeted_review' => $data['targeted_review'] ?? 0,
            'targeted_review_point' => $data['targeted_review_point'] ?? 0,
            'image' => fileUploader('customer/level/', 'png', $data['image']),
            'user_type' => CUSTOMER,
        ];
        if ($data['reward_type'] != 'no_rewards') {
            $storeData = array_merge($storeData, [
                'reward_amount' => $data['reward_amount']
            ]);
        }
        return $this->customerLevelRepository->create($storeData);
    }

    public function update(int|string $id, array $data = []): ?Model
    {
        $model = $this->customerLevelRepository->findOne(id: $id);
        $updateData = [
            'name' => $data['name'],
            'reward_type' => $data['reward_type'],
        ];
        if (array_key_exists('minimum_ride_complete', $data)) {
            $updateData = array_merge($updateData, [
                'targeted_ride' => $data['targeted_ride'],
                'targeted_ride_point' => $data['targeted_ride_point'],
            ]);
        } else {
            $updateData = array_merge($updateData, [
                'targeted_ride' => 0,
                'targeted_ride_point' => 0,
            ]);
        }
        if (array_key_exists('minimum_earn_amount', $data)) {
            $updateData = array_merge($updateData, [
                'targeted_amount' => $data['targeted_amount'],
                'targeted_amount_point' => $data['targeted_amount_point'],
            ]);
        } else {
            $updateData = array_merge($updateData, [
                'targeted_amount' => 0,
                'targeted_amount_point' => 0,
            ]);
        }
        if (array_key_exists('maximum_cancellation_rate', $data)) {
            $updateData = array_merge($updateData, [
                'targeted_cancel' => $data['targeted_cancel'],
                'targeted_cancel_point' => $data['targeted_cancel_point'],
            ]);
        } else {
            $updateData = array_merge($updateData, [
                'targeted_cancel' => 0,
                'targeted_cancel_point' => 0,
            ]);
        }
        if (array_key_exists('minimum_review_receive', $data)) {
            $updateData = array_merge($updateData, [
                'targeted_review' => $data['targeted_review'],
                'targeted_review_point' => $data['targeted_review_point'],
            ]);
        } else {
            $updateData = array_merge($updateData, [
                'targeted_review' => 0,
                'targeted_review_point' => 0,
            ]);
        }
        if (array_key_exists('image', $data)) {
            $updateData = array_merge($updateData, [
                'image' => fileUploader('customer/level/', 'png', $data['image'], $model?->image)
            ]);
        }
        if ($data['reward_type'] !== 'no_rewards') {
            $updateData = array_merge($updateData, [
                'reward_amount' => $data['reward_amount']
            ]);
        }
        return $this->customerLevelRepository->update($id, $updateData);
    }

    public function getStatistics(array $data = []): Collection|LengthAwarePaginator
    {
        $whereBetweenCriteria = [];
        if (array_key_exists('date_range', $data) && $data['date_range'] != '') {
            $dateRange = getDateRange($data['date_range']);
            if($dateRange){
                $whereBetweenCriteria = [
                    'created_at' => [$dateRange['start'], $dateRange['end']],
                ];
            }
        }
        $criteria['user_type'] = CUSTOMER;
        return $this->customerLevelRepository->getStatistics(criteria: $criteria, whereBetweenCriteria: $whereBetweenCriteria, relations: ['users.customerTrips'], withCountQuery: ['users' => []]);
    }

    public function trashedData(array $criteria = [], array $relations = [], array $orderBy = [], ?int $limit = null, ?int $offset = null, array $withCountQuery = []): Collection|LengthAwarePaginator
    {
        $searchData = [];
        if (array_key_exists('search', $criteria) && $criteria['search'] != '') {
            $searchData['fields'] = ['name'];
            $searchData['value'] = $criteria['search'];
        }
        $data['user_type'] = CUSTOMER;
        return $this->customerLevelRepository->getBy(criteria: $data, searchCriteria: $searchData, relations: $relations, orderBy: $orderBy, limit: $limit, offset: $offset, onlyTrashed: true);
    }

    public function export(array $criteria = [], array $relations = [], array $orderBy = [], ?int $limit = null, ?int $offset = null, array $withCountQuery = []): Collection|LengthAwarePaginator|\Illuminate\Support\Collection
    {
        return $this->index(criteria: $criteria, orderBy: $orderBy)->map(function ($item) {
            $totalTrip = 0;
            $completedTrip = 0;
            $cancelledTrip = 0;
            foreach ($item->users as $user) {
                $totalTrip += $user->customerTripsStatus->count();
                $completedTrip += $user->customerTripsStatus->whereNotNull('completed')->count();
                $cancelledTrip += $user->customerTripsStatus->whereNotNull('cancelled')->count();
            }
            if ($totalTrip < 1) {
                $totalTrip = 1;
            }
            return [
                'ID' => $item['id'],
                'Name' => $item['name'],
                'Targeted Ride Trip' => $item['targeted_ride'],
                'Targeted Ride Point' => $item['targeted_ride_point'],
                'Minimum Spend Amount Cash' => set_currency_symbol($item['targeted_amount'] ?? 0),
                'Minimum Spend Amount Point' => $item['targeted_amount_point'],
                'Ride Cancellation Rate' => $item['targeted_cancel'],
                'Ride Cancellation Point' => $item['targeted_cancel_point'],
                'Minimum Review' => $item['targeted_review'],
                'Minimum Review Point' => $item['targeted_review_point'],
                'Completed Rides' => $completedTrip,
                'Max Cancellation Rate' => $cancelledTrip / $totalTrip * 100,
                'Total Customer' => $item->users->count(),
                'Status' => $item['is_active'] ? 'Active' : 'Inactive',
            ];
        });
    }
}
