<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Spatie\Activitylog\Models\Activity;
use Yajra\DataTables\Facades\DataTables;
use Carbon\Carbon;

class LoggingController extends Controller
{
    /**
     * Display the logging dashboard
     */
    public function index()
    {
        // Get users for filter dropdown
        $users = \App\Models\User::select('id', 'name')->orderBy('name')->get();

        // Get distinct action types for filter dropdown
        $actionTypes = Activity::select('description')
            ->distinct()
            ->whereNotNull('description')
            ->orderBy('description')
            ->pluck('description');

        return view('logging.index', compact('users', 'actionTypes'));
    }

    /**
     * Get activity logs for DataTables
     */
    public function getActivityLogs(Request $request)
    {
        $query = Activity::with(['causer', 'subject'])
            ->orderBy('created_at', 'desc');

        // Apply filters
        if ($request->filled('user_id')) {
            $query->where('causer_id', $request->input('user_id'));
        }

        if ($request->filled('action_type')) {
            $query->where('description', $request->input('action_type'));
        }

        if ($request->filled('date_from') && $request->filled('date_to')) {
            $query->whereBetween('created_at', [
                $request->input('date_from') . ' 00:00:00',
                $request->input('date_to') . ' 23:59:59'
            ]);
        }

        return DataTables::of($query)
            ->addColumn('user', function ($activity) {
                return $activity->causer ? $activity->causer->name : 'System';
            })
            ->addColumn('subject_type', function ($activity) {
                if ($activity->subject) {
                    return class_basename($activity->subject_type);
                }
                return '-';
            })
            ->addColumn('subject_name', function ($activity) {
                if ($activity->subject) {
                    return $activity->subject->name ?? $activity->subject->id ?? 'N/A';
                }
                return '-';
            })
            ->addColumn('description', function ($activity) {
                return ucfirst(str_replace('_', ' ', $activity->description));
            })
            ->addColumn('properties', function ($activity) {
                if ($activity->properties->count() > 0) {
                    return '<button class="btn btn-sm btn-info" onclick="viewProperties(' . $activity->id . ')">View Details</button>';
                }
                return '-';
            })
                            ->addColumn('created_at', function ($activity) {
                    return $activity->created_at->setTimezone('Asia/Karachi')->format('Y-m-d H:i:s T');
                })
            ->rawColumns(['properties'])
            ->make(true);
    }

    /**
     * Get Laravel logs for DataTables
     */
    public function getLaravelLogs(Request $request)
    {
        $logFile = storage_path('logs/laravel.log');
        $logs = [];

        if (File::exists($logFile)) {
            $content = File::get($logFile);
            $lines = explode("\n", $content);

            foreach (array_reverse($lines) as $line) {
                if (trim($line) !== '') {
                    $parsedLog = $this->parseLogLine($line);
                    if ($parsedLog) {
                        $logs[] = $parsedLog;
                    }
                }
            }
        }

        $logs = collect($logs)->filter();

        // Apply filters
        if ($request->filled('log_level')) {
            $logs = $logs->filter(function ($log) use ($request) {
                return strtolower($log['level'] ?? '') === strtolower($request->input('log_level'));
            });
        }

        if ($request->filled('date_from') && $request->filled('date_to')) {
            $logs = $logs->filter(function ($log) use ($request) {
                if (!isset($log['timestamp'])) return false;

                try {
                    $logDate = Carbon::parse($log['timestamp'])->setTimezone('Asia/Karachi')->format('Y-m-d');
                    return $logDate >= $request->input('date_from') && $logDate <= $request->input('date_to');
                } catch (\Exception $e) {
                    return false;
                }
            });
        }

        return DataTables::of($logs)
            ->addColumn('level_badge', function ($log) {
                $level = strtolower($log['level'] ?? 'info');
                $badgeClass = $this->getLevelBadgeClass($level);
                return '<span class="badge ' . $badgeClass . '">' . strtoupper($level) . '</span>';
            })
            ->addColumn('message', function ($log) {
                return $log['message'] ?? '';
            })
            ->addColumn('context', function ($log) {
                if (!empty($log['context'])) {
                    return '<button class="btn btn-sm btn-info" onclick="viewContext(\'' . htmlspecialchars(json_encode($log['context'])) . '\')">View Context</button>';
                }
                return '-';
            })
            ->addColumn('timestamp', function ($log) {
                return $log['timestamp'] ?? '';
            })
            ->rawColumns(['level_badge', 'context'])
            ->make(true);
    }

    /**
     * Get error logs for DataTables
     */
    public function getErrorLogs(Request $request)
    {
        $logFile = storage_path('logs/error.log');
        $logs = [];

        if (File::exists($logFile)) {
            $content = File::get($logFile);
            $lines = explode("\n", $content);

            foreach (array_reverse($lines) as $line) {
                if (trim($line) !== '') {
                    $logs[] = $this->parseLogLine($line);
                }
            }
        }

        $logs = collect($logs)->filter();

        return DataTables::of($logs)
            ->addColumn('level_badge', function ($log) {
                $level = strtolower($log['level'] ?? 'error');
                $badgeClass = $this->getLevelBadgeClass($level);
                return '<span class="badge ' . $badgeClass . '">' . strtoupper($level) . '</span>';
            })
            ->addColumn('message', function ($log) {
                return $log['message'] ?? '';
            })
            ->addColumn('context', function ($log) {
                if (!empty($log['context'])) {
                    return '<button class="btn btn-sm btn-info" onclick="viewContext(\'' . htmlspecialchars(json_encode($log['context'])) . '\')">View Context</button>';
                }
                return '-';
            })
            ->addColumn('timestamp', function ($log) {
                return $log['timestamp'] ?? '';
            })
            ->rawColumns(['level_badge', 'context'])
            ->make(true);
    }

    /**
     * Get activity properties
     */
    public function getActivityProperties($id)
    {
        $activity = Activity::findOrFail($id);

        return response()->json([
            'properties' => $activity->properties->toArray(),
            'changes' => $activity->changes()->toArray(),
        ]);
    }

    /**
     * Clear logs
     */
    public function clearLogs(Request $request)
    {
        $type = $request->input('type', 'laravel');

        try {
            switch ($type) {
                case 'laravel':
                    File::put(storage_path('logs/laravel.log'), '');
                    break;
                case 'error':
                    File::put(storage_path('logs/error.log'), '');
                    break;
                case 'activity':
                    Activity::truncate();
                    break;
            }

            Log::channel('application')->info('Logs cleared', [
                'type' => $type,
                'user_id' => auth()->id(),
                'user_name' => auth()->user()->name ?? 'Unknown'
            ]);

            return response()->json(['success' => true, 'message' => ucfirst($type) . ' logs cleared successfully']);
        } catch (\Exception $e) {
            Log::error('Failed to clear logs', [
                'type' => $type,
                'error' => $e->getMessage()
            ]);

            return response()->json(['success' => false, 'message' => 'Failed to clear logs'], 500);
        }
    }

    /**
     * Parse log line
     */
    private function parseLogLine($line)
    {
        // Laravel log format: [2024-01-01 12:00:00] local.ERROR: message {"context":"data"}
        if (preg_match('/^\[(.*?)\] (\w+)\.(\w+): (.*?)( \{.*\})?$/', $line, $matches)) {
            return [
                'timestamp' => $matches[1],
                'environment' => $matches[2],
                'level' => $matches[3],
                'message' => $matches[4],
                'context' => isset($matches[5]) ? json_decode($matches[5], true) : null,
            ];
        }

        return null;
    }

    /**
     * Get badge class for log level
     */
    private function getLevelBadgeClass($level)
    {
        return match ($level) {
            'emergency', 'alert', 'critical' => 'bg-danger',
            'error' => 'bg-danger',
            'warning' => 'bg-warning',
            'notice', 'info' => 'bg-info',
            'debug' => 'bg-secondary',
            default => 'bg-secondary',
        };
    }
}
