<?php

namespace App\Repositories;

use App\Models\SalesOrder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;

class SalesOrderRepository extends BaseRepository
{
    protected function resolveModel(): Model
    {
        return new SalesOrder();
    }

    /**
     * Get all sales orders with relations
     */
    public function getAllWithRelations(): Collection
    {
        return $this->with(['items', 'customer', 'quotation', 'routeCard'])
            ->orderBy('sales_order_date', 'desc')
            ->all();
    }

    /**
     * Get sales orders by customer
     */
    public function getByCustomer(int $customerId): Collection
    {
        return $this->where('company_name', $customerId)
            ->orderBy('sales_order_date', 'desc')
            ->all();
    }

    /**
     * Get sales orders by quotation
     */
    public function getByQuotation(string $quotationNo): ?SalesOrder
    {
        return SalesOrder::where('quotation_no', $quotationNo)->first();
    }

    /**
     * Get sales orders by status
     */
    public function getByStatus(string $status): Collection
    {
        return $this->where('status', $status)->orderBy('sales_order_date', 'desc')->all();
    }

    /**
     * Get active sales orders (not completed/cancelled)
     */
    public function getActive(): Collection
    {
        return SalesOrder::whereNotIn('status', ['Completed', 'Cancelled'])
            ->with(['items', 'customer'])
            ->orderBy('sales_order_date', 'desc')
            ->get();
    }

    /**
     * Get sales orders by date range
     */
    public function getByDateRange(string $startDate, string $endDate): Collection
    {
        return $this->whereBetween('sales_order_date', [$startDate, $endDate])->all();
    }

    /**
     * Get latest sales order number
     */
    public function getLatestSalesOrderNumber(): ?string
    {
        return SalesOrder::orderBy('id', 'desc')->value('sales_order_no');
    }

    /**
     * Check if sales order number exists
     */
    public function salesOrderNumberExists(string $salesOrderNo): bool
    {
        return SalesOrder::where('sales_order_no', $salesOrderNo)->exists();
    }

    /**
     * Get sales orders for DataTable
     */
    public function getForDataTableWithRelations()
    {
        return SalesOrder::with(['items', 'customer', 'routeCard'])->latest('sales_order_date');
    }

    /**
     * Get sales orders without route card
     */
    public function getWithoutRouteCard(): Collection
    {
        return SalesOrder::doesntHave('routeCard')
            ->with('customer')
            ->orderBy('sales_order_date', 'desc')
            ->get();
    }

    /**
     * Search sales orders
     */
    public function search(string $term): Collection
    {
        return SalesOrder::where('sales_order_no', 'like', "%{$term}%")
            ->orWhere('description', 'like', "%{$term}%")
            ->orWhere('part_no', 'like', "%{$term}%")
            ->with('customer')
            ->get();
    }

    /**
     * Update status
     */
    public function updateStatus(int $id, string $status): SalesOrder
    {
        $salesOrder = $this->findOrFail($id);
        $salesOrder->update(['status' => $status]);
        return $salesOrder->fresh();
    }
}
