<?php

namespace App\Http\Controllers;

use App\Models\TimeEntry;
use App\Models\StaffTaskType;
use App\Models\Job;
use App\Models\JobEmployeeTaskAssignment;
use Illuminate\Http\Request;
use Carbon\Carbon;

class TimesheetController extends Controller
{
    public function index()
    {
        $user        = auth()->user();
        $isTrades    = $user->role?->name === 'trades';
        $isProcessor = $user->role?->name === 'processor';
        $isEmployee  = $user->role?->name === 'factory_employee';

        if ($isProcessor) {
            $taskTypes = StaffTaskType::where('is_active', true)->where('task_category', 'processor')->orderBy('name')->get();
        } elseif ($isEmployee) {
            $taskTypes = StaffTaskType::where('is_active', true)->where('task_category', 'employee')->orderBy('name')->get();
        } else {
            $taskTypes = StaffTaskType::where('is_active', true)->orderBy('name')->get();
        }

        // For factory_employee: only show jobs where they have assigned tasks
        if ($isEmployee) {
            $assignedJobIds = JobEmployeeTaskAssignment::where('user_id', $user->id)
                ->pluck('job_id')
                ->unique();

            $jobs = Job::with(['contact'])
                ->whereIn('id', $assignedJobIds)
                ->where('stage', 'processing')
                ->orderBy('job_number')
                ->get();

            // Build a map of job_id -> [task_type_id, ...] for dynamic filtering in the view
            $assignments = JobEmployeeTaskAssignment::where('user_id', $user->id)
                ->whereIn('job_id', $assignedJobIds)
                ->get();

            $jobTaskMap = [];
            foreach ($assignments as $a) {
                $jobTaskMap[$a->job_id][] = $a->task_type_id;
            }

            // All employee task types as array for JS
            $allTaskTypesJson = $taskTypes->map(fn($t) => ['id' => $t->id, 'name' => $t->name])->values();

        } elseif ($isTrades) {
            $jobs = $user->assignedJobs()
                ->where('status', '!=', 'completed')
                ->orderBy('job_number')
                ->get();
            $jobTaskMap      = null;
            $allTaskTypesJson = null;
        } elseif ($isProcessor) {
            $jobs = Job::with(['contact', 'consultant', 'manager'])
                ->whereHas('checkMeasures', fn($q) => $q->where('status', 'completed'))
                ->where('stage', 'processing')
                ->orderBy('job_number', 'desc')
                ->get();
            $jobTaskMap      = null;
            $allTaskTypesJson = null;
        } else {
            $jobs = Job::whereIn('status', ['active'])->orderBy('job_number')->get();
            $jobTaskMap      = null;
            $allTaskTypesJson = null;
        }

        // Running timer (if any)
        $running = TimeEntry::where('user_id', $user->id)
            ->where('status', 'running')
            ->with('taskType', 'job')
            ->first();

        // Recent entries
        $entries = TimeEntry::where('user_id', $user->id)
            ->with('taskType', 'job')
            ->orderByDesc('started_at')
            ->paginate(20);

        // Weekly summary
        $weekStart     = Carbon::now()->startOfWeek();
        $weeklyEntries = TimeEntry::where('user_id', $user->id)
            ->where('started_at', '>=', $weekStart)
            ->where('status', '!=', 'running')
            ->get();
        $weeklyHours    = $weeklyEntries->sum('duration_minutes') / 60;
        $weeklyEarnings = $weeklyHours * ($user->hourly_rate ?? 0);

        return view('timesheet.index', compact(
            'taskTypes', 'jobs', 'running', 'entries', 'weeklyHours', 'weeklyEarnings',
            'jobTaskMap', 'allTaskTypesJson'
        ));
    }

    public function start(Request $request)
    {
        $user      = auth()->user();
        $isTrades  = $user->role?->name === 'trades';
        $isEmployee = $user->role?->name === 'factory_employee';

        // Stop any running timer first
        TimeEntry::where('user_id', $user->id)->where('status', 'running')->each(function ($entry) {
            $mins = $entry->started_at->diffInMinutes(now());
            $entry->update([
                'stopped_at'       => now(),
                'duration_minutes' => $mins,
                'status'           => 'completed',
            ]);
        });

        $data = $request->validate([
            'task_type_id' => $isTrades ? 'nullable|exists:staff_task_types,id' : 'required|exists:staff_task_types,id',
            'job_id'       => 'required|exists:crm_jobs,id',
            'notes'        => 'nullable|string|max:500',
        ], [
            'task_type_id.required' => 'Please select a task type before starting the timer.',
            'job_id.required'       => 'Please select a job before starting the timer.',
        ]);

        // Trades users: validate the job is actually assigned to them
        if ($isTrades) {
            $assigned = $user->assignedJobs()
                ->where('crm_jobs.id', $data['job_id'])
                ->exists();
            if (! $assigned) {
                return back()->with('error', 'You can only start a timer for jobs assigned to you.');
            }

            $job = Job::findOrFail($data['job_id']);
            if ($job->status === 'completed') {
                return back()->with('error', 'Cannot start a timer for a completed job.');
            }
        }

        // Factory employee: validate the task is assigned to them for this job
        if ($isEmployee && $data['task_type_id']) {
            $validAssignment = JobEmployeeTaskAssignment::where('user_id', $user->id)
                ->where('job_id', $data['job_id'])
                ->where('task_type_id', $data['task_type_id'])
                ->exists();
            if (! $validAssignment) {
                return back()->with('error', 'This task is not assigned to you for the selected job.');
            }
        }

        TimeEntry::create([
            'user_id'      => $user->id,
            'task_type_id' => $data['task_type_id'] ?? null,
            'job_id'       => $data['job_id'] ?? null,
            'started_at'   => now(),
            'status'       => 'running',
            'notes'        => $data['notes'] ?? null,
        ]);

        return back()->with('success', 'Timer started.');
    }

    public function stop(Request $request)
    {
        $user  = auth()->user();
        $entry = TimeEntry::where('user_id', $user->id)->where('status', 'running')->first();
        if ($entry) {
            $mins = $entry->started_at->diffInMinutes(now());
            $entry->update([
                'stopped_at'       => now(),
                'duration_minutes' => $mins,
                'status'           => 'completed',
            ]);
            return back()->with('success', 'Timer stopped. ' . $entry->elapsed . ' recorded.');
        }
        return back()->with('error', 'No running timer found.');
    }

    public function destroy(TimeEntry $entry)
    {
        $user = auth()->user();
        if ($entry->user_id !== $user->id && $user->role?->name !== 'office_admin') {
            abort(403);
        }
        $entry->delete();
        return back()->with('success', 'Entry deleted.');
    }

    // Admin: view all timesheets
    public function admin()
    {
        $entries = TimeEntry::with('user', 'taskType', 'job')
            ->orderByDesc('started_at')
            ->paginate(50);

        $users = \App\Models\User::with('role')
            ->whereHas('role', fn($q) => $q->whereIn('name', ['factory_employee', 'trades', 'processor']))
            ->orderBy('name')
            ->get();

        return view('timesheet.admin', compact('entries', 'users'));
    }
}
