<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\InventoryAlert;
use App\Models\InventoryItem;
use App\Models\InventoryBatch;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use App\Mail\LowStockAlert;
use App\Mail\ExpiryAlert;

class CheckInventoryAlerts extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'inventory:check-alerts {--company=all : The company ID to check alerts for (default: all)}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Check inventory for low stock and expiring items and send alerts';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $companyOption = $this->option('company');

        $this->info('Starting inventory alerts check...');

        if ($companyOption === 'all') {
            $alerts = InventoryAlert::all();
            $this->info('Checking alerts for all companies');
        } else {
            $alerts = InventoryAlert::where('company_id', $companyOption)->get();
            $this->info("Checking alerts for company ID: {$companyOption}");
        }

        foreach ($alerts as $alert) {
            $this->checkLowStockAlerts($alert);
            $this->checkExpiryAlerts($alert);
        }

        $this->info('Inventory alerts check completed');

        return Command::SUCCESS;
    }

    /**
     * Check for low stock items and send alerts.
     */
    private function checkLowStockAlerts(InventoryAlert $alert)
    {
        if (!$alert->low_stock_enabled) {
            $this->line("Low stock alerts disabled for company ID: {$alert->company_id}");
            return;
        }

        $this->line("Checking low stock alerts for company ID: {$alert->company_id}");

        // Get items with low stock
        $items = InventoryItem::with(['stocks.warehouse', 'category'])
            ->where('company_id', $alert->company_id)
            ->where('is_active', true)
            ->get()
            ->filter(function ($item) use ($alert) {
                if ($item->min_stock_level <= 0) {
                    return false;
                }

                $percentage = ($item->available_stock / $item->min_stock_level) * 100;
                return $percentage <= $alert->low_stock_threshold;
            });

        if ($items->isEmpty()) {
            $this->line("No low stock items found for company ID: {$alert->company_id}");
            return;
        }

        $this->info("Found {$items->count()} low stock items for company ID: {$alert->company_id}");

        // Send email notifications
        if (!empty($alert->notification_emails)) {
            foreach ($alert->notification_emails as $email) {
                $this->line("Sending low stock alert email to: {$email}");
                Mail::to($email)->send(new LowStockAlert($items, $alert));
            }
        }

        // Send notifications to users
        if (!empty($alert->notification_users)) {
            $users = User::whereIn('id', $alert->notification_users)->get();
            foreach ($users as $user) {
                $this->line("Sending low stock alert notification to user: {$user->name}");
                $user->notify(new \App\Notifications\LowStockAlert($items, $alert));
            }
        }
    }

    /**
     * Check for expiring items and send alerts.
     */
    private function checkExpiryAlerts(InventoryAlert $alert)
    {
        if (!$alert->expiry_enabled) {
            $this->line("Expiry alerts disabled for company ID: {$alert->company_id}");
            return;
        }

        $this->line("Checking expiry alerts for company ID: {$alert->company_id}");

        // Get batches that will expire soon
        $expiryDate = now()->addDays($alert->expiry_threshold_days);

        $batches = InventoryBatch::with(['item', 'warehouse'])
            ->where('company_id', $alert->company_id)
            ->where('expiry_date', '<=', $expiryDate)
            ->where('expiry_date', '>=', now())
            ->where('quantity', '>', 0)
            ->orderBy('expiry_date')
            ->get();

        if ($batches->isEmpty()) {
            $this->line("No expiring batches found for company ID: {$alert->company_id}");
            return;
        }

        $this->info("Found {$batches->count()} expiring batches for company ID: {$alert->company_id}");

        // Send email notifications
        if (!empty($alert->notification_emails)) {
            foreach ($alert->notification_emails as $email) {
                $this->line("Sending expiry alert email to: {$email}");
                Mail::to($email)->send(new ExpiryAlert($batches, $alert));
            }
        }

        // Send notifications to users
        if (!empty($alert->notification_users)) {
            $users = User::whereIn('id', $alert->notification_users)->get();
            foreach ($users as $user) {
                $this->line("Sending expiry alert notification to user: {$user->name}");
                $user->notify(new \App\Notifications\ExpiryAlert($batches, $alert));
            }
        }
    }
}
