<?php

namespace App\Http\Controllers\AccessControl;

use App\Services\System\ActivityFormatter;
use App\Support\DataTable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Spatie\Activitylog\Models\Activity;

class ActionLogController extends Controller
{
    public function __construct()
    {
        // Middleware handled in web.php
    }

    public function index(Request $request)
    {
        if (DataTable::isDataTableRequest($request)) {
            return $this->dataTable($request);
        }

        return view('pages.access_control.action-logs');
    }

    protected function dataTable(Request $request)
    {
        try {
            $query = Activity::query()->with('causer');

            // Fast count without eager loading or ordering
            $recordsTotal = Activity::count();

            $globalSearch = DataTable::globalSearch($request);

            if ($event = $request->input('event')) {
                if ($event === 'auth') {
                    $query->whereIn('description', ['login', 'logout', 'login_attempt', 'password_changed', 'failed login', 'password reset']);
                } elseif ($event === 'data') {
                    $query->whereIn('description', ['created', 'updated', 'deleted', 'restored', 'force deleted', 'permanent_deleted']);
                } elseif ($event === 'system') {
                    $query->whereIn('log_name', ['system', 'maintenance', 'backup']);
                }
            }

            if ($user = DataTable::columnSearch($request, 0)) {
                $query->whereHas('causer', function ($causerQuery) use ($user) {
                    $causerQuery->where(function ($q) use ($user) {
                        $q->where('name', 'like', "%{$user}%")
                            ->orWhere('email', 'like', "%{$user}%");
                    });
                });
            }

            if ($action = DataTable::columnSearch($request, 1)) {
                $query->where('description', 'like', "%{$action}%");
            }

            if ($details = DataTable::columnSearch($request, 2)) {
                $query->where('properties', 'like', "%{$details}%");
            }

            if ($module = DataTable::columnSearch($request, 3)) {
                $query->where('log_name', 'like', "%{$module}%");
            }

            if ($executedAt = DataTable::columnSearch($request, 4)) {
                $query->whereDate('created_at', $executedAt);
            }

            if ($ip = DataTable::columnSearch($request, 5)) {
                $query->where('properties->ip', 'like', "%{$ip}%");
            }

            if ($agent = DataTable::columnSearch($request, 6)) {
                $query->where('properties->agent', 'like', "%{$agent}%");
            }

            if ($properties = DataTable::columnSearch($request, 7)) {
                $query->where('properties', 'like', "%{$properties}%");
            }

            if ($globalSearch) {
                $query->where(function ($searchQuery) use ($globalSearch) {
                    $searchQuery
                        ->where('description', 'like', "%{$globalSearch}%")
                        ->orWhere('log_name', 'like', "%{$globalSearch}%")
                        ->orWhere('properties', 'like', "%{$globalSearch}%")
                        ->orWhereHas('causer', function ($causerQuery) use ($globalSearch) {
                            $causerQuery->where('email', 'like', "%{$globalSearch}%");
                        });
                });
            }

            [$orderIndex, $orderDirection] = DataTable::order($request, 4, 'desc');

            $sortColumn = match ($orderIndex) {
                0 => 'causer_type',
                1 => 'description',
                3 => 'log_name',
                4 => 'created_at',
                default => 'created_at',
            };

            // Remove old global ordering and apply datatable specific ordering
            $query->orderBy($sortColumn, $orderDirection);

            // Perform filtered count WITHOUT eager loading or ordering
            $countQuery = clone $query;
            $countQuery->setEagerLoads([]);
            $countQuery->orders = null;
            $recordsFiltered = $countQuery->count();

            $logs = $query
                ->skip(DataTable::start($request))
                ->take(DataTable::length($request))
                ->get();

            $rows = $logs->map(function (Activity $log) {
                $properties = is_array($log->properties) ? $log->properties : $log->properties?->toArray();

                $eventLabel = ucfirst($log->description);
                $eventBadge = ActivityFormatter::getEventBadgeClass($log->description);
                $eventIcon = ActivityFormatter::getEventIcon($log->description);
                $modelName = ActivityFormatter::getFriendlyModelName($log->subject_type);
                $changes = ActivityFormatter::formatChanges($properties ?? []);

                // User Column (Removed icon)
                $userHtml = '<div>
                                <div class="fw-bold small">'.e($log->causer?->name ?? 'System').'</div>
                                <div class="text-secondary extra-small">'.e($log->causer?->email ?? 'no-email').'</div>
                             </div>';

                // Event Column
                $eventHtml = '<span class="badge rounded-pill '.$eventBadge.' px-3 py-2 small">
                                <i class="bi '.$eventIcon.' me-1"></i>'.$eventLabel.'
                              </span>';

                // Information Column (Preview of changes)
                $infoHtml = '<div class="small text-truncate" style="max-width: 250px;">';
                if (! empty($changes)) {
                    $first = $changes[0];
                    $infoHtml .= '<strong>'.e($first['field']).':</strong> '.e($first['new']);
                    if (count($changes) > 1) {
                        $infoHtml .= ' <span class="badge text-bg-light border text-dark ms-1">+'.(count($changes) - 1).'</span>';
                    }
                } else {
                    $infoHtml .= e(data_get($properties, 'details', '-'));
                }
                $infoHtml .= '</div>';

                // Logistics Column
                $ip = data_get($properties, 'ip', '-');
                $agent = data_get($properties, 'agent', '-');

                // Prepare JSON for modal
                $modalData = [
                    'causer' => [
                        'name' => $log->causer?->name ?? 'System',
                        'email' => $log->causer?->email ?? '-',
                    ],
                    'event' => [
                        'label' => $eventLabel,
                        'badge' => $eventBadge,
                        'icon' => $eventIcon,
                        'description' => $log->description,
                    ],
                    'subject' => [
                        'type' => $modelName,
                        'id' => $log->subject_id,
                        'module' => $log->log_name,
                    ],
                    'changes' => $changes,
                    'meta' => [
                        'ip' => $ip,
                        'agent' => $agent,
                        'time' => format_datetime($log->created_at),
                    ],
                    'raw' => $log->toArray(),
                ];

                return [
                    $userHtml,
                    $eventHtml,
                    $infoHtml,
                    '<span class="badge text-bg-theme-1-subtle text-theme-1">'.e($modelName).'</span>',
                    e(format_datetime($log->created_at)),
                    '<code class="extra-small">'.e($ip).'</code>',
                    '<span class="text-secondary extra-small text-truncate d-block" style="max-width:150px;" title="'.e($agent).'">'.e($agent).'</span>',
                    '<pre class="mb-0 extra-small text-secondary" style="max-height: 50px; overflow: hidden;">'.e(json_encode($properties)).'</pre>',
                    '<div class="text-end">
                        <button class="btn btn-square btn-outline-theme btn-sm rounded-circle btn-detail-log" 
                                data-activity=\''.e(json_encode($modalData, JSON_HEX_APOS | JSON_HEX_QUOT)).'\'>
                            <i class="bi bi-eye"></i>
                        </button>
                    </div>',
                ];
            })->all();

            return DataTable::response($request, $recordsTotal, $recordsFiltered, $rows);
        } catch (\Exception $e) {
            Log::error('DataTable Error [ActionLog]: '.$e->getMessage());

            return DataTable::response($request, 0, 0, []);
        }
    }

    public function clear()
    {
        try {
            DB::table('activity_log')->truncate();

            return response()->json(['success' => true, 'message' => __('Action logs cleared successfully.')]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => __('Failed to clear logs.')], 500);
        }
    }

    public function export(Request $request)
    {
        $query = Activity::query()->with('causer')->latest();

        // Apply same filters as dataTable
        if ($event = $request->input('event')) {
            if ($event === 'auth') {
                $query->whereIn('description', ['login', 'logout', 'login_attempt', 'password_changed', 'failed login', 'password reset']);
            } elseif ($event === 'data') {
                $query->whereIn('description', ['created', 'updated', 'deleted', 'restored', 'force deleted', 'permanent_deleted']);
            } elseif ($event === 'system') {
                $query->whereIn('log_name', ['system', 'maintenance', 'backup']);
            }
        }

        if ($search = $request->input('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('description', 'like', "%{$search}%")
                    ->orWhere('log_name', 'like', "%{$search}%")
                    ->orWhere('properties', 'like', "%{$search}%");
            });
        }

        $filename = 'action-logs-'.now()->format('Y-m-d-His').'.csv';

        return response()->streamDownload(function () use ($query) {
            $file = fopen('php://output', 'w');
            fputcsv($file, ['User', 'Action', 'Module', 'Executed At', 'IP Address', 'User Agent', 'Properties']);

            $query->chunk(200, function ($logs) use ($file) {
                foreach ($logs as $log) {
                    fputcsv($file, [
                        $log->causer?->name ?? 'System',
                        ucfirst($log->description),
                        $log->log_name,
                        $log->created_at->toDateTimeString(),
                        data_get($log->properties, 'ip', '-'),
                        data_get($log->properties, 'agent', '-'),
                        json_encode($log->properties),
                    ]);
                }
            });
            fclose($file);
        }, $filename);
    }
}
