<?php

namespace App\Livewire\Reports;

use App\Models\{Sale, Customer};
use Carbon\Carbon;
use Livewire\Attributes\Layout;
use Livewire\Component;
use App\Models\PaymentMethod;
use App\Models\SaleItem;
use Illuminate\Support\Facades\DB;
use App\Models\SaleType;

#[Layout('layouts.dashboard')]
class SalesPerformance extends Component
{
    public string $period = 'month';
    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 getSalesTrends($startDate, $endDate)
    {
        $trends = [];
        $current = $startDate->copy();

        while ($current->lte($endDate)) {
            $dayStart = $current->copy()->startOfDay();
            $dayEnd = $current->copy()->endOfDay();

            $sales = Sale::whereBetween('created_at', [$dayStart, $dayEnd])
                ->where('status', Sale::STATUS_COMPLETED)
                ->get();

            $trends[] = [
                'date' => $current->format('Y-m-d'),
                'date_label' => $current->format('d/m'),
                'sales_count' => $sales->count(),
                'total_revenue' => $sales->sum('total_amount'),
                'transactions' => $sales->count(),
                'average_sale' => $sales->count() > 0 ? $sales->sum('total_amount') / $sales->count() : 0,
            ];

            $current->addDay();
        }

        return $trends;
    }

    private function getRevenueByPaymentMethod($startDate, $endDate)
    {
        $paymentMethods = PaymentMethod::all();
        $revenue = [];

        foreach ($paymentMethods as $method) {
            $total = Sale::where('payment_method_id', $method->id)
                ->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED)
                ->sum('total_amount');

            $count = Sale::where('payment_method_id', $method->id)
                ->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED)
                ->count();

            $revenue[] = [
                'payment_method_name' => $method->name,
                'total_revenue' => $total,
                'total_orders' => $count,
                'percentage' => 0, // Will be calculated in view
                'color' => $this->getPaymentMethodColor($method->id),
            ];
        }

        // Calculate percentages
        $totalRevenue = collect($revenue)->sum('total_revenue');
        foreach ($revenue as &$item) {
            $item['percentage'] = $totalRevenue > 0 ? round(($item['total_revenue'] / $totalRevenue) * 100, 1) : 0;
        }

        return collect($revenue)->sortByDesc('total_revenue')->values();
    }

    private function getTopProducts($startDate, $endDate)
    {
        return SaleItem::with(['product', 'sale'])
            ->whereHas('sale', function ($query) use ($startDate, $endDate) {
                $query->whereBetween('created_at', [$startDate, $endDate])
                    ->where('status', Sale::STATUS_COMPLETED);
            })
            ->select(
                'product_id',
                DB::raw('SUM(quantity) as total_quantity'),
                DB::raw('SUM(quantity * unit_price) as total_revenue'),
                DB::raw('COUNT(DISTINCT sale_id) as sale_count')
            )
            ->groupBy('product_id')
            ->orderByDesc('total_revenue')
            ->limit(10)
            ->get()
            ->map(function ($item) {
                return [
                    'product' => $item->product,
                    'total_quantity' => $item->total_quantity,
                    'total_revenue' => $item->total_revenue,
                    'sale_count' => $item->sale_count,
                    'average_price' => $item->total_quantity > 0 ? $item->total_revenue / $item->total_quantity : 0,
                ];
            });
    }

    private function getSalesByUser($startDate, $endDate)
    {
        return Sale::with('user')
            ->whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->select(
                'user_id',
                DB::raw('COUNT(*) as sales_count'),
                DB::raw('SUM(total_amount) as total_revenue'),
                DB::raw('AVG(total_amount) as average_sale')
            )
            ->groupBy('user_id')
            ->orderByDesc('total_revenue')
            ->get()
            ->map(function ($sale) {
                return [
                    'user' => $sale->user,
                    'sales_count' => $sale->sales_count,
                    'total_revenue' => $sale->total_revenue,
                    'average_sale' => $sale->average_sale,
                ];
            });
    }

    private function getCustomerMetrics($startDate, $endDate)
    {
        $totalCustomers = Customer::count();
        $newCustomers = Customer::whereBetween('created_at', [$startDate, $endDate])->count();
        $activeCustomers = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->distinct('customer_id')
            ->count('customer_id');

        $repeatCustomers = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED)
            ->whereNotNull('customer_id')
            ->select('customer_id', DB::raw('COUNT(*) as purchase_count'))
            ->groupBy('customer_id')
            ->having('purchase_count', '>', 1)
            ->count();

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

        return [
            'total_customers' => $totalCustomers,
            'new_customers' => $newCustomers,
            'active_customers' => $activeCustomers,
            'repeat_customers' => $repeatCustomers,
            'customer_retention_rate' => $activeCustomers > 0 ? round(($repeatCustomers / $activeCustomers) * 100, 1) : 0,
            'average_order_value' => $averageOrderValue,
        ];
    }

    private function getSalesSummary($startDate, $endDate)
    {
        $sales = Sale::whereBetween('created_at', [$startDate, $endDate])
            ->where('status', Sale::STATUS_COMPLETED);

        $totalRevenue = $sales->sum('total_amount');
        $totalSales = $sales->count();
        $averageSale = $totalSales > 0 ? $totalRevenue / $totalSales : 0;

        // Previous period comparison
        $previousStart = $startDate->copy()->subDays($startDate->diffInDays($endDate) + 1);
        $previousEnd = $startDate->copy()->subDay();

        $previousSales = Sale::whereBetween('created_at', [$previousStart, $previousEnd])
            ->where('status', Sale::STATUS_COMPLETED);

        $previousRevenue = $previousSales->sum('total_amount');
        $previousCount = $previousSales->count();

        $revenueGrowth = $previousRevenue > 0 ? round((($totalRevenue - $previousRevenue) / $previousRevenue) * 100, 1) : 0;
        $salesGrowth = $previousCount > 0 ? round((($totalSales - $previousCount) / $previousCount) * 100, 1) : 0;

        return [
            'total_revenue' => $totalRevenue,
            'total_sales' => $totalSales,
            'average_sale' => $averageSale,
            'revenue_growth' => $revenueGrowth,
            'sales_growth' => $salesGrowth,
            'previous_revenue' => $previousRevenue,
            'previous_sales' => $previousCount,
        ];
    }

    private function getSalesByType($startDate, $endDate)
    {
        $saleTypes = SaleType::all();
        $sales = [];

        foreach ($saleTypes as $type) {
            $total = Sale::where('sale_type_id', $type->id)
                ->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED)
                ->sum('total_amount');

            $count = Sale::where('sale_type_id', $type->id)
                ->whereBetween('created_at', [$startDate, $endDate])
                ->where('status', Sale::STATUS_COMPLETED)
                ->count();

            $sales[] = [
                'sale_type_name' => $type->name,
                'total_revenue' => $total,
                'total_orders' => $count,
                'average_order_value' => $count > 0 ? $total / $count : 0,
                'percentage' => 0, // Will be calculated below
                'color' => $this->getSaleTypeColor($type->id),
            ];
        }

        // Calculate percentages
        $totalAmount = collect($sales)->sum('total_revenue');
        foreach ($sales as &$item) {
            $item['percentage'] = $totalAmount > 0 ? round(($item['total_revenue'] / $totalAmount) * 100, 1) : 0;
        }

        return collect($sales)->sortByDesc('total_revenue')->values();
    }

    private function getPaymentMethodColor($methodId)
    {
        $colors = [
            1 => '#10B981', // Cash - Green
            2 => '#F59E0B', // Debt - Orange
            3 => '#8B5CF6', // Mobile Money - Purple
            4 => '#3B82F6', // Card - Blue
            5 => '#EF4444', // Transfer - Red
        ];

        return $colors[$methodId] ?? '#6B7280';
    }

    private function getSaleTypeColor($typeId)
    {
        $colors = [
            1 => '#3B82F6', // Prescription - Blue
            2 => '#10B981', // OTC - Green
            3 => '#F59E0B', // Wholesale - Orange
        ];

        return $colors[$typeId] ?? '#6B7280';
    }

    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;
        
        $startDate = Carbon::parse($dateFrom)->startOfDay();
        $endDate = Carbon::parse($dateTo)->endOfDay();

        // Sales trends data
        $salesTrends = $this->getSalesTrends($startDate, $endDate);

        // Revenue by payment method
        $revenueByPaymentMethod = $this->getRevenueByPaymentMethod($startDate, $endDate);

        // Top products
        $topProducts = $this->getTopProducts($startDate, $endDate);

        // Sales by user performance
        $salesByUser = $this->getSalesByUser($startDate, $endDate);

        // Customer metrics
        $customerMetrics = $this->getCustomerMetrics($startDate, $endDate);

        // Sales summary
        $salesSummary = $this->getSalesSummary($startDate, $endDate);

        // Sales by type
        $salesByType = $this->getSalesByType($startDate, $endDate);

        return view('livewire.reports.sales.index', compact('salesTrends', 'revenueByPaymentMethod', 'topProducts', 'salesByUser', 'customerMetrics', 'salesSummary', 'salesByType', 'dateFrom', 'dateTo'));
    }
}
