<?php

use App\Models\Category;
use App\Models\City;
use App\Models\PaymentMethod;
use App\Models\Province;
use App\Models\SaleType;
use App\Models\Setting;
use App\Models\Unit;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * Check if this is the first launch of the application
 */
function isFirstLaunch(): bool
{
    if (! Schema::hasTable('settings')) {
        return true;
    }

    // If bootstrap has never completed, consider first launch
    $settings = Setting::first();
    if (! $settings) {
        return true;
    }

    // settings table exists and at least one row exists, but bootstrap may not be completed
    return ! (bool) ($settings->bootstrap_completed ?? false);
}

/**
 * Check if merchant setup is complete
 */
function isMerchantSetupComplete(): bool
{
    $settings = Setting::first();
    if (! $settings) {
        return false;
    }

    // Check if essential merchant information is filled
    $requiredFields = [
        'merchant_name',
        'merchant_slug',
        'merchant_phone',
        'merchant_type',
        'merchant_province_id',
        'merchant_city_id',
    ];

    foreach ($requiredFields as $field) {
        if (empty($settings->$field)) {
            return false;
        }
    }

    return true;
}

function resetDatabase(): void
{
    // Disable foreign key checks
    DB::statement('PRAGMA foreign_keys = OFF');

    try {
        // List of all tables to truncate (in order to handle dependencies)
        $listTables = [
            // Conversation & Messages
            'conversation_messages',
            'conversations',
            // Prescription data
            'prescriptions',
            // Debt data
            'debt_payments',
            'debts',
            // Activity logs
            'activity_logs',
            // Expense data
            'expenses',
            'expense_categories',
            // Subscription data
            'subscriptions',
            // Order data
            'order_products',
            'orders',
            // Sales data
            'inventory_transactions',
            'sale_items',
            'sales',
            'sale_types',
            // Purchase orders
            'purchase_order_items',
            'purchase_orders',
            // Stock management
            'stock_adjustment_items',
            'stock_adjustments',
            'stock_entries',
            'location_product',
            // Products & inventory
            'products',
            // Suppliers & Customers
            'suppliers',
            'customers',
            // Location data
            'locations',
            // Master data
            'units',
            'categories',
            'payment_methods',
            // Merchant & Users
            'merchant_users',
            'users',
            'personal_access_tokens',
            // Address data
            'contacts',
            'addresses',
            'cities',
            'provinces',
            // Settings
            'settings',
            // Auth & session
            'password_reset_tokens',
            // 'sessions',
            // System tables
            'cache',
            'cache_locks',
            'jobs',
            'job_batches',
            'failed_jobs',
        ];

        foreach ($listTables as $table) {
            // Check if table exists before truncating
            $tableExists = DB::select("SELECT name FROM sqlite_master WHERE type='table' AND name=?", [$table]);
            if (! empty($tableExists)) {
                DB::table($table)->delete(); // Use delete() for SQLite instead of truncate()
            }
        }

        // Reset auto-increment sequences for SQLite
        DB::statement('DELETE FROM sqlite_sequence');
    } finally {
        // Re-enable foreign key checks
        DB::statement('PRAGMA foreign_keys = ON');
    }
}

function runFirstTimeSetup(): void
{
    // Seed per-domain if empty or missing; safe to run multiple times
    if (! Setting::query()->exists()) {
        initializeMerchantSettings();
    }

    if (\App\Models\PaymentMethod::query()->count() === 0) {
        initializeDefaultPaymentMethods();
    }
    if (\App\Models\SaleType::query()->count() === 0) {
        initializeDefaultSaleTypes();
    }
    if (\App\Models\Unit::query()->count() === 0) {
        initializeDefaultUnits();
    }
    if (\App\Models\Category::query()->count() === 0) {
        initializeDefaultCategories();
    }
    if (\App\Models\Province::query()->count() === 0) {
        initializeDefaultProvinces();
    }
    if (\App\Models\City::query()->count() === 0) {
        initializeDefaultCities();
    }

    // Mark bootstrap completed
    $settings = Setting::first();
    if ($settings && ! ($settings->bootstrap_completed ?? false)) {
        $settings->update(['bootstrap_completed' => true]);
    }
}

/**
 * Initialize merchant settings for new installations
 */
function initializeMerchantSettings(): array
{
    try {
        $merchantSettings = [
            'merchant_name' => 'Ma Pharmacie',
            'merchant_type' => 'pharmacy',
            'merchant_status' => false,
            'merchant_slug' => 'ma-pharmacie',
            'merchant_slogan' => '',
            'merchant_phone' => '',
            'merchant_email' => '',
            'merchant_address' => '',
        ];
        Setting::create($merchantSettings);

        return [
            'success' => true,
            'message' => 'Merchant settings initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize merchant settings: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default payment methods
 */
function initializeDefaultPaymentMethods(): array
{
    try {
        $defaultPaymentMethods = PaymentMethod::PAYMENT_METHODS;
        foreach ($defaultPaymentMethods as $method) {
            PaymentMethod::firstOrCreate(
                [
                    'name' => $method['name'],
                ],
                [
                    'code' => $method['code'],
                    'status' => $method['status'],
                ]
            );
        }

        return [
            'success' => true,
            'message' => 'Payment methods initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize payment methods: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default sale types
 */
function initializeDefaultSaleTypes(): array
{
    try {
        $defaultSaleTypes = SaleType::SALE_TYPES;
        foreach ($defaultSaleTypes as $type) {
            SaleType::firstOrCreate(
                ['name' => $type['name']],
                [
                    'code' => $type['code'],
                    'description' => $type['description'],
                    'status' => $type['status'],
                ]
            );
        }

        return [
            'success' => true,
            'message' => 'Sale types initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize sale types: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default units
 */
function initializeDefaultUnits(): array
{
    try {
        $defaultUnits = Unit::UNITS;

        foreach ($defaultUnits as $unit) {
            Unit::firstOrCreate(
                ['name' => $unit['name']],
                [
                    'symbol' => $unit['symbol'],
                    'slug' => $unit['slug'],
                    'description' => $unit['description'],
                ]
            );
        }

        return [
            'success' => true,
            'message' => 'Units initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize units: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default categories
 */
function initializeDefaultCategories(): array
{
    try {
        $defaultCategories = Category::CATEGORIES;
        foreach ($defaultCategories as $category) {
            Category::firstOrCreate(
                ['name' => $category['name']],
                [
                    'slug' => $category['slug'],
                    'description' => $category['description'],
                ]
            );
        }

        return [
            'success' => true,
            'message' => 'Categories initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize categories: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default provinces
 */
function initializeDefaultProvinces(): array
{
    try {
        $defaultProvinces = Province::DEFAULT_PROVINCES;
        foreach ($defaultProvinces as $province) {
            Province::firstOrCreate(
                ['name' => $province['name']],
                ['slug' => $province['slug']]
            );
        }

        return [
            'success' => true,
            'message' => 'Provinces initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize provinces: '.$e->getMessage(),
        ];
    }
}

/**
 * Initialize default cities
 */
function initializeDefaultCities(): array
{
    try {
        $defaultCities = City::DEFAULT_CITIES;
        foreach ($defaultCities as $city) {
            City::firstOrCreate(
                ['name' => $city['name']],
                [
                    'slug' => $city['slug'],
                    'province_id' => $city['province_id'] ?? null,
                ]
            );
        }

        return [
            'success' => true,
            'message' => 'Cities initialized',
        ];
    } catch (\Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to initialize cities: '.$e->getMessage(),
        ];
    }
}

/**
 * Check if the app is licensed
 */
function checkAppLicensed(): bool
{
    if (! Schema::hasTable('subscriptions')) {
        return false;
    }

    $licensed = \App\Models\Subscription::query()
        ->where('status', \App\Models\Subscription::STATUS_ACTIVE)
        ->where(function ($q) {
            $q->whereNull('end_date')->orWhere('end_date', '>', now());
        })
        ->exists();

    return $licensed;
}
