<?php

namespace App\Http\Controllers\ActivityLogs;

use Carbon\Carbon;
use App\Models\ActivityLog;
use Illuminate\Http\Request;
use Yajra\DataTables\DataTables;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Routing\Controllers\HasMiddleware;

class ActivityLogController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('permission:activity_log.view', only: ['index', 'dataTable', 'getUserIp', 'formatMeta', 'getUsers', 'getActivityLogKey']),
        ];
    }

    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $logUsers = ActivityLog::select('user_id', DB::raw('MAX(created_at) as latest_activity'))->with(['user'])->groupBy('user_id')->get();
        $logUsers->load('user'); // Eager load the user relationship

        $modules = ActivityLog::selectRaw('DISTINCT(activity_logs.module)')->get();

        $logKeys = ActivityLog::select('activity', DB::raw('MAX(created_at) as latest_activity'))->groupBy('activity')->get();

        return view('activity-logs.index', compact('logUsers', 'logKeys', 'modules'));
    }

    public function dataTable(Request $request)
    {
        // Parse and format the input dates to MySQL datetime format
        $startDate = $request->input('start_date') ? Carbon::parse($request->input('start_date'))->format('Y-m-d') : now()->startOfMonth()->format('Y-m-d');
        $endDate = $request->input('end_date') ? Carbon::parse($request->input('end_date'))->format('Y-m-d') : now()->endOfMonth()->format('Y-m-d');

        $activities = ActivityLog::when($startDate && $endDate, function ($query) use ($startDate, $endDate) {
            $query->whereDate('created_at', '>=', $startDate)
                ->whereDate('created_at', '<=', $endDate);
        })->when($request->input('log_user') && $request->input('log_user') != 'all', function ($query) {
            $query->whereRelation('user', 'uuid', request()->input('log_user'));
        })->when($request->input('log_module') && $request->input('log_module') != 'all', function ($query) {
            $query->where('module', request()->input('log_module'));
        })->when($request->input('activity_key') && $request->input('activity_key') != 'all', function ($query) {
            $query->where('activity', request()->input('activity_key'));
        })->orderBy('id', 'desc')->get();

        $dt = DataTables::of($activities);

        $dt->addColumn('user', function ($row) {
            return canEmpty($row->user?->full_name);
        });

        $dt->addColumn('role', function ($row) {
            return $row->user?->getRolesBadges();
        });

        $dt->addColumn('module', function ($row) {
            return ucwords(str_replace('_', ' ', $row->module));
        });

        $dt->addColumn('activity', function ($row) {
            return ucfirst(str_replace('_', ' ', $row->activity));
        });

        $dt->addColumn('ip', function ($row) {
            return $this->getUserIp(json_decode($row->meta, true));
        });

        $dt->addColumn('meta', function ($row) {
            return $this->formatMeta(json_decode($row->meta, true));
        });

        $dt->addColumn('activity_performed_at', function ($row) {
            return dbDate($row->created_at);
        });

        return $dt->rawColumns(['user', 'role', 'module', 'activity', 'meta'])->make(true);
    }

    private function getUserIp($info)
    {
        if (!is_array($info)) {
            return '';
        }

        $ip = '';
        foreach ($info as $key => $value) {
            return $ip .= $value;
        }

        return $ip;
    }

    private function formatMeta($info)
    {
        if (!is_array($info)) {
            return '';
        }

        $metaString = '<p>';
        foreach ($info as $key => $value) {
            if (is_array($value)) {
                foreach ($value as $subKey => $subValue) {
                    $metaString .= htmlspecialchars((string)$subValue);
                }
            }
        }
        $metaString .= '</p>';

        return $metaString;
    }

    public function getUsers(Request $request)
    {
        try {
            // Parse and format the input dates to MySQL datetime format
            $startDate = $request->input('start_date') ? Carbon::parse($request->input('start_date'))->format('Y-m-d') : now()->startOfMonth()->format('Y-m-d');
            $endDate = $request->input('end_date') ? Carbon::parse($request->input('end_date'))->format('Y-m-d') : now()->endOfMonth()->format('Y-m-d');

            // Ensure both dates are provided
            if ($startDate && $endDate) {
                // Fetch user IDs with the latest activity within the date range
                $logUsers = ActivityLog::select('user_id', DB::raw('MAX(created_at) as latest_activity'))
                    ->whereDate('created_at', '>=', $startDate)
                    ->whereDate('created_at', '<=', $endDate)
                    ->groupBy('user_id')
                    ->with('user') // Eager load the user relationship
                    ->get();
            }

            return response()->json([
                'status' => JsonResponse::HTTP_OK,
                'logUsers' => $logUsers
            ], JsonResponse::HTTP_OK);
        } catch (\Exception $e) {
            return $this->jsonResponse([]);
        }
    }

    public function getModules(Request $request)
    {
        try {
            // Parse and format the input dates to MySQL datetime format
            $startDate = $request->input('start_date') ? Carbon::parse($request->input('start_date'))->format('Y-m-d') : now()->startOfMonth()->format('Y-m-d');
            $endDate = $request->input('end_date') ? Carbon::parse($request->input('end_date'))->format('Y-m-d') : now()->endOfMonth()->format('Y-m-d');

            $modules = ActivityLog::selectRaw('DISTINCT(activity_logs.module)')
                ->whereDate('created_at', '>=', $startDate)
                ->whereDate('created_at', '<=', $endDate)
                ->when($request->input('log_user') && $request->input('log_user') != 'all', function ($query) use ($request) {
                    $query->whereRelation('user', 'uuid', $request->input('log_user'));
                })->get();

            return response()->json([
                'status' => JsonResponse::HTTP_OK,
                'modules' => $modules
            ], JsonResponse::HTTP_OK);
        } catch (\Exception $e) {
            return $this->jsonResponse([]);
        }
    }

    public function getActivityLogKey(Request $request)
    {
        try {
            // Parse and format the input dates to MySQL datetime format
            $startDate = $request->input('start_date') ? Carbon::parse($request->input('start_date'))->format('Y-m-d') : now()->startOfMonth()->format('Y-m-d');
            $endDate = $request->input('end_date') ? Carbon::parse($request->input('end_date'))->format('Y-m-d') : now()->endOfMonth()->format('Y-m-d');

            $logKeys = ActivityLog::selectRaw('DISTINCT(activity_logs.activity)')
                ->whereDate('created_at', '>=', $startDate)
                ->whereDate('created_at', '<=', $endDate)
                ->when($request->input('log_user') && $request->input('log_user') != 'all', function ($query) use ($request) {
                    $query->whereRelation('user', 'uuid', $request->input('log_user'));
                })
                ->when($request->input('log_module') && $request->input('log_module') != 'all', function ($query) use ($request) {
                    $query->where('module', $request->input('log_module'));
                })
                ->get();

            return response()->json([
                'status' => JsonResponse::HTTP_OK,
                'logKeys' => $logKeys
            ], JsonResponse::HTTP_OK);
        } catch (\Exception $e) {
            return $this->jsonResponse([]);
        }
    }
}
