<?php

namespace App\Services;

use App\Models\Transaction;
use Dompdf\Dompdf;
use Dompdf\Options;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpFoundation\StreamedResponse;

class TransactionExportService
{
    public function filteredQuery(Request $request): Builder
    {
        return Transaction::query()
            ->with('user')
            ->when($request->search, fn ($q, $s) => $q->whereHas('user', fn ($u) => $u
                ->where('name', 'like', "%{$s}%")
                ->orWhere('email', 'like', "%{$s}%")
                ->orWhere('username', 'like', "%{$s}%")))
            ->when($request->type && $request->type !== 'all', fn ($q) => $q->where('type', $request->type))
            ->latest();
    }

    public function exportExcel(Request $request): StreamedResponse
    {
        $filename = 'transactions-'.now()->format('Y-m-d-His').'.csv';

        return response()->streamDownload(function () use ($request) {
            $handle = fopen('php://output', 'w');
            fprintf($handle, chr(0xEF).chr(0xBB).chr(0xBF));

            fputcsv($handle, [
                'ID',
                'User',
                'Email',
                'Username',
                'Type',
                'Details',
                'Amount (USD)',
                'Status',
                'Date',
            ]);

            $this->filteredQuery($request)->chunk(500, function ($transactions) use ($handle) {
                foreach ($transactions as $tx) {
                    fputcsv($handle, [
                        $tx->id,
                        $tx->user?->name ?? '—',
                        $tx->user?->email ?? '—',
                        $tx->user?->username ?? '—',
                        $this->typeLabel($tx->type),
                        $tx->details ?? '',
                        number_format((float) $tx->amount, 2, '.', ''),
                        $tx->status->label(),
                        $tx->created_at->format('Y-m-d H:i:s'),
                    ]);
                }
            });

            fclose($handle);
        }, $filename, [
            'Content-Type' => 'text/csv; charset=UTF-8',
        ]);
    }

    public function exportPdf(Request $request)
    {
        $transactions = $this->filteredQuery($request)->get();
        $filters = $this->activeFilters($request);
        $filename = 'transactions-'.now()->format('Y-m-d-His').'.pdf';

        if (! class_exists(Dompdf::class)) {
            return response()->view('admin.transactions.pdf', compact('transactions', 'filters'))
                ->header('Content-Type', 'text/html; charset=UTF-8')
                ->header('Content-Disposition', 'inline; filename="'.str_replace('.pdf', '.html', $filename).'"');
        }

        $html = View::make('admin.transactions.pdf', compact('transactions', 'filters'))->render();

        $options = new Options;
        $options->set('isRemoteEnabled', false);
        $options->set('defaultFont', 'DejaVu Sans');

        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'landscape');
        $dompdf->render();

        return response($dompdf->output(), 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'attachment; filename="'.$filename.'"',
        ]);
    }

    public function typeLabel(string $type): string
    {
        return str_replace('_', ' ', ucfirst($type));
    }

    public function activeFilters(Request $request): array
    {
        $filters = [];

        if ($request->filled('search')) {
            $filters[] = 'User: '.$request->search;
        }

        if ($request->filled('type') && $request->type !== 'all') {
            $filters[] = 'Type: '.$this->typeLabel($request->type);
        }

        return $filters;
    }
}
