<?php
namespace App\Http\Controllers\Api\V1\Admin;

use App\Http\Controllers\Controller;
use App\Jobs\ExportReport;
use App\Models\AuditLog;
use App\Models\Currency;
use App\Models\ReportExport;
use App\Models\Transfer;
use App\Services\MoneyMath;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class ReportController extends Controller
{
    public function volume(Request $request,MoneyMath $money): array
    {
        $data=$request->validate(['date_from'=>['required','date'],'date_to'=>['required','date','after_or_equal:date_from']]);
        $rows=Transfer::whereBetween('created_at',[$data['date_from'],$data['date_to']])
            ->selectRaw('corridor_id, send_currency, COUNT(*) transfer_count, SUM(send_amount_minor) send_volume_minor, SUM(fee_minor) fee_volume_minor')
            ->groupBy('corridor_id','send_currency')->get();

        return ['data'=>$rows->map(function($row) use ($money) {
            $decimals=(int)Currency::whereKey($row->send_currency)->value('decimals');
            return ['corridor_id'=>$row->corridor_id,'currency'=>$row->send_currency,'transfer_count'=>(int)$row->transfer_count,'send_volume'=>$money->format((int)$row->send_volume_minor,$row->send_currency,$decimals),'fee_volume'=>$money->format((int)$row->fee_volume_minor,$row->send_currency,$decimals)];
        })];
    }

    public function export(Request $request)
    {
        $filters=$request->validate(['date_from'=>['required','date'],'date_to'=>['required','date','after_or_equal:date_from']]);
        $export=ReportExport::create(['id'=>(string)Str::uuid(),'user_id'=>$request->user()->id,'filters'=>$filters,'status'=>'queued']);
        ExportReport::dispatch($export->id);
        return response()->json(['data'=>$this->exportData($export)],202);
    }

    public function exportStatus(Request $request,ReportExport $export): array
    {
        abort_unless($request->user()->hasRole('admin') || $request->user()->id===$export->user_id,404);
        return ['data'=>$this->exportData($export)];
    }

    public function download(Request $request,ReportExport $export)
    {
        abort_unless($request->user()->hasRole('admin') || $request->user()->id===$export->user_id,404);
        abort_unless($export->status==='completed' && $export->path && Storage::exists($export->path),404,'Export is not ready.');
        return Storage::download($export->path,'transfer-report-'.$export->id.'.csv');
    }

    public function audit(Request $request)
    {
        $paginator=AuditLog::when($request->user_id,fn($q,$value)=>$q->where('user_id',$value))
            ->when($request->action,fn($q,$value)=>$q->where('action',$value))
            ->when($request->date_from,fn($q,$value)=>$q->whereDate('created_at','>=',$value))
            ->when($request->date_to,fn($q,$value)=>$q->whereDate('created_at','<=',$value))
            ->latest()->paginate(min($request->integer('per_page',20),100));

        return response()->json(['data'=>$paginator->items(),'meta'=>['current_page'=>$paginator->currentPage(),'per_page'=>$paginator->perPage(),'total'=>$paginator->total(),'last_page'=>$paginator->lastPage()]]);
    }

    private function exportData(ReportExport $export): array
    {
        return ['id'=>$export->id,'status'=>$export->status,'filters'=>$export->filters,'download_path'=>$export->status==='completed'?'/api/v1/admin/reports/exports/'.$export->id.'/download':null,'error'=>$export->status==='failed'?$export->error:null,'created_at'=>$export->created_at?->toISOString()];
    }
}
