<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Task;
use App\Models\TaskActivity;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class TaskController extends Controller
{
    /**
     * Display a listing of tasks with filters
     */
    public function index(Request $request)
    {
        try {
            $query = Task::with(['assignedUser', 'createdByUser', 'client', 'clientBranch', 'activities' => function($q) {
                $q->latest();
            }]);

            // Apply filters
            if ($request->has('status') && $request->status !== 'All') {
                $query->where('status', $request->status);
            }

            if ($request->has('priority') && $request->priority !== 'All') {
                $query->where('priority', $request->priority);
            }

            if ($request->has('assigned_to') && $request->assigned_to !== 'All') {
                $query->where('assigned_to', $request->assigned_to);
            }

            if ($request->has('client_id') && $request->client_id !== 'All') {
                $query->where('client_id', $request->client_id);
            }

            if ($request->has('search') && !empty($request->search)) {
                $search = $request->search;
                $query->where(function($q) use ($search) {
                    $q->where('title', 'like', "%{$search}%")
                      ->orWhere('description', 'like', "%{$search}%");
                });
            }

            // Default ordering
            $query->orderByRaw("
                CASE status
                    WHEN 'OPEN' THEN 1
                    WHEN 'IN_PROGRESS' THEN 2
                    WHEN 'BLOCKED' THEN 3
                    WHEN 'COMPLETED' THEN 4
                END
            ")->orderBy('due_date');

            $perPage = $request->has('per_page') ? $request->per_page : 10;
            $tasks = $query->paginate($perPage);

            return response()->json([
                'success' => true,
                'data' => $tasks->items(),
                'meta' => [
                    'current_page' => $tasks->currentPage(),
                    'last_page' => $tasks->lastPage(),
                    'per_page' => $tasks->perPage(),
                    'total' => $tasks->total(),
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch tasks',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Store a newly created task
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'status' => 'nullable|in:OPEN,IN_PROGRESS,BLOCKED,COMPLETED',
            'priority' => 'nullable|in:LOW,MEDIUM,HIGH',
            'due_date' => 'nullable|date',
            'assigned_to' => 'required|integer|exists:users,id',
            'client_id' => 'nullable|integer|exists:clients,id',
            'client_branch_id' => 'nullable|integer|exists:client_branches,id',
            'form_compliance_id' => 'nullable|integer|exists:form_compliance,id',
            'user_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors()
            ], 422);
        }

        try {


            $task = Task::create([
                'title' => $request->title,
                'description' => $request->description,
                'status' => $request->status ?? 'OPEN',
                'priority' => $request->priority ?? 'MEDIUM',
                'due_date' => $request->due_date,
                'assigned_to' => $request->assigned_to,
                'client_id' => $request->client_id,
                'client_branch_id' => $request->client_branch_id,
                'form_compliance_id' => $request->form_compliance_id,
            ]);

            // Create initial activity
            TaskActivity::create([
                'task_id' => $task->id,
                'user_id' => $request->user_id,
                'type' => 'STATUS_CHANGE',
                'message' => 'Task created and assigned to user ID: ' . $request->assigned_to,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Task created successfully',
                'data' => $task->load(['assignedUser', 'createdByUser'])
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create task',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Display the specified task with activities
     */
    public function show($id)
    {
        try {
            $task = Task::with([
                'assignedUser',
                'createdByUser',
                'client',
                'clientBranch',
                'activities.user',
                'formCompliance'
            ])->find($id);

            if (!$task) {
                return response()->json([
                    'success' => false,
                    'message' => 'Task not found'
                ], 404);
            }

            return response()->json([
                'success' => true,
                'data' => $task
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch task',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update the specified task
     */
    public function update(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'nullable|string|max:255',
            'description' => 'nullable|string',
            'status' => 'nullable|in:OPEN,IN_PROGRESS,BLOCKED,COMPLETED',
            'priority' => 'nullable|in:LOW,MEDIUM,HIGH',
            'due_date' => 'nullable|date',
            'assigned_to' => 'nullable|integer|exists:users,id',
            'client_id' => 'nullable|integer|exists:clients,id',
            'client_branch_id' => 'nullable|integer|exists:client_branches,id',
            'form_compliance_id' => 'nullable|integer|exists:form_compliance,id',
            'user_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $task = Task::find($id);

            if (!$task) {
                return response()->json([
                    'success' => false,
                    'message' => 'Task not found'
                ], 404);
            }

            $oldStatus = $task->status;
            $oldAssignee = $task->assigned_to;

            $task->update(array_merge(
                $request->only([
                    'title', 'description', 'status', 'priority',
                    'due_date', 'assigned_to', 'client_id',
                    'client_branch_id', 'form_compliance_id'
                ])

            ));

            // Create activity for status change
            if ($request->has('status') && $request->status !== $oldStatus) {
                TaskActivity::create([
                    'task_id' => $task->id,
                    'user_id' => $request->user_id,
                    'type' => 'STATUS_CHANGE',
                    'message' => 'Status changed from ' . $oldStatus . ' to ' . $request->status,
                ]);
            }

            // Create activity for assignee change
            if ($request->has('assigned_to') && $request->assigned_to != $oldAssignee) {
                TaskActivity::create([
                    'task_id' => $task->id,
                    'user_id' => $request->user_id,
                    'type' => 'ASSIGNEE_CHANGE',
                    'message' => 'Task reassigned from user ID: ' . $oldAssignee . ' to user ID: ' . $request->assigned_to,
                ]);
            }

            return response()->json([
                'success' => true,
                'message' => 'Task updated successfully',
                'data' => $task->load(['assignedUser', 'createdByUser', 'activities.user'])
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update task',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Remove the specified task
     */
    public function destroy(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'reason' => 'required|string|max:1000',
            'user_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $task = Task::find($id);

            if (!$task) {
                return response()->json([
                    'success' => false,
                    'message' => 'Task not found'
                ], 404);
            }


            // Create activity for deletion
            TaskActivity::create([
                'task_id' => $task->id,
                'user_id' => $request->user_id,
                'type' => 'STATUS_CHANGE',
                'message' => 'Task deleted. Reason: ' . $request->reason,
            ]);

            $task->delete();

            return response()->json([
                'success' => true,
                'message' => 'Task deleted successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete task',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get task statistics
     */
    public function statistics($userId)
    {
        try {


            $total = Task::count();
            $inProgress = Task::where('status', 'IN_PROGRESS')->count();
            $completed = Task::where('status', 'COMPLETED')->count();

            // Count overdue tasks (due_date < today)
            $overdue = Task::where('due_date', '<', now())
                ->whereNotIn('status', ['COMPLETED'])
                ->count();

            // User-specific stats
            $myTotal = Task::where('assigned_to', $userId)->count();
            $myPending = Task::where('assigned_to', $userId)
                ->whereNotIn('status', ['COMPLETED'])
                ->count();

            return response()->json([
                'success' => true,
                'data' => [
                    'overall' => [
                        'total' => $total,
                        'in_progress' => $inProgress,
                        'completed' => $completed,
                        'overdue' => $overdue,
                    ],
                    'personal' => [
                        'total' => $myTotal,
                        'pending' => $myPending,
                    ]
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch statistics',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
