<?php

namespace App\Livewire\Reports;

use App\Models\Sale;
use App\Models\Expense;
use Livewire\Attributes\Layout;
use Livewire\Component;
use App\Models\Product;
use App\Models\Customer;
use App\Models\Supplier;
use App\Models\PurchaseOrder;
use App\Models\Debt;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

#[Layout('layouts.dashboard')]
class BusinessIntelligence extends Component
{
    public ?string $dateFrom = null;
    public ?string $dateTo = null;

    public function mount(?string $dateFrom = null, ?string $dateTo = null): void
    {
        $this->dateFrom = $dateFrom ?? request('date_from') ?? request('dateFrom');
        $this->dateTo = $dateTo ?? request('date_to') ?? request('dateTo');
    }

    
    private function getFinancialOverview($startDate, $endDate)
    {
        // Revenue
        $totalRevenue = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->sum('total_amount');

        // Expenses
        $totalExpenses = Expense::whereBetween('created_at', [$startDate, $endDate])
            ->sum('amount');

        // Cost of Goods Sold
        $costOfGoodsSold = DB::table('sale_items')
            ->join('sales', 'sale_items.sale_id', '=', 'sales.id')
            ->whereBetween('sales.created_at', [$startDate, $endDate])
            ->where('sales.status', Sale::STATUS_COMPLETED)
            ->sum(DB::raw('sale_items.quantity * sale_items.cost_price'));

        // Gross Profit
        $grossProfit = $totalRevenue - $costOfGoodsSold;
        $grossProfitMargin = $totalRevenue > 0 ? round(($grossProfit / $totalRevenue) * 100, 2) : 0;

        // Net Profit
        $netProfit = $grossProfit - $totalExpenses;
        $netProfitMargin = $totalRevenue > 0 ? round(($netProfit / $totalRevenue) * 100, 2) : 0;

        // Previous period comparison
        $previousPeriodStart = $startDate->copy()->subDays($startDate->diffInDays($endDate));
        $previousPeriodEnd = $startDate->copy()->subDay();

        $previousRevenue = Sale::whereBetween('created_at', [$previousPeriodStart, $previousPeriodEnd])
            ->where('status', Sale::STATUS_COMPLETED)
            ->sum('total_amount');

        $revenueGrowth = $previousRevenue > 0 ?
            round((($totalRevenue - $previousRevenue) / $previousRevenue) * 100, 2) : 0;

        return [
            'total_revenue' => $totalRevenue,
            'total_expenses' => $totalExpenses,
            'cost_of_goods_sold' => $costOfGoodsSold,
            'gross_profit' => $grossProfit,
            'gross_profit_margin' => $grossProfitMargin,
            'net_profit' => $netProfit,
            'net_profit_margin' => $netProfitMargin,
            'revenue_growth' => $revenueGrowth,
            'previous_revenue' => $previousRevenue,
        ];
    }

    private function getSalesPerformance($startDate, $endDate)
    {
        // Sales metrics
        $totalSales = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->count();

        $averageOrderValue = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->avg('total_amount') ?? 0;

        // Top performing products - only active products
        $topProducts = Product::where('status', Product::STATUS_ACTIVE)
            ->withSum(['saleItems as total_revenue' => function ($query) use ($startDate, $endDate) {
                $query->whereHas('sale', function ($q) use ($startDate, $endDate) {
                    $q->whereBetween('created_at', [$startDate, $endDate])
                        ->where('status', Sale::STATUS_COMPLETED);
                });
            }], 'total_price')
            ->withCount(['saleItems as total_quantity' => function ($query) use ($startDate, $endDate) {
                $query->whereHas('sale', function ($q) use ($startDate, $endDate) {
                    $q->whereBetween('created_at', [$startDate, $endDate])
                        ->where('status', Sale::STATUS_COMPLETED);
                });
            }], 'quantity')
            ->orderByDesc('total_revenue')
            ->limit(5)
            ->get();

        return [
            'total_sales' => $totalSales,
            'average_order_value' => round($averageOrderValue, 2),
            'top_products' => $topProducts,
        ];
    }

    private function getCustomerInsights($startDate, $endDate)
    {
        // Customer metrics
        $totalCustomers = Customer::count();
        $activeCustomers = Customer::whereHas('sales', function ($query) use ($startDate, $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED);
        })->count();

        $newCustomers = Customer::whereBetween('created_at', [$startDate, $endDate])->count();

        // Customer lifetime value
        $customerLifetimeValue = Customer::withSum('sales', 'total_amount')
            ->get()
            ->avg('sales_sum_total_amount') ?? 0;

        return [
            'total_customers' => $totalCustomers,
            'active_customers' => $activeCustomers,
            'new_customers' => $newCustomers,
            'customer_lifetime_value' => round($customerLifetimeValue, 2),
        ];
    }

    private function getInventoryInsights($startDate, $endDate)
    {
        // Inventory metrics - only active products
        $totalProducts = Product::where('status', Product::STATUS_ACTIVE)->count();
        
        $totalInventoryValue = Product::where('status', Product::STATUS_ACTIVE)
            ->get()
            ->sum(function ($product) {
                return ($product->current_stock ?? 0) * ($product->purchase_price ?? 0);
            });

        $lowStockProducts = Product::where('status', Product::STATUS_ACTIVE)
            ->where('current_stock', '<=', 10)
            ->count();
        $outOfStockProducts = Product::where('status', Product::STATUS_ACTIVE)
            ->where('current_stock', 0)
            ->count();

        return [
            'total_products' => $totalProducts,
            'total_inventory_value' => $totalInventoryValue,
            'low_stock_products' => $lowStockProducts,
            'out_of_stock_products' => $outOfStockProducts,
        ];
    }

    private function getOperationalMetrics($startDate, $endDate)
    {
        // Supplier metrics
        $totalSuppliers = Supplier::count();
        $activeSuppliers = Supplier::whereHas('purchaseOrders', function ($query) use ($startDate, $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate]);
        })->count();

        // Purchase orders
        $totalPurchaseOrders = PurchaseOrder::whereBetween('created_at', [$startDate, $endDate])->count();
        $completedPurchaseOrders = PurchaseOrder::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', PurchaseOrder::STATUS_RECEIVED)
            ->count();

        // Debt management
        $totalDebts = Debt::sum('remaining_amount');
        $pendingDebts = Debt::where('status', 'pending')->sum('remaining_amount');

        return [
            'total_suppliers' => $totalSuppliers,
            'active_suppliers' => $activeSuppliers,
            'total_purchase_orders' => $totalPurchaseOrders,
            'completed_purchase_orders' => $completedPurchaseOrders,
            'total_debts' => $totalDebts,
            'pending_debts' => $pendingDebts,
        ];
    }

    private function getTrendAnalysis($startDate, $endDate)
    {
        // Daily sales trend
        $dailySales = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->selectRaw('date(created_at) as date, COUNT(*) as count, SUM(total_amount) as revenue')
            ->groupBy('date')
            ->orderBy('date')
            ->get();

        return [
            'daily_sales' => $dailySales,
        ];
    }

    private function getRiskAssessment($startDate, $endDate)
    {
        // Financial risks
        $debtToRevenueRatio = 0;
        $totalRevenue = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->sum('total_amount');

        if ($totalRevenue > 0) {
            $totalDebts = Debt::sum('remaining_amount');
            $debtToRevenueRatio = round(($totalDebts / $totalRevenue) * 100, 2);
        }

        // Inventory risks - only active products
        $inventoryRisk = Product::where('status', Product::STATUS_ACTIVE)
            ->where('current_stock', 0)
            ->count();
        $lowStockRisk = Product::where('status', Product::STATUS_ACTIVE)
            ->where('current_stock', '>', 0)
            ->where('current_stock', '<=', 10)
            ->count();

        return [
            'debt_to_revenue_ratio' => $debtToRevenueRatio,
            'inventory_risk' => $inventoryRisk,
            'low_stock_risk' => $lowStockRisk,
        ];
    }

    private function getStrategicInsights($startDate, $endDate)
    {
        $insights = [];

        // Revenue insights
        $totalRevenue = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->sum('total_amount');

        if ($totalRevenue > 0) {
            $insights[] = [
                'type' => 'success',
                'title' => 'Performance Financière',
                'message' => 'Revenus totaux de '.number_format($totalRevenue, 0, ',', ' ').' FCFA sur la période',
            ];
        }

        // Customer insights
        $activeCustomers = Customer::whereHas('sales', function ($query) use ($startDate, $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED);
        })->count();

        if ($activeCustomers > 0) {
            $insights[] = [
                'type' => 'info',
                'title' => 'Engagement Client',
                'message' => "{$activeCustomers} clients actifs sur la période",
            ];
        }

        // Inventory insights - only active products
        $lowStockProducts = Product::where('status', Product::STATUS_ACTIVE)
            ->where('current_stock', '<=', 10)
            ->count();
        if ($lowStockProducts > 0) {
            $insights[] = [
                'type' => 'warning',
                'title' => 'Attention Stock',
                'message' => "{$lowStockProducts} produits en stock faible",
            ];
        }

        return $insights;
    }

    public function render(): \Illuminate\Contracts\View\View
    {
        // Set defaults if not provided
        if (!$this->dateFrom) {
            $this->dateFrom = now()->subDays(7)->format('Y-m-d');
        }
        if (!$this->dateTo) {
            $this->dateTo = now()->format('Y-m-d');
        }

        $dateFrom = $this->dateFrom;
        $dateTo = $this->dateTo;

        // Convert to Carbon instances
        $startDate = Carbon::parse($dateFrom)->startOfDay();
        $endDate = Carbon::parse($dateTo)->endOfDay();

        // Get all business intelligence data
        $financialOverview = $this->getFinancialOverview($startDate, $endDate);
        $salesPerformance = $this->getSalesPerformance($startDate, $endDate);
        $customerInsights = $this->getCustomerInsights($startDate, $endDate);
        $inventoryInsights = $this->getInventoryInsights($startDate, $endDate);
        $operationalMetrics = $this->getOperationalMetrics($startDate, $endDate);
        $trendAnalysis = $this->getTrendAnalysis($startDate, $endDate);
        $riskAssessment = $this->getRiskAssessment($startDate, $endDate);
        $strategicInsights = $this->getStrategicInsights($startDate, $endDate);

        return view('livewire.reports.business-intelligence.index', compact('financialOverview', 'salesPerformance', 'customerInsights', 'inventoryInsights', 'operationalMetrics', 'trendAnalysis', 'riskAssessment', 'strategicInsights', 'dateFrom', 'dateTo'));
    }
}


