<?php

namespace App\Http\Controllers\User;

use App\Exports\SimpleArrayExport;
use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\Withdrawal;
use App\Models\WalletTransaction;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

class ReportController extends Controller
{
    public function index(): View
    {
        return view('user.reports');
    }

    public function income(Request $request): View|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        [$from, $to] = $this->dateRange($request);

        $rows = WalletTransaction::query()
            ->where('user_id', auth()->id())
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->whereDate('transacted_at', '>=', $from)
            ->whereDate('transacted_at', '<=', $to)
            ->latest('transacted_at')
            ->get()
            ->map(fn ($txn) => [
                optional($txn->transacted_at)->format('Y-m-d'),
                $txn->amount,
                $txn->source_type,
                $txn->display_reference ?? $txn->reference,
            ])
            ->all();

        return $this->exportOrView(
            $request,
            'user.reports.table',
            'income-statement',
            'Income Statement',
            ['Date', 'Amount', 'Source', 'Reference'],
            $rows,
            compact('from', 'to', 'rows')
        );
    }

    public function payouts(Request $request): View|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        [$from, $to] = $this->dateRange($request);

        $rows = Withdrawal::query()
            ->where('user_id', auth()->id())
            ->whereDate('requested_at', '>=', $from)
            ->whereDate('requested_at', '<=', $to)
            ->latest('requested_at')
            ->get()
            ->map(fn ($wd) => [
                optional($wd->requested_at)->format('Y-m-d'),
                $wd->amount,
                $wd->net_amount,
                $wd->status,
            ])
            ->all();

        return $this->exportOrView(
            $request,
            'user.reports.table',
            'payout-report',
            'Payout Report',
            ['Date', 'Amount', 'Net', 'Status'],
            $rows,
            compact('from', 'to', 'rows')
        );
    }

    public function orders(Request $request): View|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        [$from, $to] = $this->dateRange($request);

        $rows = Order::query()
            ->where('user_id', auth()->id())
            ->whereDate('created_at', '>=', $from)
            ->whereDate('created_at', '<=', $to)
            ->latest('created_at')
            ->get()
            ->map(fn ($order) => [
                optional($order->created_at)->format('Y-m-d'),
                $order->order_number,
                $order->total,
                $order->total_bv,
                $order->status,
            ])
            ->all();

        return $this->exportOrView(
            $request,
            'user.reports.table',
            'order-report',
            'Order Report',
            ['Date', 'Order', 'Total', 'BV', 'Status'],
            $rows,
            compact('from', 'to', 'rows')
        );
    }

    public function yearly(Request $request): View|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        $rows = WalletTransaction::query()
            ->where('user_id', auth()->id())
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->selectRaw('YEAR(transacted_at) as year, SUM(amount) as total_income')
            ->groupBy('year')
            ->orderBy('year')
            ->get()
            ->map(fn ($row) => [$row->year, $row->total_income])
            ->all();

        return $this->exportOrView(
            $request,
            'user.reports.table',
            'yearly-earnings',
            'Yearly Earnings',
            ['Year', 'Total Income'],
            $rows,
            ['from' => null, 'to' => null, 'rows' => $rows]
        );
    }

    private function dateRange(Request $request): array
    {
        $from = $request->input('from', now()->startOfMonth()->toDateString());
        $to = $request->input('to', now()->toDateString());

        return [$from, $to];
    }

    /**
     * @param  array<int, string>  $headings
     * @param  array<int, array<int, mixed>>  $rows
     * @param  array<string, mixed>  $viewData
     */
    private function exportOrView(Request $request, string $view, string $filename, string $title, array $headings, array $rows, array $viewData): View|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        if ($request->get('export') === 'excel') {
            return Excel::download(new SimpleArrayExport($rows, $headings), $filename.'.xlsx');
        }

        if ($request->get('export') === 'pdf') {
            $pdf = Pdf::loadView('user.reports.pdf', [
                'headings' => $headings,
                'rows' => $rows,
                'title' => $title,
            ]);

            return $pdf->download($filename.'.pdf');
        }

        return view($view, array_merge($viewData, [
            'title' => $title,
            'headings' => $headings,
            'rows' => $rows,
        ]));
    }
}
