<?php

namespace App\Services\Sales;

use App\Services\BaseService;
use App\Repositories\RfqRepository;
use App\Models\Rfq;
use App\Models\RfqFile;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;

class RfqService extends BaseService
{
    protected RfqRepository $rfqRepository;

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

    /**
     * Get all RFQs with customer info
     */
    public function getAllWithCustomer(): Collection
    {
        return $this->rfqRepository->getAllWithCustomer();
    }

    /**
     * Get RFQs by customer
     */
    public function getByCustomer(int $customerId): Collection
    {
        return $this->rfqRepository->getByCustomer($customerId);
    }

    /**
     * Get RFQs by type
     */
    public function getByType(string $type): Collection
    {
        return $this->rfqRepository->getByType($type);
    }

    /**
     * Get RFQs by date range
     */
    public function getByDateRange(string $startDate, string $endDate): Collection
    {
        return $this->rfqRepository->getByDateRange($startDate, $endDate);
    }

    /**
     * Create RFQ with files
     */
    public function createWithFiles(array $data, array $files = []): Rfq
    {
        return DB::transaction(function () use ($data, $files) {
            // Generate RFQ number if not provided
            if (empty($data['rfq_no'])) {
                $data['rfq_no'] = $this->generateRfqNumber();
            }

            $rfq = $this->rfqRepository->create($data);

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

            $this->logAction('created RFQ', ['rfq_id' => $rfq->id, 'rfq_no' => $rfq->rfq_no]);

            return $rfq;
        });
    }

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

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

            $this->logAction('updated RFQ', ['rfq_id' => $rfq->id, 'rfq_no' => $rfq->rfq_no]);

            return $rfq;
        });
    }

    /**
     * Delete RFQ and associated files
     */
    public function deleteWithFiles(int $id): bool
    {
        return DB::transaction(function () use ($id) {
            $rfq = $this->rfqRepository->findOrFail($id);

            // Delete associated files
            foreach ($rfq->rfqFiles as $file) {
                Storage::delete($file->file_path);
                $file->delete();
            }

            $this->logAction('deleted RFQ', ['rfq_id' => $rfq->id, 'rfq_no' => $rfq->rfq_no]);

            return $this->rfqRepository->delete($id);
        });
    }

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

    /**
     * Upload files for RFQ
     */
    protected function uploadFiles(Rfq $rfq, array $files): void
    {
        foreach ($files as $file) {
            if ($file instanceof UploadedFile) {
                $path = $file->store('rfq-files', 'public');
                RfqFile::create([
                    'rfq_id' => $rfq->id,
                    'file_name' => $file->getClientOriginalName(),
                    'file_path' => $path,
                    'file_type' => $file->getMimeType(),
                ]);
            }
        }
    }

    /**
     * Delete a specific file
     */
    public function deleteFile(int $fileId): bool
    {
        $file = RfqFile::findOrFail($fileId);
        Storage::delete($file->file_path);
        return $file->delete();
    }

    /**
     * Get for DataTable
     */
    public function getForDataTable()
    {
        return $this->rfqRepository->getForDataTableWithRelations();
    }

    /**
     * Search RFQs
     */
    public function search(string $term): Collection
    {
        return $this->rfqRepository->search($term);
    }

    /**
     * Get RFQs available for quotation
     */
    public function getAvailableForQuotation(): Collection
    {
        // This could be enhanced with business logic
        // e.g., RFQs that don't already have quotations
        return $this->getAllWithCustomer();
    }
}
