<?php

namespace App\Services\Manufacturing;

use App\Services\BaseService;
use App\Repositories\RouteCardRepository;
use App\Models\RouteCard;
use App\Models\RouteCardProcess;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class RouteCardService extends BaseService
{
    protected RouteCardRepository $routeCardRepository;

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

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

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

    /**
     * Get approved route cards
     */
    public function getApproved(): Collection
    {
        return $this->routeCardRepository->getApproved();
    }

    /**
     * Get route cards in production
     */
    public function getInProduction(): Collection
    {
        return $this->routeCardRepository->getInProduction();
    }

    /**
     * Get planned route cards
     */
    public function getPlanned(): Collection
    {
        return $this->routeCardRepository->getPlanned();
    }

    /**
     * Get ready for production
     */
    public function getReadyForProduction(): Collection
    {
        return $this->routeCardRepository->getReadyForProduction();
    }

    /**
     * Create route card from sales order
     */
    public function createFromSalesOrder(int $salesOrderId, array $data, array $processes = []): RouteCard
    {
        return DB::transaction(function () use ($salesOrderId, $data, $processes) {
            $data['sales_order_id'] = $salesOrderId;
            $data['route_no'] = $this->generateRouteCardNumber();

            $routeCard = $this->create($data);

            foreach ($processes as $index => $process) {
                $process['route_card_id'] = $routeCard->id;
                $process['sequence'] = $index + 1;
                $routeCard->processes()->create($process);
            }

            $this->logAction('Route Card created', [
                'id' => $routeCard->id,
                'sales_order_id' => $salesOrderId,
            ]);

            return $routeCard->fresh(['processes']);
        });
    }

    /**
     * Add process to route card
     */
    public function addProcess(int $routeCardId, array $processData): RouteCardProcess
    {
        return DB::transaction(function () use ($routeCardId, $processData) {
            $routeCard = $this->findByIdOrFail($routeCardId);

            $lastSequence = $routeCard->processes()->max('sequence') ?? 0;
            $processData['route_card_id'] = $routeCardId;
            $processData['sequence'] = $lastSequence + 1;

            $process = RouteCardProcess::create($processData);
            $this->logAction('Process added to Route Card', [
                'route_card_id' => $routeCardId,
                'process_id' => $process->id,
            ]);

            return $process;
        });
    }

    /**
     * Update process
     */
    public function updateProcess(int $processId, array $data): RouteCardProcess
    {
        return DB::transaction(function () use ($processId, $data) {
            $process = RouteCardProcess::findOrFail($processId);
            $process->update($data);
            return $process->fresh();
        });
    }

    /**
     * Delete process
     */
    public function deleteProcess(int $processId): bool
    {
        return DB::transaction(function () use ($processId) {
            $process = RouteCardProcess::findOrFail($processId);
            return $process->delete();
        });
    }

    /**
     * Generate route card number
     */
    public function generateRouteCardNumber(): string
    {
        $year = date('Y');
        return nextNumber("RC/{$year}", 'route_cards', 'route_no', 2);
    }

    /**
     * Approve route card
     */
    public function approve(int $id): RouteCard
    {
        return DB::transaction(function () use ($id) {
            $routeCard = $this->findByIdOrFail($id);
            $routeCard->update(['status' => 'approved']);
            $this->logAction('Route Card approved', ['id' => $id]);
            return $routeCard->fresh();
        });
    }

    /**
     * Mark as planned
     */
    public function markPlanned(int $id): RouteCard
    {
        return DB::transaction(function () use ($id) {
            $routeCard = $this->findByIdOrFail($id);
            $routeCard->update(['status' => 'planned']);
            $this->logAction('Route Card marked as planned', ['id' => $id]);
            return $routeCard->fresh();
        });
    }

    /**
     * Mark as ready for production
     */
    public function markReadyForProduction(int $id): RouteCard
    {
        return DB::transaction(function () use ($id) {
            $routeCard = $this->findByIdOrFail($id);
            $routeCard->update(['status' => 'ready_for_production']);
            $this->logAction('Route Card ready for production', ['id' => $id]);
            return $routeCard->fresh();
        });
    }

    /**
     * Mark as in production
     */
    public function markInProduction(int $id): RouteCard
    {
        return DB::transaction(function () use ($id) {
            $routeCard = $this->findByIdOrFail($id);
            $routeCard->update(['status' => 'in_production']);
            $this->logAction('Route Card in production', ['id' => $id]);
            return $routeCard->fresh();
        });
    }
}
