<?php

namespace App\Services\MasterData;

use App\Services\BaseService;
use App\Repositories\MachineRepository;
use App\Models\Machines;
use App\Models\MachineLog;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class MachineService extends BaseService
{
    protected MachineRepository $machineRepository;

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

    /**
     * Get with process
     */
    public function getAllWithProcess(): Collection
    {
        return $this->machineRepository->getWithProcess();
    }

    /**
     * Get by process
     */
    public function getByProcess(int $processId): Collection
    {
        return $this->machineRepository->getByProcess($processId);
    }

    /**
     * Get active machines
     */
    public function getActive(): Collection
    {
        return $this->machineRepository->getActive();
    }

    /**
     * Get available machines
     */
    public function getAvailable(): Collection
    {
        return $this->machineRepository->getAvailable();
    }

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

    /**
     * Generate machine code
     */
    public function generateMachineCode(): string
    {
        return nextNumber('MCH', 'machines', 'machine_code', 1);
    }

    /**
     * Log machine activity
     */
    public function logActivity(int $machineId, string $activity, ?string $remarks = null): MachineLog
    {
        return MachineLog::create([
            'machine_id' => $machineId,
            'activity' => $activity,
            'remarks' => $remarks,
            'logged_by' => auth()->id(),
            'logged_at' => now(),
        ]);
    }

    /**
     * Start machine
     */
    public function start(int $id): Machines
    {
        return DB::transaction(function () use ($id) {
            $machine = $this->findByIdOrFail($id);
            $machine->update([
                'is_running' => true,
                'started_at' => now(),
            ]);
            $this->logActivity($id, 'started');
            $this->logAction('Machine started', ['id' => $id]);
            return $machine->fresh();
        });
    }

    /**
     * Stop machine
     */
    public function stop(int $id): Machines
    {
        return DB::transaction(function () use ($id) {
            $machine = $this->findByIdOrFail($id);
            $machine->update([
                'is_running' => false,
                'stopped_at' => now(),
            ]);
            $this->logActivity($id, 'stopped');
            $this->logAction('Machine stopped', ['id' => $id]);
            return $machine->fresh();
        });
    }

    /**
     * Report breakdown
     */
    public function reportBreakdown(int $id, string $reason): Machines
    {
        return DB::transaction(function () use ($id, $reason) {
            $machine = $this->findByIdOrFail($id);
            $machine->update([
                'status' => 'breakdown',
                'is_running' => false,
            ]);
            $this->logActivity($id, 'breakdown', $reason);
            $this->logAction('Machine breakdown reported', ['id' => $id]);
            return $machine->fresh();
        });
    }

    /**
     * Get machine logs
     */
    public function getLogs(int $machineId): Collection
    {
        return MachineLog::where('machine_id', $machineId)
            ->orderBy('logged_at', 'desc')
            ->get();
    }
}
