<?php

namespace App\Core\Repositories;

use App\Models\Income;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;

/**
 * Income Repository
 * Handles all database operations for income
 */
class IncomeRepository
{
    /**
     * Get all income records
     */
    public function getAll(): Collection
    {
        return Income::with(['account', 'customer', 'creator'])->get();
    }

    /**
     * Get paginated income records
     */
    public function getPaginated(int $perPage = 15, array $filters = []): LengthAwarePaginator
    {
        $query = Income::with(['account', 'customer', 'creator']);

        if (isset($filters['status'])) {
            $query->where('status', $filters['status']);
        }

        if (isset($filters['account_id'])) {
            $query->where('account_id', $filters['account_id']);
        }

        if (isset($filters['customer_id'])) {
            $query->where('customer_id', $filters['customer_id']);
        }

        if (isset($filters['date_from'])) {
            $query->where('income_date', '>=', $filters['date_from']);
        }

        if (isset($filters['date_to'])) {
            $query->where('income_date', '<=', $filters['date_to']);
        }

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

    /**
     * Get income by ID
     */
    public function getById(int $id): ?Income
    {
        return Income::with(['account', 'customer', 'creator'])->find($id);
    }

    /**
     * Create a new income record
     */
    public function create(array $data): Income
    {
        return Income::create($data);
    }

    /**
     * Update an income record
     */
    public function update(Income $income, array $data): bool
    {
        return $income->update($data);
    }

    /**
     * Delete an income record
     */
    public function delete(Income $income): bool
    {
        return $income->delete();
    }

    /**
     * Generate next income number
     */
    public function generateIncomeNumber(): string
    {
        $prefix = config('accounting.income_prefix', 'INC');
        $year = now()->year;
        $lastIncome = Income::whereYear('created_at', $year)
            ->orderBy('id', 'desc')
            ->first();

        if ($lastIncome) {
            $lastNumber = (int) substr($lastIncome->income_number, -6);
            $nextNumber = $lastNumber + 1;
        } else {
            $nextNumber = 1;
        }

        return $prefix.'-'.$year.'-'.str_pad($nextNumber, 6, '0', STR_PAD_LEFT);
    }

    /**
     * Get total income for date range
     */
    public function getTotalForDateRange(string $dateFrom, string $dateTo): float
    {
        return Income::whereBetween('income_date', [$dateFrom, $dateTo])
            ->where('status', '!=', 'reversed')
            ->sum('total');
    }
}
