<?php

namespace App\Services\Manufacturing;

use App\Services\BaseService;
use App\Services\DocumentNumberService;
use App\Repositories\QualityControlRepository;
use App\Models\QualityControl;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class QualityControlService extends BaseService
{
    protected QualityControlRepository $qcRepository;
    protected DocumentNumberService $documentService;

    public function __construct(QualityControlRepository $repository, DocumentNumberService $documentService)
    {
        parent::__construct($repository);
        $this->qcRepository = $repository;
        $this->documentService = $documentService;
    }

    /**
     * Generate next QC number
     */
    public function generateQcNumber(): string
    {
        return $this->documentService->generateQcNumber();
    }

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

    /**
     * Get pending QC inspections
     */
    public function getPending(): Collection
    {
        return $this->qcRepository->getPending();
    }

    /**
     * Get failed QC
     */
    public function getFailed(): Collection
    {
        return $this->qcRepository->getFailed();
    }

    /**
     * Get QC by route card
     */
    public function getByRouteCard(int $routeCardId): Collection
    {
        return $this->qcRepository->getByRouteCard($routeCardId);
    }

    /**
     * Create QC inspection
     */
    public function createInspection(array $data): QualityControl
    {
        return DB::transaction(function () use ($data) {
            // Auto-generate QC number if not provided
            if (empty($data['qc_no'])) {
                $data['qc_no'] = $this->generateQcNumber();
            }
            $data['status'] = $data['status'] ?? QualityControl::STATUS_PENDING;
            $data['inspected_by'] = $data['inspected_by'] ?? auth()->id();

            $qc = $this->create($data);
            $this->logAction('QC inspection created', ['id' => $qc->id, 'qc_no' => $qc->qc_no]);
            return $qc;
        });
    }

    /**
     * Approve QC (mark as passed)
     */
    public function approve(int $id, ?string $remarks = null): QualityControl
    {
        return DB::transaction(function () use ($id, $remarks) {
            $qc = $this->findByIdOrFail($id);
            $qc->update([
                'status' => QualityControl::STATUS_APPROVED,
                'result' => QualityControl::RESULT_PASS,
                'remarks' => $remarks,
                'inspected_at' => now(),
                'inspected_by' => auth()->id(),
            ]);
            $this->logAction('QC passed', ['id' => $id, 'qc_no' => $qc->qc_no]);
            return $qc->fresh();
        });
    }

    /**
     * Reject QC (mark as failed)
     */
    public function reject(int $id, string $remarks): QualityControl
    {
        return DB::transaction(function () use ($id, $remarks) {
            $qc = $this->findByIdOrFail($id);
            $qc->update([
                'status' => QualityControl::STATUS_REJECTED,
                'result' => QualityControl::RESULT_FAIL,
                'remarks' => $remarks,
                'inspected_at' => now(),
                'inspected_by' => auth()->id(),
            ]);
            $this->logAction('QC failed', ['id' => $id, 'qc_no' => $qc->qc_no]);
            return $qc->fresh();
        });
    }

    /**
     * Mark QC as conditional pass
     */
    public function conditionalPass(int $id, string $remarks): QualityControl
    {
        return DB::transaction(function () use ($id, $remarks) {
            $qc = $this->findByIdOrFail($id);
            $qc->update([
                'status' => QualityControl::STATUS_APPROVED,
                'result' => QualityControl::RESULT_CONDITIONAL,
                'remarks' => $remarks,
                'inspected_at' => now(),
                'inspected_by' => auth()->id(),
            ]);
            $this->logAction('QC conditional pass', ['id' => $id, 'qc_no' => $qc->qc_no]);
            return $qc->fresh();
        });
    }

    /**
     * Update QC status
     */
    public function updateStatus(int $id, string $status): QualityControl
    {
        return DB::transaction(function () use ($id, $status) {
            $qc = $this->findByIdOrFail($id);
            $qc->update(['status' => $status]);
            return $qc->fresh();
        });
    }
}
