<?php

namespace App\Repositories;

use App\Models\TaxInvoice;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;

class InvoiceRepository extends BaseRepository
{
    protected function resolveModel(): Model
    {
        return new TaxInvoice();
    }

    /**
     * Get all invoices with relations
     */
    public function getAllWithRelations(): Collection
    {
        return $this->with(['items', 'company'])
            ->orderBy('invoice_date', 'desc')
            ->all();
    }

    /**
     * Get invoices by company
     */
    public function getByCompany(int $companyId): Collection
    {
        return $this->where('company_id', $companyId)
            ->orderBy('invoice_date', 'desc')
            ->all();
    }

    /**
     * Get invoices by status
     */
    public function getByStatus(string $status): Collection
    {
        return $this->where('status', $status)->orderBy('invoice_date', 'desc')->all();
    }

    /**
     * Get pending invoices (awaiting approval)
     */
    public function getPending(): Collection
    {
        return TaxInvoice::where('status', 'Pending')
            ->with(['items', 'company'])
            ->orderBy('invoice_date', 'desc')
            ->get();
    }

    /**
     * Get approved invoices
     */
    public function getApproved(): Collection
    {
        return TaxInvoice::where('status', 'Approved')
            ->with(['items', 'company'])
            ->orderBy('invoice_date', 'desc')
            ->get();
    }

    /**
     * Get invoices pending payment
     */
    public function getPendingPayment(): Collection
    {
        return TaxInvoice::where('status', 'Approved')
            ->whereDoesntHave('payments', function ($q) {
                $q->where('status', 'Completed');
            })
            ->with(['items', 'company'])
            ->get();
    }

    /**
     * Get invoices by date range
     */
    public function getByDateRange(string $startDate, string $endDate): Collection
    {
        return $this->whereBetween('invoice_date', [$startDate, $endDate])->all();
    }

    /**
     * Get latest invoice number
     */
    public function getLatestInvoiceNumber(): ?string
    {
        return TaxInvoice::orderBy('id', 'desc')->value('invoice_no');
    }

    /**
     * Check if invoice number exists
     */
    public function invoiceNumberExists(string $invoiceNo): bool
    {
        return TaxInvoice::where('invoice_no', $invoiceNo)->exists();
    }

    /**
     * Get invoices for DataTable
     */
    public function getForDataTableWithRelations()
    {
        return TaxInvoice::with(['items', 'company'])->latest('invoice_date');
    }

    /**
     * Search invoices
     */
    public function search(string $term): Collection
    {
        return TaxInvoice::where('invoice_no', 'like', "%{$term}%")
            ->orWhere('buyer_order_no', 'like', "%{$term}%")
            ->with('company')
            ->get();
    }

    /**
     * Approve invoice
     */
    public function approve(int $id, int $approvedBy, ?string $remarks = null): TaxInvoice
    {
        $invoice = $this->findOrFail($id);
        $invoice->update([
            'status' => 'Approved',
            'approved_by' => $approvedBy,
            'approved_at' => now(),
            'approval_remarks' => $remarks,
        ]);
        return $invoice->fresh();
    }

    /**
     * Reject invoice
     */
    public function reject(int $id, int $rejectedBy, ?string $remarks = null): TaxInvoice
    {
        $invoice = $this->findOrFail($id);
        $invoice->update([
            'status' => 'Rejected',
            'approved_by' => $rejectedBy,
            'approved_at' => now(),
            'approval_remarks' => $remarks,
        ]);
        return $invoice->fresh();
    }

    /**
     * Get revenue by month
     */
    public function getRevenueByMonth(int $year, int $month): float
    {
        return TaxInvoice::whereYear('invoice_date', $year)
            ->whereMonth('invoice_date', $month)
            ->where('status', 'Approved')
            ->sum('total_amount');
    }

    /**
     * Get total revenue for year
     */
    public function getYearlyRevenue(int $year): float
    {
        return TaxInvoice::whereYear('invoice_date', $year)
            ->where('status', 'Approved')
            ->sum('total_amount');
    }
}
