<?php

namespace App\Http\Controllers;

use App\Models\Customer;
use App\Models\Debt;
use App\Models\Expense;
use App\Models\Product;
use App\Models\PurchaseOrder;
use App\Models\Sale;
use App\Models\Supplier;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class BusinessDashboardController extends Controller
{
    public function export(Request $request)
    {
        // Export implementation
    }

    public function print(Request $request)
    {
        try {
            $request->validate([
                'print_date_from' => 'required|date',
                'print_date_to' => 'required|date|after_or_equal:print_date_from',
            ]);

            $dateFrom = Carbon::parse($request->get('print_date_from'));
            $dateTo = Carbon::parse($request->get('print_date_to'));

            $startDate = $dateFrom->startOfDay();
            $endDate = $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);
            $riskAssessment = $this->getRiskAssessment($startDate, $endDate);

            return view('livewire.reports.business-intelligence.print', [
                'financialOverview' => $financialOverview,
                'salesPerformance' => $salesPerformance,
                'customerInsights' => $customerInsights,
                'inventoryInsights' => $inventoryInsights,
                'operationalMetrics' => $operationalMetrics,
                'riskAssessment' => $riskAssessment,
                'dateFrom' => $dateFrom,
                'dateTo' => $dateTo,
            ]);
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors de l\'impression: '.$e->getMessage());
        }
    }

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

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

        $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'));

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

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

        $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): array
    {
        $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;

        $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): array
    {
        $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();

        $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): array
    {
        // 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): array
    {
        $totalSuppliers = Supplier::count();
        $activeSuppliers = Supplier::whereHas('purchaseOrders', function ($query) use ($startDate, $endDate) {
            $query->whereBetween('created_at', [$startDate, $endDate]);
        })->count();

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

        $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 getRiskAssessment($startDate, $endDate): array
    {
        $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,
        ];
    }
}
