<?php

namespace App\Http\Controllers\Api;

use App\Http\Resources\Reports\CategorySaleResource;
use App\Http\Resources\Reports\InventoryValuationResource;
use App\Http\Resources\Reports\TopProductResource;
use App\Http\Resources\DailySalesSummaryResource;
use App\Models\DailySalesSummary;
use App\Models\OrderItem;
use App\Models\StockLevel;
use App\Services\DailySummaryService;
use Illuminate\Support\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class ReportController extends ApiController
{
    public function __construct(private readonly DailySummaryService $dailySummaryService)
    {
    }

    public function dailySales(Request $request): AnonymousResourceCollection
    {
        $dateFrom = $request->date('date_from')?->format('Y-m-d') ?? now()->toDateString();
        $dateTo = $request->date('date_to')?->format('Y-m-d') ?? $dateFrom;

        if ($request->boolean('refresh')) {
            $period = Carbon::parse($dateFrom);
            $end = Carbon::parse($dateTo);

            while ($period->lte($end)) {
                $this->dailySummaryService->rebuildForDate(
                    $period->toDateString(),
                    $this->currentCompanyId($request),
                    $this->currentBranchId($request),
                );
                $period->addDay();
            }
        }

        $query = DailySalesSummary::query()
            ->where('company_id', $this->currentCompanyId($request));

        if ($branchId = $this->currentBranchId($request)) {
            $query->where('branch_id', $branchId);
        }

        $summaries = $query->whereBetween('summary_date', [$dateFrom, $dateTo])
            ->orderBy('summary_date')
            ->get();

        return DailySalesSummaryResource::collection($summaries);
    }

    public function topProducts(Request $request): AnonymousResourceCollection
    {
        $dateFrom = $request->date('date_from')?->format('Y-m-d') ?? now()->subMonth()->toDateString();
        $dateTo = $request->date('date_to')?->format('Y-m-d') ?? now()->toDateString();

        $rows = OrderItem::query()
            ->selectRaw('product_id, name as product_name, sku, SUM(quantity) as total_quantity, SUM(total_amount) as total_revenue, SUM(quantity * cost_price) as total_cost')
            ->whereHas('order', function ($query) use ($request) {
                $query->where('company_id', $this->currentCompanyId($request))
                    ->where('status', 'completed');
                
                if ($branchId = $this->currentBranchId($request)) {
                    $query->where('branch_id', $branchId);
                }
            })
            ->whereBetween('created_at', [$dateFrom . ' 00:00:00', $dateTo . ' 23:59:59'])
            ->groupBy('product_id', 'product_name', 'sku')
            ->orderByDesc('total_revenue')
            ->limit(10)
            ->get();

        return TopProductResource::collection($rows);
    }

    public function categorySales(Request $request): AnonymousResourceCollection
    {
        $dateFrom = $request->date('date_from')?->format('Y-m-d') ?? now()->subMonth()->toDateString();
        $dateTo = $request->date('date_to')?->format('Y-m-d') ?? now()->toDateString();

        $rows = OrderItem::query()
            ->join('products', 'order_items.product_id', '=', 'products.id')
            ->join('categories', 'products.category_id', '=', 'categories.id')
            ->selectRaw('categories.id as category_id, categories.name as category_name, SUM(order_items.quantity) as total_quantity, SUM(order_items.total_amount) as total_revenue')
            ->whereHas('order', function ($query) use ($request) {
                $query->where('company_id', $this->currentCompanyId($request))
                    ->where('status', 'completed');

                if ($branchId = $this->currentBranchId($request)) {
                    $query->where('branch_id', $branchId);
                }
            })
            ->whereBetween('order_items.created_at', [$dateFrom . ' 00:00:00', $dateTo . ' 23:59:59'])
            ->groupBy('categories.id', 'categories.name')
            ->orderByDesc('total_revenue')
            ->get();

        return CategorySaleResource::collection($rows);
    }

    public function inventoryValuation(Request $request): InventoryValuationResource
    {
        $query = StockLevel::query()
            ->join('products', 'stock_levels.product_id', '=', 'products.id')
            ->selectRaw('COUNT(DISTINCT product_id) as total_items, SUM(stock_levels.quantity) as stock_quantity, SUM(stock_levels.quantity * products.cost_price) as total_cost_value, SUM(stock_levels.quantity * products.selling_price) as total_retail_value')
            ->whereHas('product', function ($q) use ($request) {
                $q->where('company_id', $this->currentCompanyId($request));
            });

        if ($branchId = $this->currentBranchId($request)) {
            $query->where('stock_levels.branch_id', $branchId);
        }

        $summary = $query->first();

        return new InventoryValuationResource($summary);
    }
}
