<?php
declare(strict_types=1);

namespace App\Controllers\Api;

use App\Middleware\ApiToken;
use App\Middleware\TenantScope;
use App\Models\Part;
use App\Models\WorkOrder;
use Core\Controller;

final class WorkOrdersController extends Controller
{
    public function middleware(): array
    {
        return [ApiToken::class, TenantScope::class];
    }

    private function tenantId(): int { return (int) ($_SESSION['tenant_id'] ?? 0); }
    private function userId():   int { return (int) ($_SESSION['user']['user_id'] ?? 0); }

    public function index(): void
    {
        $filters = [
            'wo_type'     => $_GET['wo_type']     ?? null,
            'priority'    => $_GET['priority']    ?? null,
            'status'      => $_GET['status']      ?? null,
            'assigned_to' => $_GET['assigned_to'] ?? null,
        ];
        // Field techs typically want to see only their own — default to that
        // when the caller doesn't specify assigned_to and the caller is a tech.
        $role = $_SESSION['user']['role_code'] ?? '';
        if ($role === 'field_technician' && empty($filters['assigned_to'])) {
            $filters['assigned_to'] = $this->userId();
        }
        $this->json(['data' => WorkOrder::listForTenant($this->tenantId(), array_filter($filters))]);
    }

    public function show(int $id): void
    {
        $wo = WorkOrder::findInTenant($this->tenantId(), $id);
        if (!$wo) $this->json(['error' => 'Not found'], 404);
        $wo['tasks']         = WorkOrder::tasksFor($id);
        $wo['parts_used']    = Part::partsUsedOnWo($id);
        $wo['material_cost'] = Part::totalMaterialCostForWo($id);
        $this->json(['data' => $wo]);
    }

    public function update(int $id): void
    {
        if (!in_array(($_SERVER['REQUEST_METHOD'] ?? ''), ['POST','PUT','PATCH'], true)) {
            $this->json(['error' => 'POST/PUT/PATCH required'], 405);
        }
        $wo = WorkOrder::findInTenant($this->tenantId(), $id);
        if (!$wo) $this->json(['error' => 'Not found'], 404);
        WorkOrder::update($this->tenantId(), $id, $this->input());
        $this->json(['data' => WorkOrder::findInTenant($this->tenantId(), $id)]);
    }

    public function completeTask(int $taskId): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $task = WorkOrder::taskInTenant($this->tenantId(), $taskId);
        if (!$task) $this->json(['error' => 'Not found'], 404);
        $body = $this->input();

        $response = isset($body['response_value']) ? (string) $body['response_value'] : null;
        $note     = isset($body['note']) ? (string) $body['note'] : null;
        $remedy   = isset($body['remedy_note']) ? (string) $body['remedy_note'] : null;

        if (!empty($task['is_required']) && ($task['input_type'] ?? 'checkbox') !== 'checkbox'
            && ($response === null || $response === '')) {
            $this->json(['error' => 'response_value required for this task'], 422);
        }

        WorkOrder::completeTask($taskId, $this->userId(), $note, $response !== '' ? $response : null, $remedy);
        $this->json(['success' => true]);
    }

    /**
     * POST /api/v1/work-orders/consume-part/{woId}
     * Body: { part_id, quantity }
     * Writes the stock_movements ledger row + wo_parts_used row atomically.
     */
    public function consumePart(int $woId): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $wo = WorkOrder::findInTenant($this->tenantId(), $woId);
        if (!$wo) $this->json(['error' => 'Not found'], 404);
        $body = $this->input();
        $partId = (int) ($body['part_id'] ?? 0);
        $qty    = (float) ($body['quantity'] ?? 0);
        if ($partId <= 0 || $qty <= 0) {
            $this->json(['error' => 'part_id and quantity > 0 are required'], 422);
        }
        Part::consumeToWo($this->tenantId(), $partId, $woId, $qty, $this->userId() ?: null);
        $this->json([
            'success'         => true,
            'material_cost'   => Part::totalMaterialCostForWo($woId),
            'parts_used'      => Part::partsUsedOnWo($woId),
        ]);
    }

    public function reopenTask(int $taskId): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $task = WorkOrder::taskInTenant($this->tenantId(), $taskId);
        if (!$task) $this->json(['error' => 'Not found'], 404);
        WorkOrder::reopenTask($taskId);
        $this->json(['success' => true]);
    }
}
