<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreBranchRequest;
use App\Http\Requests\UpdateBranchRequest;
use App\Models\Branch;
use App\Services\BranchService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class BranchController extends Controller
{
    public function __construct(private BranchService $branchService) {}

    /**
     * GET /api/branches
     * List all branches for the current organisation.
     */
    public function index(Request $request): JsonResponse
    {
        $branches = Branch::query()
            ->when($request->boolean('active_only'), fn($q) => $q->active())
            ->withCount(['sales', 'purchases'])
            ->orderBy('is_default', 'desc')
            ->orderBy('name')
            ->get();

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

    /**
     * POST /api/branches
     */
    public function store(StoreBranchRequest $request): JsonResponse
    {
        $this->authorize('create', Branch::class);

        $branch = $this->branchService->create($request->validated());

        return response()->json($branch, 201);
    }

    /**
     * GET /api/branches/{branch}
     */
    public function show(Branch $branch): JsonResponse
    {
        $this->authorize('view', $branch);

        return response()->json(
            $branch->load(['users:id,name,email,branch_id', 'productStocks.product:id,name,sku'])
        );
    }

    /**
     * PUT /api/branches/{branch}
     */
    public function update(UpdateBranchRequest $request, Branch $branch): JsonResponse
    {
        $this->authorize('update', $branch);

        $branch = $this->branchService->update($branch, $request->validated());

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

    /**
     * DELETE /api/branches/{branch}
     */
    public function destroy(Branch $branch): JsonResponse
    {
        $this->authorize('delete', $branch);

        $this->branchService->delete($branch);

        return response()->json(['message' => 'Branch deleted successfully.']);
    }

    /**
     * POST /api/branches/{branch}/set-default
     */
    public function setDefault(Branch $branch): JsonResponse
    {
        $this->authorize('update', $branch);

        $branch = $this->branchService->setDefault($branch);

        return response()->json(['message' => 'Default branch updated.', 'branch' => $branch]);
    }

    /**
     * GET /api/branches/{branch}/stock
     * Stock snapshot for a specific branch.
     */
    public function stock(Branch $branch): JsonResponse
    {
        $this->authorize('view', $branch);

        $stocks = $branch->productStocks()
            ->with('product:id,name,sku,unit,low_stock_threshold')
            ->get()
            ->map(fn($s) => [
                'product_id'         => $s->product_id,
                'product_name'       => $s->product?->name,
                'sku'                => $s->product?->sku,
                'unit'               => $s->product?->unit,
                'quantity'           => $s->quantity,
                'low_stock_threshold'=> $s->product?->low_stock_threshold,
                'is_low'             => $s->quantity <= ($s->product?->low_stock_threshold ?? 0),
            ]);

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

    /**
     * GET /api/branches/summary
     * Aggregate KPI stats for every branch in the organisation.
     * Uses DB::table() to bypass BelongsToBranch / BelongsToOrganization Eloquent scopes.
     */
    public function summary(): JsonResponse
    {
        $this->authorize('viewAny', Branch::class);

        $orgId      = app('current_organization_id');
        $today      = today()->toDateString();
        $monthStart = now()->startOfMonth()->toDateString();

        // Branch list (BelongsToOrganization scope handles org filtering automatically)
        $branches = Branch::orderBy('is_default', 'desc')
            ->orderBy('name')
            ->get(['id', 'name', 'code', 'address', 'phone', 'email', 'is_active', 'is_default']);

        // ── Sales ─────────────────────────────────────────────────────────────
        $salesStats = DB::table('sales')
            ->selectRaw(
                'branch_id,
                SUM(amount_paid) as total_revenue,
                COUNT(*) as total_transactions,
                SUM(CASE WHEN DATE(sale_date) = ? THEN amount_paid ELSE 0 END) as today_revenue,
                COUNT(CASE WHEN DATE(sale_date) = ? THEN 1 END) as today_transactions,
                SUM(CASE WHEN sale_date >= ? THEN amount_paid ELSE 0 END) as month_revenue,
                COUNT(CASE WHEN sale_date >= ? THEN 1 END) as month_transactions,
                SUM(outstanding_balance) as outstanding',
                [$today, $today, $monthStart, $monthStart]
            )
            ->where('organization_id', $orgId)
            ->whereIn('status', ['completed', 'partial'])
            ->whereNull('deleted_at')
            ->groupBy('branch_id')
            ->get()->keyBy('branch_id');

        // ── Purchases ─────────────────────────────────────────────────────────
        $purchaseStats = DB::table('purchases')
            ->selectRaw(
                'branch_id,
                SUM(total) as total_cost,
                COUNT(*) as total_count,
                SUM(CASE WHEN purchase_date >= ? THEN total ELSE 0 END) as month_cost,
                COUNT(CASE WHEN purchase_date >= ? THEN 1 END) as month_count',
                [$monthStart, $monthStart]
            )
            ->where('organization_id', $orgId)
            ->whereNull('deleted_at')
            ->groupBy('branch_id')
            ->get()->keyBy('branch_id');

        // ── Expenses ──────────────────────────────────────────────────────────
        $expenseStats = DB::table('expenses')
            ->selectRaw(
                'branch_id,
                SUM(amount) as total_expenses,
                SUM(CASE WHEN expense_date >= ? THEN amount ELSE 0 END) as month_expenses',
                [$monthStart]
            )
            ->where('organization_id', $orgId)
            ->groupBy('branch_id')
            ->get()->keyBy('branch_id');

        // ── Products ──────────────────────────────────────────────────────────
        $productStats = DB::table('products')
            ->selectRaw(
                'branch_id,
                COUNT(*) as total_products,
                SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_products,
                SUM(CASE WHEN is_active = 1 AND low_stock_threshold > 0
                         AND stock_quantity <= low_stock_threshold THEN 1 ELSE 0 END) as low_stock_count'
            )
            ->where('organization_id', $orgId)
            ->whereNull('deleted_at')
            ->groupBy('branch_id')
            ->get()->keyBy('branch_id');

        // ── Users ─────────────────────────────────────────────────────────────
        $userStats = DB::table('users')
            ->selectRaw('branch_id, COUNT(*) as total_users')
            ->where('organization_id', $orgId)
            ->whereNotNull('branch_id')
            ->whereNull('deleted_at')
            ->groupBy('branch_id')
            ->get()->keyBy('branch_id');

        // ── Assemble per-branch data ───────────────────────────────────────────
        $branchData = $branches->map(function ($branch) use (
            $salesStats, $purchaseStats, $expenseStats, $productStats, $userStats
        ) {
            $id = $branch->id;
            $s  = $salesStats[$id]    ?? null;
            $p  = $purchaseStats[$id] ?? null;
            $e  = $expenseStats[$id]  ?? null;
            $pr = $productStats[$id]  ?? null;
            $u  = $userStats[$id]     ?? null;

            return [
                'id'                   => $branch->id,
                'name'                 => $branch->name,
                'code'                 => $branch->code,
                'address'              => $branch->address,
                'phone'                => $branch->phone,
                'email'                => $branch->email,
                'is_active'            => (bool) $branch->is_active,
                'is_default'           => (bool) $branch->is_default,
                'total_revenue'        => (float) ($s?->total_revenue        ?? 0),
                'today_revenue'        => (float) ($s?->today_revenue        ?? 0),
                'month_revenue'        => (float) ($s?->month_revenue        ?? 0),
                'total_transactions'   => (int)   ($s?->total_transactions   ?? 0),
                'today_transactions'   => (int)   ($s?->today_transactions   ?? 0),
                'month_transactions'   => (int)   ($s?->month_transactions   ?? 0),
                'outstanding'          => (float) ($s?->outstanding          ?? 0),
                'total_cost'           => (float) ($p?->total_cost           ?? 0),
                'month_cost'           => (float) ($p?->month_cost           ?? 0),
                'total_purchase_count' => (int)   ($p?->total_count          ?? 0),
                'month_purchase_count' => (int)   ($p?->month_count          ?? 0),
                'total_expenses'       => (float) ($e?->total_expenses       ?? 0),
                'month_expenses'       => (float) ($e?->month_expenses       ?? 0),
                'total_products'       => (int)   ($pr?->total_products      ?? 0),
                'active_products'      => (int)   ($pr?->active_products     ?? 0),
                'low_stock_count'      => (int)   ($pr?->low_stock_count     ?? 0),
                'total_users'          => (int)   ($u?->total_users          ?? 0),
            ];
        });

        return response()->json([
            'branches' => $branchData->values(),
            'totals'   => [
                'total_revenue'      => $branchData->sum('total_revenue'),
                'today_revenue'      => $branchData->sum('today_revenue'),
                'month_revenue'      => $branchData->sum('month_revenue'),
                'total_transactions' => $branchData->sum('total_transactions'),
                'today_transactions' => $branchData->sum('today_transactions'),
                'month_transactions' => $branchData->sum('month_transactions'),
                'outstanding'        => $branchData->sum('outstanding'),
                'total_cost'         => $branchData->sum('total_cost'),
                'month_cost'         => $branchData->sum('month_cost'),
                'total_expenses'     => $branchData->sum('total_expenses'),
                'month_expenses'     => $branchData->sum('month_expenses'),
                'total_products'     => $branchData->sum('total_products'),
                'low_stock_count'    => $branchData->sum('low_stock_count'),
                'total_users'        => $branchData->sum('total_users'),
                'total_branches'     => $branches->count(),
                'active_branches'    => $branches->where('is_active', true)->count(),
            ],
            'period' => ['today' => $today, 'month_start' => $monthStart],
        ]);
    }
}
