<?php

namespace App\Services\Purchase;

use App\Services\BaseService;
use App\Repositories\PurchaseRfqRepository;
use App\Models\PurchaseRFQ;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class PurchaseRfqService extends BaseService
{
    protected PurchaseRfqRepository $purchaseRfqRepository;

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

    /**
     * Get all RFQs with vendor
     */
    public function getAllWithVendor(): Collection
    {
        return $this->purchaseRfqRepository->getWithVendor();
    }

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

    /**
     * Get RFQs by status
     */
    public function getByStatus(string $status): Collection
    {
        return $this->purchaseRfqRepository->getByStatus($status);
    }

    /**
     * Get RFQs available for quotation
     */
    public function getAvailableForQuotation(): Collection
    {
        return $this->purchaseRfqRepository->getAvailableForQuotation();
    }

    /**
     * Create RFQ with files
     */
    public function createWithFiles(array $data, array $files = []): PurchaseRFQ
    {
        return DB::transaction(function () use ($data, $files) {
            $rfq = $this->create($data);

            if (!empty($files)) {
                $this->uploadFiles($rfq, $files);
            }

            $this->logAction('Purchase RFQ created', ['id' => $rfq->id]);
            return $rfq;
        });
    }

    /**
     * Update RFQ with files
     */
    public function updateWithFiles(int $id, array $data, array $files = []): PurchaseRFQ
    {
        return DB::transaction(function () use ($id, $data, $files) {
            $rfq = $this->update($id, $data);

            if (!empty($files)) {
                $this->uploadFiles($rfq, $files);
            }

            $this->logAction('Purchase RFQ updated', ['id' => $rfq->id]);
            return $rfq;
        });
    }

    /**
     * Generate RFQ number
     */
    public function generateRfqNumber(): string
    {
        $year = date('Y');
        return nextNumber("PRFQ/{$year}", 'purchase_rfqs', 'rfq_no', 2);
    }

    /**
     * Upload files for RFQ
     */
    protected function uploadFiles(PurchaseRFQ $rfq, array $files): void
    {
        foreach ($files as $file) {
            $path = $file->store('purchase-rfq-files', 'public');
            $rfq->files()->create([
                'file_path' => $path,
                'file_name' => $file->getClientOriginalName(),
            ]);
        }
    }

    /**
     * Delete file
     */
    public function deleteFile(int $fileId): bool
    {
        $file = \App\Models\PurchaseRFQFiles::findOrFail($fileId);
        Storage::disk('public')->delete($file->file_path);
        return $file->delete();
    }

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

    /**
     * Reject RFQ
     */
    public function reject(int $id, ?string $remarks = null): PurchaseRFQ
    {
        return DB::transaction(function () use ($id, $remarks) {
            $rfq = $this->findByIdOrFail($id);
            $rfq->update([
                'status' => 'rejected',
                'remarks' => $remarks,
            ]);
            $this->logAction('Purchase RFQ rejected', ['id' => $id]);
            return $rfq->fresh();
        });
    }
}
