<?php

namespace App\Http\Controllers;

use App\Models\Job;
use App\Models\ProcessingOrder;
use App\Models\ActivityLog;
use App\Models\User;
use App\Models\StaffTaskType;
use App\Models\JobEmployeeTaskAssignment;
use Illuminate\Http\Request;

class ProcessingController extends Controller
{
    public function index()
    {
        $user     = auth()->user();
        $isTrades = $user->role?->name === 'trades';

        $query = Job::with(['contact', 'processingOrders'])
            ->whereIn('stage', ['processing', 'delivery', 'installation']);

        if ($isTrades) {
            $query->whereHas('tradeUsers', fn($q) => $q->where('users.id', $user->id));
        }

        $jobs = $query->paginate(20);
        return view('processing.index', compact('jobs'));
    }

    public function show(Job $job)
    {
        // Trades users may only view jobs assigned to them
        $user = auth()->user();
        if ($user->role?->name === 'trades') {
            abort_unless(
                $user->assignedJobs()->where('crm_jobs.id', $job->id)->exists(),
                403
            );
        }

        $job->load([
            'contact', 'processingOrders', 'tasks',
            'employeeTaskAssignments.user', 'employeeTaskAssignments.taskType',
        ]);

        // Factory employees available to assign tasks to
        $factoryEmployees = User::whereHas('role', fn($q) => $q->where('name', 'factory_employee'))
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        // Employee task types (task_category = 'employee')
        $employeeTaskTypes = StaffTaskType::where('is_active', true)
            ->where('task_category', 'employee')
            ->orderBy('name')
            ->get();

        return view('processing.show', compact('job', 'factoryEmployees', 'employeeTaskTypes'));
    }

    public function storeOrder(Request $request, Job $job)
    {
        $data = $request->validate([
            'description' => 'required|string|max:255',
            'supplier'    => 'nullable|string|max:255',
            'order_date'  => 'nullable|date',
            'eta_date'    => 'nullable|date',
            'total_items' => 'nullable|integer|min:0',
            'notes'       => 'nullable|string',
        ]);

        $data['job_id'] = $job->id;
        $data['po_number'] = 'PO-' . str_pad((ProcessingOrder::max('id') ?? 0) + 1, 4, '0', STR_PAD_LEFT);
        $data['status'] = 'pending';
        $data['progress_pct'] = 0;
        $data['completed_items'] = 0;

        $order = ProcessingOrder::create($data);

        ActivityLog::create([
            'user_id' => auth()->id(), 'loggable_type' => 'ProcessingOrder', 'loggable_id' => $order->id,
            'action' => 'Order Created',
            'description' => "Processing order {$order->po_number} created for job {$job->job_number}",
        ]);

        return back()->with('success', "Processing order {$order->po_number} created.");
    }

    public function updateOrder(Request $request, ProcessingOrder $order)
    {
        $data = $request->validate([
            'status'          => 'required|in:pending,ordered,in_production,ready,delivered,cancelled',
            'supplier'        => 'nullable|string',
            'eta_date'        => 'nullable|date',
            'completed_items' => 'nullable|integer|min:0',
            'notes'           => 'nullable|string',
        ]);

        if (isset($data['completed_items']) && $order->total_items > 0) {
            $data['progress_pct'] = min(100, (int) round($data['completed_items'] / $order->total_items * 100));
        }

        $order->update($data);
        return back()->with('success', "Order {$order->po_number} updated.");
    }

    public function updateProgress(Request $request, ProcessingOrder $order)
    {
        $request->validate(['progress_pct' => 'required|integer|min:0|max:100']);
        $order->update(['progress_pct' => $request->progress_pct]);
        if ($request->progress_pct === 100) {
            $order->update(['status' => 'ready']);
        }
        return back()->with('success', 'Progress updated.');
    }

    /**
     * Assign an employee task type to a factory employee for this job.
     * Now accepts optional allocated_hours set by the processor.
     */
    public function assignEmployeeTask(Request $request, Job $job)
    {
        $data = $request->validate([
            'user_id'         => 'required|exists:users,id',
            'task_type_id'    => 'required|exists:staff_task_types,id',
            'allocated_hours' => 'required|numeric|min:1|max:999',
        ]);

        $exists = JobEmployeeTaskAssignment::where('job_id', $job->id)
            ->where('user_id', $data['user_id'])
            ->where('task_type_id', $data['task_type_id'])
            ->exists();

        if ($exists) {
            return back()->with('error', 'This task is already assigned to this employee for this job.');
        }

        JobEmployeeTaskAssignment::create([
            'job_id'          => $job->id,
            'user_id'         => $data['user_id'],
            'task_type_id'    => $data['task_type_id'],
            'allocated_hours' => $data['allocated_hours'] ?? null,
            'task_status'     => 'pending',
        ]);

        return back()->with('success', 'Task assigned to employee successfully.');
    }

    /**
     * Remove an employee task assignment.
     */
    public function removeEmployeeTask(JobEmployeeTaskAssignment $assignment)
    {
        $assignment->delete();
        return back()->with('success', 'Task assignment removed.');
    }
}
