<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\User;
use App\Models\Transaction;
use App\Services\MoneyBalanceService;
use App\Services\MetalBalanceService;

class ReportController extends Controller
{
    public function __construct(
        protected MoneyBalanceService $moneyBalanceService,
        protected MetalBalanceService $metalBalanceService
    ) {
    }

    public function customerBalances()
    {
        $customers = User::where('is_customer', true)->get();

        $data = $customers->map(function (User $customer) {
            $summary = $this->moneyBalanceService->getCustomerMoneyBalanceSummary($customer);

            return [
                'customer' => $customer,
                'remaining' => [
                    'remaining_debt' => $summary['debt'],
                    'remaining_credit' => $summary['credit'],
                ],
            ];
        });

        // Filter to only customers with non-zero balances if requested
        if (request()->query('non_zero') === 'true') {
            $data = $data->filter(function ($item) {
                return abs($item['remaining']['remaining_debt']) > 0.01
                    || abs($item['remaining']['remaining_credit']) > 0.01;
            });
        }

        return response()->json([
            'success' => true,
            'data' => $data->values(),
        ]);
    }

    public function customerMetalBalances()
    {
        $customers = User::where('is_customer', true)->get();

        $data = $customers->map(function (User $customer) {
            $summary = $this->metalBalanceService->getCustomerMetalBalanceSummary($customer);

            return [
                'customer' => $customer,
                'balances' => $summary['balances'],
                'remaining' => [
                    'remaining_debt' => $summary['total_debt_grams'],
                    'remaining_credit' => $summary['total_credit_grams'],
                ],
            ];
        });

        // Filter to only customers with non-zero metal balances if requested
        if (request()->query('non_zero') === 'true') {
            $data = $data->filter(function ($item) {
                return abs($item['remaining']['remaining_debt']) > 0.001
                    || abs($item['remaining']['remaining_credit']) > 0.001;
            });
        }

        return response()->json([
            'success' => true,
            'data' => $data->values(),
        ]);
    }

    /**
     * سفارشاتی که از نظر مالی تسویه نشده‌اند.
     * فقط سفارشاتی که مشتری‌شان هنوز ماندهٔ مالی دارد (بدهکار یا بستانکار) برگردانده می‌شوند؛
     * اگر با تراکنش سفارش دیگر بالانس شده باشد، در این لیست نمی‌آید.
     */
    public function unbalancedBatches()
    {
        $query = Order::with('user')->where('money_status', 'UNSETTLED');

        if ($from = request()->query('from_date')) {
            $query->whereDate('order_date', '>=', $from);
        }

        if ($to = request()->query('to_date')) {
            $query->whereDate('order_date', '<=', $to);
        }

        $orders = $query->orderBy('order_date', 'desc')->get();

        // حذف سفارشاتی که مشتری‌شان از نظر ماندهٔ کلی بالانسه (با تراکنش سفارش دیگر تسویه شده)
        $orders = $orders->filter(function (Order $order) {
            if (! $order->user_id) {
                return true;
            }
            $summary = $this->moneyBalanceService->getCustomerMoneyBalanceSummary($order->user);
            return $summary['debt'] > 0.01 || $summary['credit'] > 0.01;
        })->values();

        return response()->json([
            'success' => true,
            'data' => $orders,
        ]);
    }

    public function openBatches()
    {
        $query = Order::with('user')->where('status', '!=', 'CLOSED');

        if ($from = request()->query('from_date')) {
            $query->whereDate('order_date', '>=', $from);
        }

        if ($to = request()->query('to_date')) {
            $query->whereDate('order_date', '<=', $to);
        }

        $orders = $query->orderBy('order_date', 'desc')->get();

        return response()->json([
            'success' => true,
            'data' => $orders,
        ]);
    }

    public function unallocatedTransactions()
    {
        $query = Transaction::with(['fromUser', 'toUser'])
            ->where('status', 'SETTLED');

        if ($from = request()->query('from_date')) {
            $query->whereDate('transaction_date', '>=', $from);
        }

        if ($to = request()->query('to_date')) {
            $query->whereDate('transaction_date', '<=', $to);
        }

        $transactions = $query->orderBy('transaction_date', 'desc')->get()
            ->map(function (Transaction $transaction) {
                $allocated = $transaction->allocations()->sum('amount');

                $remaining = $transaction->amount - $allocated;
                $transaction->allocated_amount = (float) $allocated;
                $transaction->remaining_amount = (float) max(0, $remaining);

                return $transaction;
            })
            ->filter(fn($transaction) => $transaction->remaining_amount > 0.01)
            ->values();

        return response()->json([
            'success' => true,
            'data' => $transactions,
        ]);
    }

    public function batchSettlements()
    {
        $orders = Order::all()->map(function (Order $order) {
            return [
                'order' => $order,
                'money_status' => $order->money_status,
            ];
        });

        return response()->json([
            'success' => true,
            'data' => $orders,
        ]);
    }
}
