<?php

namespace App\Http\Controllers;

use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;

class SettingsController extends Controller
{
    public function index()
    {
        $settings = Setting::all()->pluck('value', 'key')->toArray();

        // Always pull .env values so the form shows what is actually in .env
        // (DB defaults may differ from real .env until the user saves once)
        $envMap = [
            'project_name'       => env('APP_NAME'),
            'site_url'           => env('APP_URL'),
            'app_debugging'      => filter_var(env('APP_DEBUG', false), FILTER_VALIDATE_BOOLEAN) ? '1' : '0',
            'timezone'           => env('APP_TIMEZONE'),
            'file_storage'       => env('FILESYSTEM_DISK'),
            'aws_access_key'     => env('AWS_ACCESS_KEY_ID'),
            'aws_secret_key'     => env('AWS_SECRET_ACCESS_KEY'),
            'aws_region'         => env('AWS_DEFAULT_REGION'),
            'aws_bucket'         => env('AWS_BUCKET'),
            'aws_bucket_url'     => env('AWS_URL'),
            'pusher_app_id'      => env('PUSHER_APP_ID'),
            'pusher_app_key'     => env('PUSHER_APP_KEY'),
            'pusher_app_secret'  => env('PUSHER_APP_SECRET'),
            'pusher_app_cluster' => env('PUSHER_APP_CLUSTER'),
            'broadcast_driver'   => env('BROADCAST_CONNECTION'),
        ];

        foreach ($envMap as $key => $value) {
            if ($value !== null && $value !== '') {
                $settings[$key] = $value;
            }
        }

        $settings = collect($settings);

        // Parse Laravel log into structured entries
        $logEntries = [];
        $logPath = storage_path('logs/laravel.log');
        if (file_exists($logPath)) {
            $raw = file_get_contents($logPath);
            // Split on log entry boundaries — each entry starts with [YYYY-MM-DD HH:mm:ss]
            $chunks = preg_split('/(?=^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\])/m', $raw, -1, PREG_SPLIT_NO_EMPTY);
            foreach (array_reverse(array_slice($chunks, -100)) as $chunk) {
                $chunk = trim($chunk);
                if (!$chunk) continue;

                $lines     = explode("\n", $chunk);
                $firstLine = $lines[0];

                // Parse header: [2026-03-27 12:34:56] local.ERROR: message
                if (!preg_match('/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]\s+\S+\.(\w+):\s*(.*)/', $firstLine, $m)) {
                    continue;
                }

                $timestamp = $m[1];
                $level     = strtoupper($m[2]);
                $message   = trim($m[3]);

                // Strip trailing JSON context object {"exception":...}
                $message = preg_replace('/\s*\{"exception.*$/s', '', $message);
                $message = preg_replace('/\s*\{["\[].*$/s', '', $message);
                $message = trim($message) ?: 'No message';

                // Everything after line 0 is stack trace — skip blank lines between
                $traceLines = array_filter(array_slice($lines, 1), fn($l) => trim($l) !== '');
                $trace      = implode("\n", $traceLines);

                $logEntries[] = [
                    'timestamp' => $timestamp,
                    'level'     => $level,
                    'message'   => $message,
                    'trace'     => $trace,
                ];
            }
        }

        return view('settings', compact('settings', 'logEntries'))->with('authUser', Auth::user());
    }

    public function update(Request $request)
    {
        $boolFields = ['app_debugging', 'disable_landing_page', 'wildcard_domain', 'money_conversion'];

        $fields = [
            'project_name', 'site_url', 'subdomains',
            'app_debugging', 'disable_landing_page', 'wildcard_domain',
            'pagination_count',
            'file_storage', 'aws_access_key', 'aws_secret_key', 'aws_region', 'aws_bucket', 'aws_bucket_url',
            'default_language', 'available_languages', 'timezone', 'default_currency',
            'money_conversion', 'time_format', 'date_format', 'working_time_format', 'phone_country_code',
            'pusher_app_id', 'pusher_app_key', 'pusher_app_secret', 'pusher_app_cluster', 'broadcast_driver',
            'msg_sending_mode', 'async_sending_mode', 'campaign_batch_size',
        ];

        foreach ($fields as $field) {
            $value = in_array($field, $boolFields)
                ? ($request->has($field) ? '1' : '0')
                : $request->input($field, '');
            Setting::set($field, $value);
        }

        // Clamp campaign batch size to max 150
        $batchSize = (int) $request->input('campaign_batch_size', 50);
        if ($batchSize > 150) $batchSize = 150;
        if ($batchSize < 1)   $batchSize = 1;
        Setting::set('campaign_batch_size', $batchSize);

        // Handle app logo upload — stored in storage/app/public/uploads/ served via public/uploads/ symlink
        if ($request->hasFile('app_logo')) {
            $ext  = $request->file('app_logo')->getClientOriginalExtension();
            $name = 'app_logo.' . $ext;
            Storage::disk('public')->putFileAs('uploads', $request->file('app_logo'), $name);
            Setting::set('app_logo', $name);
        }

        // Sync relevant settings → .env
        $this->syncEnv([
            'APP_NAME'              => $request->input('project_name', ''),
            'APP_URL'               => $request->input('site_url', ''),
            'APP_DEBUG'             => $request->has('app_debugging') ? 'true' : 'false',
            'APP_TIMEZONE'          => $request->input('timezone', 'UTC'),
            'FILESYSTEM_DISK'       => $request->input('file_storage', 'local'),
            'AWS_ACCESS_KEY_ID'     => $request->input('aws_access_key', ''),
            'AWS_SECRET_ACCESS_KEY' => $request->input('aws_secret_key', ''),
            'AWS_DEFAULT_REGION'    => $request->input('aws_region', 'us-east-1'),
            'AWS_BUCKET'            => $request->input('aws_bucket', ''),
            'AWS_URL'               => $request->input('aws_bucket_url', ''),
            'PUSHER_APP_ID'         => $request->input('pusher_app_id', ''),
            'PUSHER_APP_KEY'        => $request->input('pusher_app_key', ''),
            'PUSHER_APP_SECRET'     => $request->input('pusher_app_secret', ''),
            'PUSHER_APP_CLUSTER'    => $request->input('pusher_app_cluster', 'mt1'),
            'BROADCAST_CONNECTION'  => $request->input('broadcast_driver', 'log'),
        ]);

        return redirect()->route('settings')->with('success', 'Settings saved and .env updated successfully.');
    }

    /**
     * Write key=value pairs into .env line-by-line.
     * Safe against values with $, quotes, spaces, special chars.
     * Does NOT call Artisan::call() — that crashes mid-request.
     */
    private function syncEnv(array $data): void
    {
        $path = base_path('.env');
        if (!file_exists($path)) return;

        // Read line by line so we can do exact string replacements (no regex on values)
        $lines = file($path, FILE_IGNORE_NEW_LINES);

        foreach ($data as $key => $value) {
            // Quote value if it contains spaces or special characters
            $needsQuotes = preg_match('/[\s#"\'\\\\]/', $value);
            $escaped     = $needsQuotes ? '"' . str_replace('"', '\\"', $value) . '"' : $value;
            $newLine     = "{$key}={$escaped}";

            $found = false;
            foreach ($lines as &$line) {
                // Match exact key (case-sensitive, must start the line)
                if (preg_match('/^' . preg_quote($key, '/') . '=/', $line)) {
                    $line  = $newLine;
                    $found = true;
                    break;
                }
            }
            unset($line);

            if (!$found) {
                $lines[] = '';
                $lines[] = $newLine;
            }
        }

        file_put_contents($path, implode("\n", $lines) . "\n");

        // Delete compiled config cache file directly — safe inside a request
        $cacheFile = base_path('bootstrap/cache/config.php');
        if (file_exists($cacheFile)) {
            @unlink($cacheFile);
        }
    }
}
