<?php

namespace App\Http\Controllers\Workflow;

use App\Http\Controllers\Controller;
use App\Models\WorkflowTask;
use Illuminate\Http\Request;

class WorkflowTaskController extends Controller
{
    public function index(Request $request)
    {
        // List all tasks for the current user (by role or direct assignment)
        $user = $request->user();
    $tasks = WorkflowTask::where(function($q) use ($user) {
        $q->where('assigned_user', $user->id)
          ->orWhere('assigned_role', $user->role_id); // Adjust if user has multiple roles
        })
        ->with(['instance', 'document', 'assignedRole', 'assignedUser', 'transition'])
        ->orderByDesc('created_at')
        ->get();
        return view('workflow.tasks.index', compact('tasks'));
    }

    public function show($id)
    {
    $task = WorkflowTask::with(['instance', 'document', 'assignedRole', 'assignedUser', 'transition'])->findOrFail($id);
        return view('workflow.tasks.show', compact('task'));
    }

    public function updateStatus(Request $request, $id)
    {
        $task = WorkflowTask::findOrFail($id);
        $request->validate([
            'status' => 'required|string',
        ]);
        $task->status = $request->status;
        $task->save();
        return redirect()->back()->with('message', 'Task status updated.');
    }

    /**
     * Move the task to the next transition, saving the comment.
     */
    public function transition(Request $request, $id)
    {
        $task = WorkflowTask::with(['transition', 'workflow', 'document'])->findOrFail($id);

        // Prevent duplicate first tasks: check if this is the first task for the instance/document/workflow/transition/step
        $isFirstTask = false;
        $firstTransition = $task->workflow->transitions->sortBy('id')->first();
        $initialStep = $task->workflow->steps->sortBy('order')->first();
        if ($firstTransition && $initialStep) {
            $isFirstTask = (
                $task->transition_id == $firstTransition->id &&
                $task->step_id == $initialStep->id
            );
        }

        // If this is the first task, ensure there are no duplicates
        if ($isFirstTask) {
            $duplicateFirstTask = \App\Models\WorkflowTask::where([
                'instance_id' => $task->instance_id,
                'document_id' => $task->document_id,
                'workflow_id' => $task->workflow_id,
                'transition_id' => $firstTransition->id,
                'step_id' => $initialStep->id,
            ])->where('id', '!=', $task->id)->first();
            if ($duplicateFirstTask) {
                // Remove duplicate
                $duplicateFirstTask->delete();
            }
            // You can add any custom logic for the first task here
            \Log::debug('First workflow task handled (no duplicates)', ['task_id' => $task->id]);
        }

        $request->validate([
            'comment' => 'nullable|string',
            'transition_id' => 'required|integer|exists:workflow_transitions,id',
        ]);

        \Log::debug('Transition called', ['task_id' => $task->id, 'step_id' => $task->step_id, 'status' => $task->status]);

        $selectedTransition = $task->workflow->transitions->where('id', $request->transition_id)->first();

        \Log::debug('Transition selection debug', [
            'request_transition_id' => $request->transition_id,
            'selected_transition' => $selectedTransition,
            'all_transition_ids' => $task->workflow->transitions->pluck('id'),
        ]);
        if (!$selectedTransition) {
            \Log::debug('No valid transition found', ['task_id' => $task->id]);
            return redirect()->back()->with('message', 'No valid transition found.');
        }

        // Find the next transition for the next step
        $nextTransition = $task->workflow->transitions->where('from_step_id', $selectedTransition->to_step_id)->first();

        // Robustly decode user_ids and role_ids for assignment (from next transition)
        $rawUserIds = $nextTransition ? $nextTransition->user_ids : null;
        $rawRoleIds = $nextTransition ? $nextTransition->role_ids : null;
        $userIds = [];
        $roleIds = [];
        if (is_array($rawUserIds)) {
            $userIds = $rawUserIds;
        } elseif (is_string($rawUserIds) && strlen($rawUserIds) > 0) {
            $decoded = json_decode($rawUserIds, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $userIds = $decoded;
            }
        }
        if (is_array($rawRoleIds)) {
            $roleIds = $rawRoleIds;
        } elseif (is_string($rawRoleIds) && strlen($rawRoleIds) > 0) {
            $decoded = json_decode($rawRoleIds, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $roleIds = $decoded;
            }
        }
        $assignedRole = (count($roleIds) > 0) ? $roleIds[0] : null;
        $assignedUser = (count($userIds) > 0) ? $userIds[0] : null;

        // Guard against stale references (a user/role that was deleted): assigning a
        // non-existent id would violate the foreign key and crash the request. Drop it.
        if ($assignedUser !== null && !\App\Models\User::whereKey($assignedUser)->exists()) {
            \Log::warning('Workflow transition references a missing user; clearing assignment', ['assigned_user' => $assignedUser, 'transition_id' => $nextTransition ? $nextTransition->id : null]);
            $assignedUser = null;
        }
        if ($assignedRole !== null && !\Spatie\Permission\Models\Role::whereKey($assignedRole)->exists()) {
            \Log::warning('Workflow transition references a missing role; clearing assignment', ['assigned_role' => $assignedRole, 'transition_id' => $nextTransition ? $nextTransition->id : null]);
            $assignedRole = null;
        }

        \Log::debug('Next transition assignment debug', [
            'next_transition_id' => $nextTransition ? $nextTransition->id : null,
            'raw_user_ids' => $rawUserIds,
            'decoded_user_ids' => $userIds,
            'raw_role_ids' => $rawRoleIds,
            'decoded_role_ids' => $roleIds,
            'assignedUser' => $assignedUser,
            'assignedRole' => $assignedRole,
        ]);

        $nextStepName = null;
        if ($selectedTransition->to_step_id) {
            $nextStep = \App\Models\WorkflowStep::find($selectedTransition->to_step_id);
            $nextStepName = $nextStep ? $nextStep->name : null;
        }


        // Complete current task — record the transition the user actually chose,
        // so the task history shows the action performed AT this step (not the
        // transition that created/reached the task). This keeps the sequence correct.
        $task->comment = $request->comment;
        $task->status = 'completed';
        $task->transition_id = $selectedTransition->id;
        $task->save();

        // Check if a task for the next transition/step already exists
        $existingNextTask = \App\Models\WorkflowTask::where([
            'instance_id' => $task->instance_id,
            'document_id' => $task->document_id,
            'workflow_id' => $task->workflow_id,
            'transition_id' => $selectedTransition->id,
            'step_id' => $selectedTransition->to_step_id,
        ])->first();

        $nextTaskData = [
            'assigned_role' => $assignedRole,
            'assigned_user' => $assignedUser,
            'status' => $selectedTransition->is_end ? 'completed' : 'in_progress',
          
        ];

        if ($selectedTransition->is_end) {
            // The task we just completed already records the final action (its transition
            // is_end + status completed makes it show "Workflow Complete"). Creating a
            // separate marker task at the end step produced a duplicate "Approve …
            // Workflow Complete" row, so we no longer create it — we just mark the
            // workflow instance as completed.
            \App\Models\WorkflowInstance::where('id', $task->instance_id)->update(['status' => 'completed']);
            \Log::debug('Workflow completed', ['instance_id' => $task->instance_id, 'final_task_id' => $task->id]);
            return redirect()->back()->with(['message' => 'Workflow completed.', 'workflow_completed' => true]);
        }

        if ($existingNextTask) {
            $existingNextTask->update($nextTaskData);
            \Log::debug('Next task updated', ['next_task_id' => $existingNextTask->id]);
        } else {
            $newTask = \App\Models\WorkflowTask::create(array_merge($nextTaskData, [
                'instance_id' => $task->instance_id,
                'document_id' => $task->document_id,
                'workflow_id' => $task->workflow_id,
                'transition_id' => $selectedTransition->id,
                'step_id' => $selectedTransition->to_step_id,
            ]));
            \Log::debug('New task created', ['new_task_id' => $newTask->id]);
        }
        return redirect()->back()->with('message', 'Transition "' . $selectedTransition->name . '" started.');
    }
}

