<?php

namespace App\Services\Purchase;

use App\Services\BaseService;
use App\Repositories\PurchaseOrderRepository;
use App\Models\PurchaseOrder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;

class PurchaseOrderService extends BaseService
{
    protected PurchaseOrderRepository $orderRepository;

    public function __construct(PurchaseOrderRepository $repository)
    {
        parent::__construct($repository);
        $this->orderRepository = $repository;
    }

    /**
     * Get orders with details
     */
    public function getAllWithDetails(): Collection
    {
        return $this->orderRepository->getWithDetails();
    }

    /**
     * Get orders by vendor
     */
    public function getByVendor(int $vendorId): Collection
    {
        return $this->orderRepository->getByVendor($vendorId);
    }

    /**
     * Get pending orders for GRN
     */
    public function getPendingForGrn(): Collection
    {
        return $this->orderRepository->getPendingForGrn();
    }

    /**
     * Create order from quotation
     */
    public function createFromQuotation(int $quotationId, array $data): PurchaseOrder
    {
        return DB::transaction(function () use ($quotationId, $data) {
            $data['purchase_quotation_id'] = $quotationId;
            $data['order_no'] = $this->generateOrderNumber();

            $order = $this->create($data);
            $this->logAction('Purchase Order created from Quotation', [
                'id' => $order->id,
                'quotation_id' => $quotationId,
            ]);

            return $order;
        });
    }

    /**
     * Create order with items
     */
    public function createWithItems(array $data, array $items): PurchaseOrder
    {
        return DB::transaction(function () use ($data, $items) {
            $data['order_no'] = $this->generateOrderNumber();
            $order = $this->create($data);

            foreach ($items as $item) {
                $item['purchase_order_id'] = $order->id;
                $order->items()->create($item);
            }

            $this->calculateTotals($order);
            $this->logAction('Purchase Order created', ['id' => $order->id]);
            return $order->fresh(['items']);
        });
    }

    /**
     * Calculate order totals
     */
    public function calculateTotals(PurchaseOrder $order): void
    {
        $subtotal = $order->items->sum(function ($item) {
            return $item->quantity * $item->rate;
        });

        $gst = $subtotal * ($order->gst_percentage ?? 0) / 100;
        $total = $subtotal + $gst;

        $order->update([
            'subtotal' => $subtotal,
            'gst_amount' => $gst,
            'total' => $total,
        ]);
    }

    /**
     * Generate order number
     */
    public function generateOrderNumber(): string
    {
        $year = date('Y');
        return nextNumber("PO/{$year}", 'purchase_orders', 'order_no', 2);
    }

    /**
     * Generate PDF
     */
    public function generatePdf(int $id)
    {
        $order = $this->findByIdWith($id, ['vendor', 'items']);
        $pdf = Pdf::loadView('purchase.order.print', compact('order'));
        return $pdf->download("PO-{$order->order_no}.pdf");
    }

    /**
     * Approve order
     */
    public function approve(int $id): PurchaseOrder
    {
        return DB::transaction(function () use ($id) {
            $order = $this->findByIdOrFail($id);
            $order->update(['status' => 'approved']);
            $this->logAction('Purchase Order approved', ['id' => $id]);
            return $order->fresh();
        });
    }
}
