<?php

namespace MoneyTransfer\Core\Repositories;

use MoneyTransfer\Core\Models\Transfer;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;

class TransferRepository
{
    public function findById($id): ?Transfer
    {
        return Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                     ->find($id);
    }

    public function create(array $data): Transfer
    {
        return Transfer::create($data);
    }

    public function update($id, array $data): bool
    {
        $transfer = $this->findById($id);
        if (!$transfer) {
            return false;
        }
        return $transfer->update($data);
    }

    public function delete($id): bool
    {
        $transfer = $this->findById($id);
        if (!$transfer) {
            return false;
        }
        return $transfer->delete();
    }

    public function getTransfersWithFilters(array $filters, int $perPage = 15): LengthAwarePaginator
    {
        $query = Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                        ->byUser(auth()->id());

        // Apply filters
        if (isset($filters['status'])) {
            $query->byStatus($filters['status']);
        }

        if (isset($filters['currency'])) {
            $query->byCurrency($filters['currency']);
        }

        if (isset($filters['date_from']) && isset($filters['date_to'])) {
            $query->byDateRange($filters['date_from'], $filters['date_to']);
        }

        if (isset($filters['search'])) {
            $query->where(function ($q) use ($filters) {
                $q->where('reference_number', 'like', '%' . $filters['search'] . '%')
                  ->orWhere('notes', 'like', '%' . $filters['search'] . '%')
                  ->orWhereHas('recipient', function ($recipientQuery) use ($filters) {
                      $recipientQuery->where('name', 'like', '%' . $filters['search'] . '%')
                                   ->orWhere('email', 'like', '%' . $filters['search'] . '%');
                  });
            });
        }

        return $query->orderBy('created_at', 'desc')->paginate($perPage);
    }

    public function search(string $query, int $perPage = 15): LengthAwarePaginator
    {
        return Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                      ->byUser(auth()->id())
                      ->where(function ($q) use ($query) {
                          $q->where('reference_number', 'like', '%' . $query . '%')
                            ->orWhere('notes', 'like', '%' . $query . '%')
                            ->orWhereHas('recipient', function ($recipientQuery) use ($query) {
                                $recipientQuery->where('name', 'like', '%' . $query . '%')
                                             ->orWhere('email', 'like', '%' . $query . '%');
                            });
                      })
                      ->orderBy('created_at', 'desc')
                      ->paginate($perPage);
    }

    public function getTransferStats(int $userId): array
    {
        $totalTransfers = Transfer::byUser($userId)->count();
        $completedTransfers = Transfer::byUser($userId)->completed()->count();
        $pendingTransfers = Transfer::byUser($userId)->pending()->count();
        $failedTransfers = Transfer::byUser($userId)->failed()->count();

        $totalAmount = Transfer::byUser($userId)->completed()->sum('total_amount');
        $totalFees = Transfer::byUser($userId)->completed()->sum('fee');

        return [
            'total_transfers' => $totalTransfers,
            'completed_transfers' => $completedTransfers,
            'pending_transfers' => $pendingTransfers,
            'failed_transfers' => $failedTransfers,
            'total_amount' => $totalAmount,
            'total_fees' => $totalFees,
            'success_rate' => $totalTransfers > 0 ? round(($completedTransfers / $totalTransfers) * 100, 2) : 0,
        ];
    }

    public function getRecentTransfers(int $userId, int $limit = 10): Collection
    {
        return Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                      ->byUser($userId)
                      ->orderBy('created_at', 'desc')
                      ->limit($limit)
                      ->get();
    }

    public function getTransfersByStatus(int $userId, string $status): Collection
    {
        return Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                      ->byUser($userId)
                      ->byStatus($status)
                      ->orderBy('created_at', 'desc')
                      ->get();
    }

    public function getTransfersByCurrency(int $userId, string $currency): Collection
    {
        return Transfer::with(['sender', 'recipient', 'currencyFrom', 'currencyTo'])
                      ->byUser($userId)
                      ->byCurrency($currency)
                      ->orderBy('created_at', 'desc')
                      ->get();
    }
} 