<?php

namespace App\Http\Controllers;

use App\Support\PaymentGatewayInspector;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;

class UserPaymentController extends Controller
{
    /**
     * List user's own payments with filters + KPIs.
     */
    public function index(Request $request)
    {
        $userId   = auth()->id(); // শুধুই নিজের ট্রানজ্যাকশন
        $q        = trim((string) $request->input('q', ''));
        $status   = (string) $request->input('status', '');
        $method   = (string) $request->input('method', '');
        $dateFrom = $request->input('date_from'); // null/'' হতে পারে
        $dateTo   = $request->input('date_to');   // null/'' হতে পারে
        $perPage  = (int) $request->input('per_page', 15);
        $perPage  = ($perPage > 0 && $perPage <= 100) ? $perPage : 15;

        // Base query
        $query = DB::table('payments as p')
            ->where('p.user_id', $userId)
            ->select(
                'p.id',
                'p.transaction_id',
                'p.trx_id',
                'p.payment_method',
                'p.amount',
                'p.status',
                'p.created_at',
                'p.updated_at',
                'p.raw_response'
            )
            ->orderByDesc('p.created_at');

        // Global search
        if ($q !== '') {
            $like = "%{$q}%";
            $query->where(function ($w) use ($like) {
                $w->where('p.transaction_id', 'like', $like)
                  ->orWhere('p.trx_id', 'like', $like)
                  ->orWhere('p.payment_method', 'like', $like);
            });
        }

        // Individual filters (filled() ব্যবহার করলে Invalid operator সমস্যা এড়ায়)
        if ($status !== '')               $query->where('p.status', $status);
        if ($method !== '')               $query->where('p.payment_method', $method);
        if ($request->filled('date_from'))$query->whereDate('p.created_at', '>=', $dateFrom);
        if ($request->filled('date_to'))  $query->whereDate('p.created_at', '<=', $dateTo);

        // Pagination
        $payments = $query->paginate($perPage)->appends($request->query());
        $this->decoratePayments($payments->getCollection());

        // KPIs (same filters applied)
        $base = clone $query;
        $summary = [
            'count'         => (clone $base)->count(),
            'sum_completed' => (clone $base)->where('p.status', 'completed')->sum('p.amount'),
            'sum_pending'   => (clone $base)->where('p.status', 'pending')->sum('p.amount'),
            'sum_failed'    => (clone $base)->whereIn('p.status', ['failed','cancelled'])->sum('p.amount'),
        ];

        // Methods dropdown (user scoped)
        $methods = DB::table('payments')
            ->where('user_id', $userId)
            ->whereNotNull('payment_method')
            ->distinct()
            ->orderBy('payment_method')
            ->pluck('payment_method');

        return view('user.payments.index', compact(
            'payments','summary','q','status','method','methods','dateFrom','dateTo','perPage'
        ));
    }

    /**
     * Export user's filtered payments to CSV.
     */
    public function export(Request $request): StreamedResponse
    {
        $userId   = auth()->id();
        $q        = trim((string) $request->input('q', ''));
        $status   = (string) $request->input('status', '');
        $method   = (string) $request->input('method', '');
        $dateFrom = $request->input('date_from');
        $dateTo   = $request->input('date_to');

        $query = DB::table('payments as p')
            ->where('p.user_id', $userId)
            ->select(
                'p.id',
                'p.transaction_id',
                'p.trx_id',
                'p.payment_method',
                'p.amount',
                'p.status',
                'p.created_at',
                'p.raw_response'
            )
            ->orderByDesc('p.created_at');

        if ($q !== '') {
            $like = "%{$q}%";
            $query->where(function ($w) use ($like) {
                $w->where('p.transaction_id', 'like', $like)
                  ->orWhere('p.trx_id', 'like', $like)
                  ->orWhere('p.payment_method', 'like', $like);
            });
        }
        if ($status !== '')                $query->where('p.status', $status);
        if ($method !== '')                $query->where('p.payment_method', $method);
        if ($request->filled('date_from')) $query->whereDate('p.created_at', '>=', $dateFrom);
        if ($request->filled('date_to'))   $query->whereDate('p.created_at', '<=', $dateTo);

        $rows = $query->get();
        $this->decoratePayments($rows);

        $headers = [
            'Content-Type'        => 'text/csv',
            'Content-Disposition' => 'attachment; filename="my_payments.csv"',
        ];

        return response()->stream(function () use ($rows) {
            $out = fopen('php://output', 'w');
            fputcsv($out, ['ID','TransactionID','TrxID','Method','Amount','Status','CreatedAt']);
            foreach ($rows as $r) {
                fputcsv($out, [
                    $r->id,
                    $r->transaction_id,
                    $r->display_trx_id ?? $r->trx_id,
                    $r->display_method ?? $r->payment_method,
                    $r->amount,
                    $r->status,
                    $r->created_at,
                ]);
            }
            fclose($out);
        }, 200, $headers);
    }

    private function decoratePayments($payments): void
    {
        $payments->transform(function ($payment) {
            $raw = $this->decodeJsonToArray($payment->raw_response ?? null);
            $payment->display_trx_id = $payment->trx_id
                ?: PaymentGatewayInspector::extractTrxId($raw)
                ?: '—';
            $payment->display_method = PaymentGatewayInspector::detectMethod($payment->payment_method ?? null, $raw)
                ?: ($payment->payment_method ?: '—');

            return $payment;
        });
    }

    private function decodeJsonToArray($value): array
    {
        if (is_array($value)) {
            return $value;
        }

        if (!is_string($value) || trim($value) === '') {
            return [];
        }

        $decoded = json_decode($value, true);

        return is_array($decoded) ? $decoded : [];
    }
}
