<?php

declare(strict_types=1);

namespace App\Repositories;

use App\Contracts\Repositories\PartnerDistributionRepositoryInterface;
use App\Models\PartnerDistribution;
use Illuminate\Database\Eloquent\Collection;

final class EloquentPartnerDistributionRepository implements PartnerDistributionRepositoryInterface
{
    public function findById(int $id): ?PartnerDistribution
    {
        return PartnerDistribution::with(['partner', 'investment', 'distribution'])->find($id);
    }

    public function getByPartner(int $partnerId): Collection
    {
        return PartnerDistribution::where('partner_id', $partnerId)
            ->with(['investment.investmentProperty', 'distribution'])
            ->latest()
            ->get();
    }

    public function getByInvestment(int $investmentId): Collection
    {
        return PartnerDistribution::where('investment_id', $investmentId)
            ->with('distribution')
            ->latest()
            ->get();
    }

    public function getPaginatedByInvestment(int $investmentId, int $perPage = 15)
    {
        return PartnerDistribution::where('investment_id', $investmentId)
            ->with('distribution')
            ->latest()
            ->paginate($perPage);
    }

    public function getByDistribution(int $distributionId): Collection
    {
        return PartnerDistribution::where('distribution_id', $distributionId)
            ->with(['partner', 'investment'])
            ->latest()
            ->get();
    }

    public function getPending(int $partnerId): Collection
    {
        return PartnerDistribution::pending()
            ->where('partner_id', $partnerId)
            ->with(['investment.investmentProperty', 'distribution'])
            ->latest()
            ->get();
    }

    public function getProcessed(int $partnerId): Collection
    {
        return PartnerDistribution::processed()
            ->where('partner_id', $partnerId)
            ->with(['investment.investmentProperty', 'distribution'])
            ->latest()
            ->get();
    }

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

    public function update(int $id, array $data): PartnerDistribution
    {
        $distribution = PartnerDistribution::findOrFail($id);
        $distribution->update($data);

        return $distribution->fresh();
    }

    public function markAsProcessed(int $id, string $reference): bool
    {
        $distribution = PartnerDistribution::findOrFail($id);
        $distribution->markAsProcessed($reference);

        return true;
    }

    public function getTotalByPartner(int $partnerId): float
    {
        return (float) PartnerDistribution::where('partner_id', $partnerId)
            ->where('payment_status', 'processed')
            ->sum('distribution_amount');
    }
}
