<?php

namespace App\Repositories;

use App\Models\Backend\Transaction;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class TransactionRepository
{
    /**
     * Alle Transaktionen mit Outputs
     */
    public function all(): Collection
    {
        return Transaction::with('outputs')
            ->orderBy('created_at', 'desc')
            ->get();
    }

    /**
     * Finde Transaction by ID mit Outputs
     */
    public function find(int $id): ?Transaction
    {
        return Transaction::with('outputs')->find($id);
    }

    /**
     * Transaktionen die Review benötigen
     */
    public function requiresReview(): Collection
    {
        return Transaction::with('outputs')
            ->where('status', Transaction::STATUS_COMPLETED)
            ->get()
            ->filter(fn ($t) => $t->requiresReview());
    }

    /**
     * High-Risk Transaktionen
     */
    public function highRisk(int $threshold = 70): Collection
    {
        return $this->all()
            ->filter(function ($transaction) use ($threshold) {
                $risk = $transaction->getRiskAssessment();

                return ($risk['score'] ?? 0) >= $threshold;
            });
    }

    /**
     * Transaktionen nach Firma
     */
    public function byCompany(string $companyName): Collection
    {
        return Transaction::with('outputs')
            ->where('corporate_entity', 'ILIKE', "%{$companyName}%")
            ->orderBy('tx_date', 'desc')
            ->get();
    }

    /**
     * Transaktionen nach Status
     */
    public function byStatus(string $status): Collection
    {
        return Transaction::with('outputs')
            ->where('status', $status)
            ->orderBy('created_at', 'desc')
            ->get();
    }

    /**
     * Pending Transaktionen (warten auf KI-Verarbeitung)
     */
    public function pending(): Collection
    {
        return $this->byStatus(Transaction::STATUS_PENDING);
    }

    /**
     * Processing Transaktionen (werden gerade verarbeitet)
     */
    public function processing(): Collection
    {
        return $this->byStatus(Transaction::STATUS_PROCESSING);
    }

    /**
     * Completed Transaktionen
     */
    public function completed(): Collection
    {
        return $this->byStatus(Transaction::STATUS_COMPLETED);
    }

    /**
     * Failed Transaktionen
     */
    public function failed(): Collection
    {
        return $this->byStatus(Transaction::STATUS_FAILED);
    }

    /**
     * Statistiken
     */
    public function stats(): array
    {
        $total = Transaction::count();
        $pending = Transaction::where('status', Transaction::STATUS_PENDING)->count();
        $processing = Transaction::where('status', Transaction::STATUS_PROCESSING)->count();
        $completed = Transaction::where('status', Transaction::STATUS_COMPLETED)->count();
        $failed = Transaction::where('status', Transaction::STATUS_FAILED)->count();

        // Review Statistics
        $needsReview = $this->completed()
            ->filter(fn ($t) => $t->requiresReview())
            ->count();

        // Risk Statistics
        $highRisk = $this->completed()
            ->filter(fn ($t) => $t->getRiskScore() >= 70)
            ->count();

        $mediumRisk = $this->completed()
            ->filter(fn ($t) => $t->getRiskScore() >= 40 && $t->getRiskScore() < 70)
            ->count();

        $lowRisk = $this->completed()
            ->filter(fn ($t) => $t->getRiskScore() < 40)
            ->count();

        return compact(
            'total',
            'pending',
            'processing',
            'completed',
            'failed',
            'needsReview',
            'highRisk',
            'mediumRisk',
            'lowRisk'
        );
    }

    /**
     * Paginierte Transaktionen
     */
    public function paginated(int $perPage = 20)
    {
        return Transaction::with('outputs')
            ->orderBy('created_at', 'desc')
            ->paginate($perPage);
    }

    /**
     * Suche in Transaktionen
     */
    public function search(string $query): Collection
    {
        return Transaction::with('outputs')
            ->where(function ($q) use ($query) {
                $q->where('corporate_entity', 'ILIKE', "%{$query}%")
                    ->orWhere('corporate_counterparty', 'ILIKE', "%{$query}%")
                    ->orWhere('tx_purpose', 'ILIKE', "%{$query}%");
            })
            ->orderBy('created_at', 'desc')
            ->get();
    }

    /**
     * Transaktionen nach Datum-Range
     */
    public function byDateRange(string $startDate, string $endDate): Collection
    {
        return Transaction::with('outputs')
            ->whereBetween('tx_date', [$startDate, $endDate])
            ->orderBy('tx_date', 'desc')
            ->get();
    }

    /**
     * Alle unique Firmen
     */
    public function getAllCompanies(): Collection
    {
        return DB::connection('backend')
            ->table('transactions')
            ->select('corporate_entity')
            ->distinct()
            ->orderBy('corporate_entity')
            ->get();
    }

    /**
     * Dashboard-Daten
     */
    public function dashboardData(): array
    {
        $stats = $this->stats();

        $recentTransactions = Transaction::with('outputs')
            ->orderBy('created_at', 'desc')
            ->limit(10)
            ->get();

        $recentHighRisk = $this->completed()
            ->filter(fn ($t) => $t->getRiskScore() >= 70)
            ->take(5);

        $topCompanies = DB::connection('backend')
            ->table('transactions')
            ->select('corporate_entity', DB::raw('COUNT(*) as count'))
            ->groupBy('corporate_entity')
            ->orderByDesc('count')
            ->limit(10)
            ->get();

        return [
            'stats' => $stats,
            'recent_transactions' => $recentTransactions,
            'recent_high_risk' => $recentHighRisk,
            'top_companies' => $topCompanies,
        ];
    }
}
