<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Sale;
use App\Models\SaleItem;
use App\Models\Purchase;
use App\Models\Product;
use App\Models\SalePayment;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class ReportsController extends Controller
{
    public function sales(Request $request): JsonResponse
    {
        $user = Auth::user();
        $isAdmin = $user->role && $user->role->slug === 'admin';

        $dateFrom = $request->get('date_from', now()->subDays(30)->toDateString());
        $dateTo = $request->get('date_to', now()->toDateString());
        $groupBy = $request->get('group_by', 'day'); // day, week, month, year

        $query = Sale::whereBetween('sale_date', [$dateFrom, $dateTo])
            ->where('status', 'completed');

        if (!$isAdmin) {
            $query->where('user_id', $user->id);
        }

        // Sales by payment method
        $byMethod = SalePayment::whereHas('sale', function ($q) use ($dateFrom, $dateTo, $user, $isAdmin) {
            $q->whereBetween('sale_date', [$dateFrom, $dateTo])
              ->where('status', 'completed');
            if (!$isAdmin) {
                $q->where('user_id', $user->id);
            }
        })
        ->select('payment_method', DB::raw('SUM(amount) as total'))
        ->groupBy('payment_method')
        ->get();

        // Sales by date
        $dateFormat = 'Y-m-d';
        if ($groupBy === 'week') {
            $dateFormat = 'Y-W';
        } elseif ($groupBy === 'month') {
            $dateFormat = 'Y-m';
        } elseif ($groupBy === 'year') {
            $dateFormat = 'Y';
        }

        $byDate = Sale::whereBetween('sale_date', [$dateFrom, $dateTo])
            ->where('status', 'completed')
            ->when(!$isAdmin, fn($q) => $q->where('user_id', $user->id))
            ->select(
                DB::raw("DATE_FORMAT(sale_date, '%Y-%m-%d') as date"),
                DB::raw('COUNT(*) as count'),
                DB::raw('SUM(total) as total')
            )
            ->groupBy('date')
            ->orderBy('date')
            ->get();

        // Top products
        $topProducts = SaleItem::whereHas('sale', function ($q) use ($dateFrom, $dateTo, $user, $isAdmin) {
            $q->whereBetween('sale_date', [$dateFrom, $dateTo])
              ->where('status', 'completed');
            if (!$isAdmin) {
                $q->where('user_id', $user->id);
            }
        })
        ->select('product_id', DB::raw('SUM(quantity) as quantity_sold'), DB::raw('SUM(subtotal) as total'))
        ->groupBy('product_id')
        ->orderByDesc('total')
        ->limit(10)
        ->get();

        foreach ($topProducts as $item) {
            $product = Product::find($item->product_id);
            $item->product_name = $product ? $product->name : 'Unknown';
        }

        $summary = [
            'total_sales' => $query->count(),
            'total_revenue' => $query->sum('total'),
            'average_sale' => $query->avg('total') ?? 0,
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
        ];

        return response()->json([
            'summary' => $summary,
            'by_method' => $byMethod,
            'by_date' => $byDate,
            'top_products' => $topProducts,
        ]);
    }

    public function purchases(Request $request): JsonResponse
    {
        $user = Auth::user();
        $isAdmin = $user->role && $user->role->slug === 'admin';

        $dateFrom = $request->get('date_from', now()->subDays(30)->toDateString());
        $dateTo = $request->get('date_to', now()->toDateString());

        $query = Purchase::whereBetween('purchase_date', [$dateFrom, $dateTo])
            ->where('status', 'completed');

        if (!$isAdmin) {
            $query->where('user_id', $user->id);
        }

        // Purchases by date
        $byDate = Purchase::whereBetween('purchase_date', [$dateFrom, $dateTo])
            ->where('status', 'completed')
            ->when(!$isAdmin, fn($q) => $q->where('user_id', $user->id))
            ->select(
                DB::raw("DATE_FORMAT(purchase_date, '%Y-%m-%d') as date"),
                DB::raw('COUNT(*) as count'),
                DB::raw('SUM(total) as total')
            )
            ->groupBy('date')
            ->orderBy('date')
            ->get();

        $summary = [
            'total_purchases' => $query->count(),
            'total_expenses' => $query->sum('total'),
            'average_purchase' => $query->avg('total') ?? 0,
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
        ];

        return response()->json([
            'summary' => $summary,
            'by_date' => $byDate,
        ]);
    }

    public function inventory(Request $request): JsonResponse
    {
        $user = Auth::user();
        $isAdmin = $user->role && $user->role->slug === 'admin';

        // Stock summary
        $stockSummary = [
            'total_products' => Product::count(),
            'in_stock' => Product::where('stock', '>', 0)->count(),
            'low_stock' => Product::whereRaw('stock <= min_stock')->where('stock', '>', 0)->count(),
            'out_of_stock' => Product::where('stock', 0)->count(),
        ];

        // Inventory value
        $inventoryValue = Product::selectRaw("
            SUM(stock * purchase_price) as total_cost,
            SUM(stock * sale_price) as total_sale,
            SUM(stock) as total_units
        ")->first();

        // Products by category
        $byCategory = Product::select('category_id')
            ->selectRaw('COUNT(*) as count')
            ->selectRaw('SUM(stock) as total_stock')
            ->whereNotNull('category_id')
            ->groupBy('category_id')
            ->get();

        // Low stock products
        $lowStockProducts = Product::with('category')
            ->whereRaw('stock <= min_stock')
            ->orderBy('stock')
            ->limit(20)
            ->get();

        // Out of stock
        $outOfStock = Product::with('category')
            ->where('stock', 0)
            ->orderBy('name')
            ->get();

        return response()->json([
            'stock_summary' => $stockSummary,
            'inventory_value' => $inventoryValue,
            'by_category' => $byCategory,
            'low_stock' => $lowStockProducts,
            'out_of_stock' => $outOfStock,
        ]);
    }

    public function financial(Request $request): JsonResponse
    {
        $user = Auth::user();
        $isAdmin = $user->role && $user->role->slug === 'admin';

        $dateFrom = $request->get('date_from', now()->subDays(30)->toDateString());
        $dateTo = $request->get('date_to', now()->toDateString());

        $salesQuery = Sale::whereBetween('sale_date', [$dateFrom, $dateTo])
            ->where('status', 'completed');
        
        $purchasesQuery = Purchase::whereBetween('purchase_date', [$dateFrom, $dateTo])
            ->where('status', 'completed');

        if (!$isAdmin) {
            $salesQuery->where('user_id', $user->id);
            $purchasesQuery->where('user_id', $user->id);
        }

        $totalRevenue = $salesQuery->sum('total');
        $totalExpenses = $purchasesQuery->sum('total');
        $grossProfit = $totalRevenue - $totalExpenses;

        // Profit margin
        $profitMargin = $totalRevenue > 0 ? (($grossProfit / $totalRevenue) * 100) : 0;

        // Daily summary
        $dailyData = [];
        $dates = [];
        $current = strtotime($dateFrom);
        $end = strtotime($dateTo);
        
        while ($current <= $end) {
            $date = date('Y-m-d', $current);
            $dates[] = $date;
            $current = strtotime('+1 day', $current);
        }

        foreach ($dates as $date) {
            $dayRevenue = Sale::where('sale_date', $date)
                ->where('status', 'completed');
            $dayExpenses = Purchase::where('purchase_date', $date)
                ->where('status', 'completed');

            if (!$isAdmin) {
                $dayRevenue->where('user_id', $user->id);
                $dayExpenses->where('user_id', $user->id);
            }

            $dailyData[] = [
                'date' => $date,
                'revenue' => $dayRevenue->sum('total'),
                'expenses' => $dayExpenses->sum('total'),
                'profit' => $dayRevenue->sum('total') - $dayExpenses->sum('total'),
            ];
        }

        return response()->json([
            'summary' => [
                'total_revenue' => $totalRevenue,
                'total_expenses' => $totalExpenses,
                'gross_profit' => $grossProfit,
                'profit_margin' => round($profitMargin, 2),
                'date_from' => $dateFrom,
                'date_to' => $dateTo,
            ],
            'daily' => $dailyData,
        ]);
    }
}
