<?php

namespace App\Http\Controllers\Api\V1\Admin;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\User;
use App\Models\Product;
use App\Models\OrderItem;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class AdminDashboardController extends Controller
{
    public function index()
    {
        // Check if user is admin
        if (auth()->user()->role !== 'admin') {
            return response()->json(['error' => 'Forbidden'], 403);
        }

        if (request('chart_only')) {
            $timeframe = request('timeframe', '30d');
            $year = request('year', Carbon::now()->year);
            $chartData = $this->getChartData($timeframe, $year);
            return response()->json([
                'chart_data' => $chartData
            ]);
        }

        // 1. Stats Cards
        $totalRevenue = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->sum('total');

        $totalOrders = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->count();

        $totalCustomers = User::where('role', 'customer')->count();
        $conversionRate = $totalCustomers > 0 ? round(($totalOrders / $totalCustomers) * 100, 2) : 0;

        // Calculate trends comparing this month vs last month
        $startOfThisMonth = Carbon::now()->startOfMonth();
        $startOfLastMonth = Carbon::now()->subMonth()->startOfMonth();
        $endOfLastMonth = Carbon::now()->subMonth()->endOfMonth();

        // Revenue trend
        $revenueThisMonth = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->where('created_at', '>=', $startOfThisMonth)
            ->sum('total');
        $revenueLastMonth = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->whereBetween('created_at', [$startOfLastMonth, $endOfLastMonth])
            ->sum('total');
        $revenueTrend = 0;
        if ($revenueLastMonth > 0) {
            $revenueTrend = round((($revenueThisMonth - $revenueLastMonth) / $revenueLastMonth) * 100, 1);
        } elseif ($revenueThisMonth > 0) {
            $revenueTrend = 100.0;
        }

        // Orders trend
        $ordersThisMonth = Order::where('created_at', '>=', $startOfThisMonth)->count();
        $ordersLastMonth = Order::whereBetween('created_at', [$startOfLastMonth, $endOfLastMonth])->count();
        $ordersTrend = 0;
        if ($ordersLastMonth > 0) {
            $ordersTrend = round((($ordersThisMonth - $ordersLastMonth) / $ordersLastMonth) * 100, 1);
        } elseif ($ordersThisMonth > 0) {
            $ordersTrend = 100.0;
        }

        // Customers trend
        $customersThisMonth = User::where('role', 'customer')
            ->where('created_at', '>=', $startOfThisMonth)
            ->count();
        $customersLastMonth = User::where('role', 'customer')
            ->whereBetween('created_at', [$startOfLastMonth, $endOfLastMonth])
            ->count();
        $customersTrend = 0;
        if ($customersLastMonth > 0) {
            $customersTrend = round((($customersThisMonth - $customersLastMonth) / $customersLastMonth) * 100, 1);
        } elseif ($customersThisMonth > 0) {
            $customersTrend = 100.0;
        }

        // Conversion trend
        $conversionRateThisMonth = $customersThisMonth > 0 ? ($ordersThisMonth / $customersThisMonth) * 100 : 0;
        $conversionRateLastMonth = $customersLastMonth > 0 ? ($ordersLastMonth / $customersLastMonth) * 100 : 0;
        $conversionTrend = 0;
        if ($conversionRateLastMonth > 0) {
            $conversionTrend = round((($conversionRateThisMonth - $conversionRateLastMonth) / $conversionRateLastMonth) * 100, 1);
        } elseif ($conversionRateThisMonth > 0) {
            $conversionTrend = 100.0;
        }

        // --- REAL METRICS FOR REPORTS ---
        // total_stock_value
        $totalStockValue = 0;
        $products = Product::with('variants')->get();
        foreach ($products as $product) {
            if ($product->variants->isNotEmpty()) {
                foreach ($product->variants as $variant) {
                    $price = $variant->price ?: $product->price;
                    $totalStockValue += $variant->stock * $price;
                }
            } else {
                $totalStockValue += $product->stock * $product->price;
            }
        }

        // low_stock_count
        $lowStockCount = Product::where('status', 'active')
            ->where('stock', '<=', 5)
            ->count();

        // redeemed_vouchers_value
        $redeemedVouchersVal = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->sum('discount_amount');

        // popular_voucher
        $popularVoucherRow = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->whereNotNull('voucher_id')
            ->select('voucher_id', DB::raw('count(*) as count'))
            ->groupBy('voucher_id')
            ->orderBy('count', 'desc')
            ->first();
        $popularVoucherCode = '-';
        if ($popularVoucherRow) {
            $voucher = \App\Models\Voucher::find($popularVoucherRow->voucher_id);
            if ($voucher) {
                $popularVoucherCode = $voucher->code;
            }
        } else {
            $firstVoucher = \App\Models\Voucher::where('end_date', '>', now())->first();
            if ($firstVoucher) {
                $popularVoucherCode = $firstVoucher->code;
            }
        }

        // 2. Sales per Day (last 30 days)
        $salesPerDay = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->where('created_at', '>=', Carbon::now()->subDays(30))
            ->select(
                DB::raw('DATE(created_at) as date'),
                DB::raw('SUM(total) as revenue'),
                DB::raw('COUNT(id) as orders')
            )
            ->groupBy('date')
            ->orderBy('date', 'asc')
            ->get();

        // 3. Sales per Month (last 12 months)
        $salesPerMonth = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->where('created_at', '>=', Carbon::now()->subMonths(12))
            ->select(
                DB::raw("DATE_FORMAT(created_at, '%Y-%m') as month"),
                DB::raw('SUM(total) as revenue'),
                DB::raw('COUNT(id) as orders')
            )
            ->groupBy('month')
            ->orderBy('month', 'asc')
            ->get();

        // 4. Best Selling Products
        $bestSellers = OrderItem::whereHas('order', function($query) {
                $query->whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed']);
            })
            ->select('product_id', DB::raw('SUM(qty) as total_qty'), DB::raw('SUM(qty * price) as total_revenue'))
            ->with(['product:id,name,price'])
            ->groupBy('product_id')
            ->orderBy('total_qty', 'desc')
            ->take(5)
            ->get();

        // 5. Recent Orders
        $recentOrders = Order::with('user')
            ->latest()
            ->take(5)
            ->get();

        $availableYears = Order::selectRaw('YEAR(created_at) as year')
            ->distinct()
            ->orderBy('year', 'desc')
            ->pluck('year')
            ->toArray();

        if (empty($availableYears)) {
            $availableYears = [Carbon::now()->year];
        }

        $timeframe = request('timeframe', '30d');
        $year = request('year', Carbon::now()->year);
        $chartData = $this->getChartData($timeframe, $year);

        return response()->json([
            'stats' => [
                'total_revenue' => (float)$totalRevenue,
                'total_orders' => $totalOrders,
                'total_customers' => $totalCustomers,
                'conversion_rate' => $conversionRate,
                'revenue_trend' => (float)$revenueTrend,
                'orders_trend' => (float)$ordersTrend,
                'customers_trend' => (float)$customersTrend,
                'conversion_trend' => (float)$conversionTrend,
                'total_stock_value' => (float)$totalStockValue,
                'low_stock_count' => $lowStockCount,
                'redeemed_vouchers_value' => (float)$redeemedVouchersVal,
                'popular_voucher' => $popularVoucherCode
            ],
            'sales_per_day' => $salesPerDay,
            'sales_per_month' => $salesPerMonth,
            'best_sellers' => $bestSellers,
            'recent_orders' => $recentOrders,
            'available_years' => $availableYears,
            'chart_data' => $chartData
        ]);
    }

    public function getNotifications()
    {
        if (auth()->user()->role !== 'admin') {
            return response()->json(['error' => 'Forbidden'], 403);
        }

        $notifications = [];
        $idCounter = 1;

        // 1. Orders (Last 5 orders)
        $orders = Order::with(['user', 'payment'])
            ->latest()
            ->take(5)
            ->get();

        foreach ($orders as $order) {
            $hasProof = $order->status === 'waiting_payment' && $order->payment && $order->payment->payment_proof;
            $isUnread = in_array($order->status, ['pending', 'waiting_payment', 'paid']);
            
            $title = 'Pesanan Baru #' . $order->invoice_number;
            if ($order->status === 'paid') {
                $title = 'Pesanan Dibayar #' . $order->invoice_number;
            } elseif ($hasProof) {
                $title = 'Pesanan Menunggu Verifikasi #' . $order->invoice_number;
            }

            $notifications[] = [
                'id' => $idCounter++,
                'key' => 'order-' . $order->id . '-' . $order->status . ($hasProof ? '-proof' : ''),
                'title' => $title,
                'description' => ($order->user->name ?? 'Pelanggan') . ' melakukan pembelian senilai Rp ' . number_format($order->total, 0, ',', '.'),
                'time' => $order->created_at->diffForHumans(),
                'type' => 'order',
                'isUnread' => $isUnread,
                'created_at' => $order->created_at->toIso8601String(),
            ];
        }

        // 2. Low Stock Products (where stock <= 5)
        $lowStockProducts = Product::where('stock', '<=', 5)
            ->where('status', 'active')
            ->take(5)
            ->get();

        foreach ($lowStockProducts as $product) {
            $notifications[] = [
                'id' => $idCounter++,
                'key' => 'stock-' . $product->id . '-' . $product->stock,
                'title' => 'Peringatan Stok Rendah!',
                'description' => "Stok produk '" . $product->name . "' tersisa " . $product->stock . " pcs",
                'time' => $product->updated_at->diffForHumans(),
                'type' => 'stock',
                'isUnread' => true,
                'created_at' => $product->updated_at->toIso8601String(),
            ];
        }

        // 3. Vouchers Ending Soon (ending in the next 48 hours)
        $endingVouchers = \App\Models\Voucher::where('end_date', '>', now())
            ->where('end_date', '<', now()->addDays(2))
            ->take(3)
            ->get();

        foreach ($endingVouchers as $voucher) {
            $notifications[] = [
                'id' => $idCounter++,
                'key' => 'voucher-' . $voucher->id,
                'title' => 'Voucher Segera Berakhir',
                'description' => "Promo kupon '" . $voucher->code . "' akan berakhir dalam 48 jam",
                'time' => \Carbon\Carbon::parse($voucher->end_date)->diffForHumans(),
                'type' => 'voucher',
                'isUnread' => false,
                'created_at' => $voucher->created_at ? $voucher->created_at->toIso8601String() : now()->toIso8601String(),
            ];
        }

        // 4. Contact Messages (Last 5 unread messages)
        $unreadMessages = \App\Models\ContactMessage::where('status', 'unread')
            ->latest()
            ->take(5)
            ->get();

        foreach ($unreadMessages as $msg) {
            $notifications[] = [
                'id' => $idCounter++,
                'key' => 'message-' . $msg->id,
                'title' => 'Pesan Masuk Baru',
                'description' => "Dari " . $msg->name . ": " . \Illuminate\Support\Str::limit($msg->subject, 40),
                'time' => $msg->created_at->diffForHumans(),
                'type' => 'message',
                'isUnread' => true,
                'created_at' => $msg->created_at->toIso8601String(),
            ];
        }

        // 5. Withdrawal Requests (Last 5 pending requests)
        $pendingWithdrawals = \App\Models\WithdrawalRequest::with('user')
            ->where('status', 'pending')
            ->latest()
            ->take(5)
            ->get();

        foreach ($pendingWithdrawals as $withdraw) {
            $notifications[] = [
                'id' => $idCounter++,
                'key' => 'withdraw-' . $withdraw->id,
                'title' => 'Permintaan Penarikan Komisi',
                'description' => "Dari " . ($withdraw->user->name ?? 'Pelanggan') . " sebesar Rp " . number_format($withdraw->amount, 0, ',', '.'),
                'time' => $withdraw->created_at->diffForHumans(),
                'type' => 'withdraw',
                'isUnread' => true,
                'created_at' => $withdraw->created_at->toIso8601String(),
            ];
        }

        return response()->json($notifications);
    }

    private function getChartData($timeframe, $year = null)
    {
        $query = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed']);

        switch ($timeframe) {
            case '1d':
                return $query->where('created_at', '>=', Carbon::now()->subDay())
                    ->select(
                        DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') as date"),
                        DB::raw('SUM(total) as revenue'),
                        DB::raw('COUNT(id) as orders')
                    )
                    ->groupBy('date')
                    ->orderBy('date', 'asc')
                    ->get();

            case '7d':
                return $query->where('created_at', '>=', Carbon::now()->subDays(7))
                    ->select(
                        DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as date"),
                        DB::raw('SUM(total) as revenue'),
                        DB::raw('COUNT(id) as orders')
                    )
                    ->groupBy('date')
                    ->orderBy('date', 'asc')
                    ->get();

            case '1y':
                return $query->where('created_at', '>=', Carbon::now()->subMonths(12))
                    ->select(
                        DB::raw("DATE_FORMAT(created_at, '%Y-%m') as date"),
                        DB::raw('SUM(total) as revenue'),
                        DB::raw('COUNT(id) as orders')
                    )
                    ->groupBy('date')
                    ->orderBy('date', 'asc')
                    ->get();

            case 'year':
                $selectedYear = $year ?: Carbon::now()->year;
                return $query->whereYear('created_at', $selectedYear)
                    ->select(
                        DB::raw("DATE_FORMAT(created_at, '%Y-%m') as date"),
                        DB::raw('SUM(total) as revenue'),
                        DB::raw('COUNT(id) as orders')
                    )
                    ->groupBy('date')
                    ->orderBy('date', 'asc')
                    ->get();

            case '30d':
            default:
                return $query->where('created_at', '>=', Carbon::now()->subDays(30))
                    ->select(
                        DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as date"),
                        DB::raw('SUM(total) as revenue'),
                        DB::raw('COUNT(id) as orders')
                    )
                    ->groupBy('date')
                    ->orderBy('date', 'asc')
                    ->get();
        }
    }

    public function getAccountingReports()
    {
        if (auth()->user()->role !== 'admin') {
            return response()->json(['error' => 'Forbidden'], 403);
        }

        $year = request('year', Carbon::now()->year);
        $month = request('month'); // optional

        // P&L Order Query
        $orderQuery = Order::with(['items.product'])
            ->whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->whereYear('created_at', $year);

        if ($month) {
            $orderQuery->whereMonth('created_at', $month);
        }
        $orders = $orderQuery->get();

        // 1. PROFIT & LOSS (Laba Rugi)
        $revenue = 0;
        $onlineRevenue = 0;
        $posRevenue = 0;
        $cogs = 0;
        $onlineCogs = 0;
        $posCogs = 0;
        $taxCollected = 0;
        $onlineTax = 0;
        $posTax = 0;
        $shippingCollected = 0;
        $posTransactions = 0;
        $onlineTransactions = 0;

        foreach ($orders as $order) {
            $shippingCollected += $order->shipping_cost;
            $taxCollected += $order->tax_amount;
            
            $isPOS = str_starts_with($order->shipping_address ?? '', 'POS In-Store Purchase');
            
            // Net sales = total order - shipping cost - tax amount
            $netSales = ($order->total - $order->shipping_cost - $order->tax_amount);
            $revenue += $netSales;

            if ($isPOS) {
                $posRevenue += $netSales;
                $posTax += $order->tax_amount;
                $posTransactions++;
            } else {
                $onlineRevenue += $netSales;
                $onlineTax += $order->tax_amount;
                $onlineTransactions++;
            }

            foreach ($order->items as $item) {
                // HPP (COGS) based on cost_price
                $cost = $item->product ? ($item->product->cost_price ?? 0) : 0;
                $itemCogs = $cost * $item->qty;
                $cogs += $itemCogs;

                if ($isPOS) {
                    $posCogs += $itemCogs;
                } else {
                    $onlineCogs += $itemCogs;
                }
            }
        }

        // Commissions in time frame
        $commissionQuery = \App\Models\AffiliateCommission::whereIn('status', ['approved', 'withdrawn', 'paid'])
            ->whereYear('created_at', $year);
        if ($month) {
            $commissionQuery->whereMonth('created_at', $month);
        }
        $commissionsExpense = $commissionQuery->sum('commission_amount');

        $grossProfit = $revenue - $cogs;
        $netProfit = $grossProfit - $commissionsExpense;

        // 2. BALANCE SHEET (Neraca - Cumulative/All-time)
        // Cash & Bank Calculation
        $allTimePaidOrders = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])->sum('total');
        $allTimePaidCommissions = \App\Models\AffiliateCommission::where('status', 'paid')->sum('commission_amount');
        
        $currentCash = $allTimePaidOrders - $allTimePaidCommissions;

        // Inventory Value
        $currentInventory = 0;
        $allProducts = Product::all();
        foreach ($allProducts as $p) {
            $cost = $p->cost_price > 0 ? $p->cost_price : 0;
            $currentInventory += $p->stock * $cost;
        }

        $totalAssets = $currentCash + $currentInventory;

        // Liabilities
        $commissionsPayable = \App\Models\AffiliateCommission::where('status', 'approved')->sum('commission_amount');
        $taxPayable = Order::whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])->sum('tax_amount');
        $totalLiabilities = $commissionsPayable + $taxPayable;

        // Equity
        // Calculate retained earnings all-time
        $allTimeOrders = Order::with('items.product')
            ->whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->get();
        $allTimeRevenue = 0;
        $allTimeCogs = 0;
        foreach ($allTimeOrders as $o) {
            $allTimeRevenue += ($o->total - $o->shipping_cost - $o->tax_amount);
            foreach ($o->items as $item) {
                $cost = $item->product ? ($item->product->cost_price ?? 0) : 0;
                $allTimeCogs += $cost * $item->qty;
            }
        }
        $allTimeCommissions = \App\Models\AffiliateCommission::whereIn('status', ['approved', 'withdrawn', 'paid'])->sum('commission_amount');
        
        $retainedEarnings = $allTimeRevenue - $allTimeCogs - $allTimeCommissions;
        $initialCapital = $totalAssets - $totalLiabilities - $retainedEarnings;

        // 3. TAX LOG
        $taxLogs = Order::with('user')
            ->whereIn('status', ['paid', 'processing', 'shipped', 'delivered', 'completed'])
            ->where('tax_amount', '>', 0)
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function($o) {
                return [
                    'id' => $o->id,
                    'invoice_number' => $o->invoice_number,
                    'user' => $o->user->name ?? 'Pelanggan',
                    'created_at' => $o->created_at ? $o->created_at->toIso8601String() : null,
                    'subtotal' => (float) ($o->total - $o->tax_amount),
                    'tax_amount' => (float) $o->tax_amount
                ];
            });

        return response()->json([
            'profit_loss' => [
                'revenue' => (float) $revenue,
                'online_revenue' => (float) $onlineRevenue,
                'pos_revenue' => (float) $posRevenue,
                'cogs' => (float) $cogs,
                'online_cogs' => (float) $onlineCogs,
                'pos_cogs' => (float) $posCogs,
                'gross_profit' => (float) $grossProfit,
                'commissions_expense' => (float) $commissionsExpense,
                'tax_collected' => (float) $taxCollected,
                'online_tax_collected' => (float) $onlineTax,
                'pos_tax_collected' => (float) $posTax,
                'shipping_collected' => (float) $shippingCollected,
                'net_profit' => (float) $netProfit,
                'pos_transactions_count' => $posTransactions,
                'online_transactions_count' => $onlineTransactions,
            ],
            'balance_sheet' => [
                'cash' => (float) $currentCash,
                'inventory' => (float) $currentInventory,
                'total_assets' => (float) $totalAssets,
                'commissions_payable' => (float) $commissionsPayable,
                'tax_payable' => (float) $taxPayable,
                'total_liabilities' => (float) $totalLiabilities,
                'initial_capital' => (float) $initialCapital,
                'retained_earnings' => (float) $retainedEarnings,
                'total_equity' => (float) ($initialCapital + $retainedEarnings)
            ],
            'tax_report' => [
                'total_tax' => (float) $taxLogs->sum('tax_amount'),
                'tax_logs' => $taxLogs
            ]
        ]);
    }
}
