<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Hash;
use App\Models\User; // Assuming User model is at App\Models\User
use Exception;

class InstallController extends Controller
{
    public function index()
    {
        return view('install.wizard');
    }

    public function checkRequirements()
    {
        $phpVersion = PHP_VERSION;
        $phpPass = version_compare($phpVersion, '8.3.0', '>=');

        $extensions = [
            'pdo_mysql' => extension_loaded('pdo_mysql'),
            'openssl' => extension_loaded('openssl'),
            'mbstring' => extension_loaded('mbstring'),
            'tokenizer' => extension_loaded('tokenizer'),
            'xml' => extension_loaded('xml'),
            'ctype' => extension_loaded('ctype'),
            'json' => extension_loaded('json'),
            'fileinfo' => extension_loaded('fileinfo'),
            'curl' => extension_loaded('curl'),
        ];

        $permissions = [
            'storage' => is_writable(storage_path()),
            'bootstrap_cache' => is_writable(base_path('bootstrap/cache')),
            'env' => is_writable(base_path('.env')),
        ];

        $allPass = $phpPass && !in_array(false, $extensions, true) && !in_array(false, $permissions, true);

        return response()->json([
            'php_version' => $phpVersion,
            'php_pass' => $phpPass,
            'extensions' => $extensions,
            'permissions' => $permissions,
            'all_pass' => $allPass,
        ]);
    }

    public function testDb(Request $request)
    {
        $request->validate([
            'host' => 'required',
            'port' => 'required|numeric',
            'database' => 'required',
            'username' => 'required',
        ]);

        $host = $request->host;
        $port = $request->port;
        $database = $request->database;
        $username = $request->username;
        $password = $request->password ?? '';

        // Temporarily configure database connection
        config([
            'database.connections.install_test' => [
                'driver' => 'mysql',
                'host' => $host,
                'port' => $port,
                'database' => $database,
                'username' => $username,
                'password' => $password,
                'charset' => 'utf8mb4',
                'collation' => 'utf8mb4_unicode_ci',
                'prefix' => '',
                'strict' => true,
                'engine' => null,
            ]
        ]);

        try {
            DB::connection('install_test')->getPdo();
            return response()->json(['success' => true, 'message' => 'Database connection successful!']);
        } catch (Exception $e) {
            return response()->json(['success' => false, 'message' => 'Connection failed: ' . $e->getMessage()]);
        }
    }

    public function saveConfig(Request $request)
    {
        $request->validate([
            'db_host' => 'required',
            'db_port' => 'required|numeric',
            'db_database' => 'required',
            'db_username' => 'required',
            'app_name' => 'required',
            'app_url' => 'required|url',
            'nextjs_frontend_url' => 'required|url',
            'app_env' => 'required|in:local,production',
        ]);

        try {
            $envPath = base_path('.env');
            if (!file_exists($envPath)) {
                if (file_exists(base_path('.env.example'))) {
                    copy(base_path('.env.example'), $envPath);
                } else {
                    touch($envPath);
                }
            }

            $envContent = file_get_contents($envPath);

            $configs = [
                'DB_CONNECTION' => 'mysql',
                'DB_HOST' => $request->db_host,
                'DB_PORT' => $request->db_port,
                'DB_DATABASE' => $request->db_database,
                'DB_USERNAME' => $request->db_username,
                'DB_PASSWORD' => $request->db_password ?? '',
                'APP_NAME' => '"' . str_replace('"', '\\"', $request->app_name) . '"',
                'APP_URL' => $request->app_url,
                'FRONTEND_URL' => $request->nextjs_frontend_url,
                'NEXTJS_FRONTEND_URL' => $request->nextjs_frontend_url,
                'APP_ENV' => $request->app_env,
                'APP_DEBUG' => $request->app_env === 'local' ? 'true' : 'false',
                // Shared hosting safe drivers - no Redis required
                'CACHE_STORE' => 'file',
                'SESSION_DRIVER' => 'file',
            ];

            $driver = $request->input('cache_driver', 'file');

            $cacheConfig = match($driver) {
                'redis' => [
                    'CACHE_STORE'      => 'redis',
                    'SESSION_DRIVER'   => 'redis',
                    'QUEUE_CONNECTION' => 'redis',
                    'REDIS_CLIENT'     => 'phpredis',
                    'REDIS_HOST'       => $request->input('redis_host', '127.0.0.1'),
                    'REDIS_PASSWORD'   => $request->input('redis_password') ?: 'null',
                    'REDIS_PORT'       => $request->input('redis_port', '6379'),
                ],
                'database' => [
                    'CACHE_STORE'      => 'database',
                    'SESSION_DRIVER'   => 'database',
                    'QUEUE_CONNECTION' => 'database',
                ],
                default => [
                    'CACHE_STORE'      => 'file',
                    'SESSION_DRIVER'   => 'file',
                    'QUEUE_CONNECTION' => 'sync',
                ],
            };

            $configs = array_merge($configs, $cacheConfig);

            foreach ($configs as $key => $value) {
                // If key exists, replace it, else append it
                if (preg_match("/^{$key}=/m", $envContent)) {
                    $envContent = preg_replace("/^{$key}=.*/m", "{$key}={$value}", $envContent);
                } else {
                    $envContent .= "\n{$key}={$value}";
                }
            }

            file_put_contents($envPath, $envContent);

            return response()->json(['success' => true, 'message' => 'Configuration saved successfully!']);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'Failed to save configuration: ' . $e->getMessage()]);
        }
    }

    public function generateKey()
    {
        try {
            Artisan::call('key:generate', ['--force' => true]);
            return response()->json(['success' => true, 'message' => 'App key generated successfully!']);
        } catch (Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to generate key: ' . $e->getMessage()]);
        }
    }

    public function runInstall(Request $request)
    {
        $request->validate([
            'admin_name' => 'required|string|max:255',
            'admin_email' => 'required|email|max:255',
            'admin_password' => 'required|string|min:8',
        ]);

        try {
            // Check if any database tables already exist (e.g. if the "users" table is present)
            $tablesExist = false;
            try {
                $tablesExist = \Illuminate\Support\Facades\Schema::hasTable('users');
            } catch (\Throwable $e) {}

            if ($tablesExist) {
                // 1. Run incremental migrations to avoid deleting existing tables/data
                Artisan::call('migrate', ['--force' => true]);
            } else {
                // 1. Run fresh migrations (completely empty database setup)
                Artisan::call('migrate:fresh', ['--force' => true]);
                
                // 2. Run ONLY BdLocationSeeder (Utility geographic data, not demo content)
                if (class_exists(\Database\Seeders\BdLocationSeeder::class)) {
                    Artisan::call('db:seed', [
                        '--class' => \Database\Seeders\BdLocationSeeder::class,
                        '--force' => true
                    ]);
                }

                // Run LandingPageSeeder to automatically create the 3 default landing pages
                if (class_exists(\Database\Seeders\LandingPageSeeder::class)) {
                    Artisan::call('db:seed', [
                        '--class' => \Database\Seeders\LandingPageSeeder::class,
                        '--force' => true
                    ]);
                }

                // 3. Clear migration-seeded menus, categories, products, etc.
                // This guarantees no default/demo data is left
                DB::statement('SET FOREIGN_KEY_CHECKS=0;');
                DB::table('navigation_menus')->truncate();
                DB::table('categories')->truncate();
                DB::table('products')->truncate();
                DB::table('brands')->truncate();
                DB::table('coupons')->truncate();
                DB::table('shipping_methods')->truncate();
                DB::table('page_sections')->truncate();
                DB::table('pages')->truncate();
                DB::statement('SET FOREIGN_KEY_CHECKS=1;');

                // 3.1 Seed Default Header Menu Items (Home and Shop)
                DB::table('navigation_menus')->insert([
                    [
                        'name' => 'Home',
                        'link_url' => '/',
                        'position' => 'header',
                        'sort_order' => 0,
                        'is_active' => 1,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ],
                    [
                        'name' => 'Shop',
                        'link_url' => '/shop',
                        'position' => 'header',
                        'sort_order' => 1,
                        'is_active' => 1,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ],
                ]);

                // 4. Seed Default Settings Structure (Essential for store settings page & API configs)
                $settings = [
                    ['key' => 'site_name', 'value' => 'Sawdabazar', 'group' => 'general'],
                    ['key' => 'primary_brand_color', 'value' => '#003b20', 'group' => 'general'],
                    ['key' => 'secondary_brand_color', 'value' => '#f37021', 'group' => 'general'],
                    ['key' => 'store_email', 'value' => 'info@sawdabazar.com', 'group' => 'general'],
                    ['key' => 'store_phone', 'value' => '+8801700000000', 'group' => 'general'],
                    ['key' => 'store_address', 'value' => "House 12, Road 5, Sector 3\nUttara, Dhaka - 1230\nBangladesh", 'group' => 'general'],
                    ['key' => 'logo', 'value' => null, 'group' => 'general'],
                    ['key' => 'favicon', 'value' => null, 'group' => 'general'],
                    ['key' => 'facebook_url', 'value' => 'https://facebook.com/sawdabazar', 'group' => 'general'],
                    ['key' => 'instagram_url', 'value' => 'https://instagram.com/sawdabazar', 'group' => 'general'],
                    ['key' => 'whatsapp_number', 'value' => '+8801700000000', 'group' => 'general'],
                    ['key' => 'sms_gateway', 'value' => 'bulksmsbd', 'group' => 'sms'],
                    ['key' => 'bulksmsbd_username', 'value' => 'demo_user', 'group' => 'sms'],
                    ['key' => 'bulksmsbd_password', 'value' => 'demo_pass', 'group' => 'sms'],
                    ['key' => 'bulksmsbd_senderid', 'value' => '8801844000000', 'group' => 'sms'],
                    ['key' => 'greenweb_token', 'value' => 'demo_greenweb_token', 'group' => 'sms'],
                    ['key' => 'greenweb_senderid', 'value' => 'Sawdabazar', 'group' => 'sms'],
                    ['key' => 'sslwireless_token', 'value' => 'demo_ssl_token', 'group' => 'sms'],
                    ['key' => 'sslwireless_sid', 'value' => 'Sawdabazar_SID', 'group' => 'sms'],
                    ['key' => 'steadfast_api_key', 'value' => 'demo_steadfast_key', 'group' => 'courier'],
                    ['key' => 'steadfast_secret_key', 'value' => 'demo_steadfast_secret', 'group' => 'courier'],
                    ['key' => 'pathao_client_id', 'value' => 'demo_pathao_id', 'group' => 'courier'],
                    ['key' => 'pathao_client_secret', 'value' => 'demo_pathao_secret', 'group' => 'courier'],
                    ['key' => 'pathao_username', 'value' => 'demo_pathao_user', 'group' => 'courier'],
                    ['key' => 'pathao_password', 'value' => 'demo_pathao_pass', 'group' => 'courier'],
                    ['key' => 'pathao_store_id', 'value' => 'demo_pathao_store', 'group' => 'courier'],
                    ['key' => 'smtp_host', 'value' => 'sandbox.smtp.mailtrap.io', 'group' => 'email'],
                    ['key' => 'smtp_port', 'value' => '2525', 'group' => 'email'],
                    ['key' => 'smtp_username', 'value' => 'demo_username', 'group' => 'email'],
                    ['key' => 'smtp_password', 'value' => 'demo_password', 'group' => 'email'],
                    ['key' => 'smtp_encryption', 'value' => 'tls', 'group' => 'email'],
                    ['key' => 'smtp_from_address', 'value' => 'noreply@sawdabazar.com', 'group' => 'email'],
                    ['key' => 'smtp_from_name', 'value' => 'Sawdabazar', 'group' => 'email'],
                    ['key' => 'header_scripts', 'value' => '', 'group' => 'scripts'],
                    ['key' => 'footer_scripts', 'value' => '', 'group' => 'scripts'],
                    ['key' => 'meta_pixel_id', 'value' => 'demo_pixel_id', 'group' => 'scripts'],
                    ['key' => 'gtm_container_id', 'value' => 'GTM-DEMO', 'group' => 'scripts'],
                ];

                foreach ($settings as $set) {
                    DB::table('settings')->updateOrInsert(['key' => $set['key']], [
                        'value' => $set['value'],
                        'group' => $set['group'],
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                }

                // 5. Create a blank Home page (Required for frontend home render without errors)
                DB::table('pages')->insert([
                    'title' => 'Welcome to Sawdabazar',
                    'slug' => 'home',
                    'meta_title' => 'Sawdabazar - High Quality E-Commerce Store',
                    'meta_description' => 'Browse our catalog of premium products, fast shipping and easy online payments.',
                    'is_active' => true,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            }

            // 6. Create or Update Admin user
            $admin = User::updateOrCreate(
                ['email' => $request->admin_email],
                [
                    'name' => $request->admin_name,
                    'password' => Hash::make($request->admin_password),
                    'role' => 'admin',
                    'email_verified_at' => now(),
                ]
            );

            // 7. Create storage symlink automatically (to fix broken images/logo)
            try {
                $target = public_path('storage');
                $shortcut = storage_path('app/public');
                
                if (file_exists($target)) {
                    if (is_link($target)) {
                        $linkTarget = readlink($target);
                        if (!file_exists($linkTarget)) {
                            @unlink($target);
                        }
                    } else {
                        // Recursively delete physical public/storage folder if exists
                        $deleteDir = function ($dirPath) use (&$deleteDir) {
                            if (!is_dir($dirPath)) return;
                            $files = array_diff(scandir($dirPath), ['.','..']);
                            foreach ($files as $file) {
                                (is_dir("$dirPath/$file")) ? $deleteDir("$dirPath/$file") : @unlink("$dirPath/$file");
                            }
                            return @rmdir($dirPath);
                        };
                        $deleteDir($target);
                    }
                }
                
                if (!file_exists($target)) {
                    @symlink($shortcut, $target);
                }
                
                // Secondary check using Laravel's Artisan command
                if (!file_exists($target)) {
                    Artisan::call('storage:link');
                }
            } catch (\Throwable $linkEx) {
                // Fail silently or log it to avoid breaking installation on restrictive hosts
                \Illuminate\Support\Facades\Log::warning('Install Wizard storage link failed: ' . $linkEx->getMessage());
            }

            // 8. Clear all stale caches (do NOT re-cache — so future file uploads work immediately)
            try {
                Artisan::call('optimize:clear');
                Artisan::call('filament:cache:clear');
            } catch (\Exception $optEx) {
                \Illuminate\Support\Facades\Log::warning('Install Wizard cache clear failed: ' . $optEx->getMessage());
            }

            // 9. Create .installed lock file to mark setup as complete
            file_put_contents(storage_path('app/.installed'), date('Y-m-d H:i:s'));

            return response()->json(['success' => true, 'message' => 'Installation successful!']);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'Installation failed: ' . $e->getMessage()]);
        }
    }
}
