<?php

namespace Modules\Order\Services;

use DB;
use Modules\Notification\Services\NotificationService;
use Modules\Order\Interfaces\OrderRepositoryInterface;
use Modules\Order\Models\Order;
use Modules\PaymentLog\Enums\PaymentLogAccStatusEnum;
use Modules\PaymentLog\Enums\PaymentLogStatusEnum;
use Modules\PaymentLog\Services\PaymentLogService;
use Modules\Product\Enums\ProductStockStatusEnum;
use Modules\Product\Models\Product;
use Modules\Product\Services\ProductService;
use Modules\User\Services\UserService;

class OrderService
{
    private OrderRepositoryInterface $orderRepository;

    public function __construct(
        OrderRepositoryInterface $orderRepository,
        private UserService $userService,
        private PaymentLogService $paymentLogService,
        private ProductService $productService,
        private NotificationService $notificationService,
    ) {
        $this->orderRepository = $orderRepository;
    }

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

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

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

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

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

        if (@$request['condition']) {
            $builder->whereRaw($request['condition']);
        }

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

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

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

        if (@$request['orderBy']) {
            $builder->orderBy($request['orderBy']['key'], $request['orderBy']['value']);
        } else {
            $builder->orderBy('id', 'DESC');
        }

        if (@$request['paginate']) {
            $orders = $builder->paginate(50);
        } elseif (@$request['api']) {
            $orders = $builder;
        } else {
            $orders = $builder->cursor();
        }
        return $orders;
    }
    public function getProductsByChildId(int $childId)
    {
        return $this->orderRepository->getProductsByChildId($childId);
    }

    public function checkItem($id)
    {
        $order = $this->orderRepository->checkItem($id);
        return $order;
    }

    public function getItem($id)
    {
        $order = $this->checkItem($id);

        return $order;
    }

    public function getItemTrashed($id)
    {
        $order = $this->orderRepository->getItemTrashed($id);
        return $order;
    }

    public function create(array $request): Order
    {
        return DB::transaction(function () use ($request) {
            $children = $request['children'];
            $data = [];
            // Calculate total order values
            $total = 0;
            $totalProducts = 0;

            foreach ($request['products'] as $item) {
                $product = $this->productService->getItem($item['product_id'])['ar'] ?? null;
                if (!$product) {
                    continue; // Skip if product not found
                }
                $productTotal = $product->cost * $item['count']; // Assuming price field exists in Product
                $total += $productTotal;
                $totalProducts += $item['count'];
            }

            $canteen_id = auth()->user()->canteen->id;
            $data['total_products'] = $total;
            $data['child_id'] = $request['child_id'];
            $data['canteen_id'] = $canteen_id;

            $data['total_management'] = $total * (settings('management_tax') / 100);
            $data['tax_cost'] = settings('tax_valid') == "1" ? $total * (settings('tax_value') / 100) : 0;
            $data['total'] = $data['total_management'] + $data['tax_cost'] + $total;
//            $data['total_points'] = $data['total'] / settings('point_val');
            // dd($data);
            // Create the order
            $order = $this->orderRepository->create($data);
            $parent = $children->parent;
            $parentId = $parent->id;
            $this->paymentLogService->create(
                [
                    'user_id' => $parentId,
                    'status' => PaymentLogStatusEnum::MINUS->value,
                    'acc_status'=>PaymentLogAccStatusEnum::PARENT->value,
                    'price' => $data['total'],
//                    'points' => $data['total_points'],
                    'order_id' => $order->id,

                ]
            );
            $this->notificationService->create([
                'target' => $parentId,
                'user_id' => $parentId,
                'title_ar' => 'عملية شراء من ' . $children->name,
                'title_en' => 'Purchase from ' . $children->name,
                'description_ar' => 'تم اتمام عملية شراء بقيمة ' . $data['total'] . ' ريال سعودي',
                'description_en' => 'Purchase process completed with ' . $data['total'] . ' SAR',

            ]);
            if ($children->remainingCashToday() - $data['total'] <= 0) {
                $this->notificationService->create([
                    'target' => $parentId,
                    'user_id' => $parentId,
                    'title_ar' => 'استهلاك الحد اليومي',
                    'title_en' => 'Consumption of the daily limit',
                    'description_ar' => 'قام ' . $children->name . ' باستهلاك الحد اليومي ',
                    'description_en' => ' ' . $children->name . ' has consumed the daily limit ',

                ]);
            }
            if ($parent->wallet - $data['total'] <= 0) {
                $this->notificationService->create([
                    'target' => $parentId,
                    'user_id' => $parentId,
                    'title_ar' => 'رصيد ',
                    'title_en' => ' balance',
                    'description_ar' => 'لقد انتهى الرصيد الخاص بك',
                    'description_en' => 'Your balance has been depleted',

                ]);
            }
            $this->userService->update(['wallet' => $parent->wallet - $data['total'], 'unread_notification' => $parent->unread_notification + 1], $parentId);
            $this->paymentLogService->create(
                [
                    'canteen_id' => $canteen_id,
                    'status' => PaymentLogStatusEnum::PLUS->value,
                    'acc_status' => PaymentLogAccStatusEnum::CANTEEN->value,
                    'price' => $total,
                    'order_id' => $order->id,

                ]
            );
            // Attach products to order
            foreach ($request['products'] as $item) {
                $product = $this->productService->getItem($item['product_id'])['ar'];
                // dd($product->cost * $item['count']);
                $this->productService->createStock([
                    'status'=>ProductStockStatusEnum::MINUS->value,
                    'count'=>$item['count'],
                    'price'=>$product->cost * $item['count'],
                    'canteen_id'=>$order->canteen_id,
                    'product_id'=>$item['product_id'],
                    'category_id'=>$product->category_id,
                    'date'=>date('Y-m-d')
                ]);
                $this->orderRepository->createOrderProduct([
                    'order_id' => $order->id,
                    'product_id' => $item['product_id'],
                    'count' => $item['count'],
                    'product_cost' => $product->cost,
                    'product_total' => $product->cost * $item['count'],
                ]);
                $this->productService->updateMain(['count' => $product->count - $item['count']], $item['product_id']);
                if ($product->count - $item['count'] <= 0) {
                    $this->notificationService->create([
                        'target' => auth()->user()->id,
                        'user_id' => auth()->user()->id,
                        'title_ar' => 'تم نفاذ الكمية من المنتج ( ' . $product->title . ' )',
                        'title_en' => 'The quantity of the product (' . $product->title . ') has run out',
                        'description_ar' => 'يرجى تحديث المخزون أو مراجعة الخيارات المتاحة. شكراً لتعاونكم!',
                        'description_en' => 'Please update the stock or review the available options. Thank you for your cooperation!',

                    ]);
                }
            }

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