<?php

namespace App\Http\Controllers\Api\V1;

use App\Application\Services\LedgerService;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Payout;
use App\Models\PayoutAddressAllowlist;
use App\Models\SettlementBatch;
use App\Models\WebhookEndpoint;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

final class MerchantDashboardController extends Controller
{
    public function __invoke(Request $request, LedgerService $ledger)
    {
        $merchant = $request->attributes->get('merchant');
        $environment = $request->attributes->get('environment');

        $invoiceCounts = $this->countsByStatus(
            Invoice::query()->where('merchant_id', $merchant->id)->where('environment', $environment)
        );

        $payoutCounts = $this->countsByStatus(
            Payout::query()->where('merchant_id', $merchant->id)->where('environment', $environment)
        );

        $settlementCounts = $this->countsByStatus(
            SettlementBatch::query()->where('merchant_id', $merchant->id)->where('environment', $environment)
        );

        $grossVolume = (string) Invoice::query()
            ->where('merchant_id', $merchant->id)
            ->where('environment', $environment)
            ->whereIn('status', ['confirmed', 'finished'])
            ->selectRaw('COALESCE(SUM(price_amount_minor), 0) as total')
            ->value('total');

        $recentInvoices = Invoice::with(['asset', 'address'])
            ->where('merchant_id', $merchant->id)
            ->where('environment', $environment)
            ->latest('id')
            ->limit(5)
            ->get()
            ->map(fn (Invoice $invoice) => [
                'invoice_id' => $invoice->public_id,
                'order_id' => $invoice->order_id,
                'status' => $invoice->status,
                'price_amount' => number_format($invoice->price_amount_minor / 100, 2, '.', ''),
                'price_currency' => $invoice->price_currency,
                'pay_currency' => $invoice->asset?->code,
                'pay_address' => $invoice->address?->address,
                'created_at' => $invoice->created_at?->utc()->toIso8601String(),
            ])
            ->values();

        $recentPayouts = Payout::with('asset')
            ->where('merchant_id', $merchant->id)
            ->where('environment', $environment)
            ->latest('id')
            ->limit(5)
            ->get()
            ->map(fn (Payout $payout) => [
                'payout_id' => $payout->public_id,
                'status' => $payout->status,
                'pay_currency' => $payout->asset?->code,
                'to_address' => $payout->to_address,
                'tx_hash' => $payout->tx_hash,
                'created_at' => $payout->created_at?->utc()->toIso8601String(),
            ])
            ->values();

        return ApiResponse::success([
            'merchant' => [
                'id' => $merchant->public_id,
                'name' => $merchant->name,
                'email' => $merchant->email,
                'status' => $merchant->status,
                'kyc_status' => $merchant->kyc_status ?? 'not_submitted',
            ],
            'environment' => $environment,
            'balances' => $ledger->merchantBalances($merchant->id),
            'payments' => [
                'total' => array_sum($invoiceCounts),
                'by_status' => $invoiceCounts,
                'gross_volume_usd' => number_format(((int) $grossVolume) / 100, 2, '.', ''),
            ],
            'customers' => [
                'total' => Customer::where('merchant_id', $merchant->id)->where('environment', $environment)->count(),
                'active' => Customer::where('merchant_id', $merchant->id)->where('environment', $environment)->where('status', 'active')->count(),
            ],
            'payout_wallets' => [
                'total' => PayoutAddressAllowlist::where('merchant_id', $merchant->id)->where('environment', $environment)->whereNull('archived_at')->count(),
                'active' => PayoutAddressAllowlist::where('merchant_id', $merchant->id)->where('environment', $environment)->where('status', 'active')->whereNull('archived_at')->count(),
                'default_configured' => PayoutAddressAllowlist::where('merchant_id', $merchant->id)->where('environment', $environment)->where('status', 'active')->where('is_default', true)->whereNull('archived_at')->exists(),
            ],
            'payouts' => [
                'total' => array_sum($payoutCounts),
                'by_status' => $payoutCounts,
            ],
            'settlements' => [
                'total' => array_sum($settlementCounts),
                'by_status' => $settlementCounts,
            ],
            'webhooks' => [
                'active' => WebhookEndpoint::where('merchant_id', $merchant->id)->where('environment', $environment)->where('status', 'active')->count(),
            ],
            'recent' => [
                'invoices' => $recentInvoices,
                'payouts' => $recentPayouts,
            ],
        ]);
    }

    private function countsByStatus($query): array
    {
        return $query
            ->select('status', DB::raw('COUNT(*) as total'))
            ->groupBy('status')
            ->pluck('total', 'status')
            ->map(fn ($value) => (int) $value)
            ->all();
    }
}