<?php

declare(strict_types=1);

namespace App\Http\Controllers\Project;

use App\Http\Controllers\Concerns\AuthorizesProjectAccess;
use App\Http\Controllers\Controller;
use App\Http\Resources\ProjectFinanceResource;
use App\Models\Invoice;
use App\Models\Project;
use App\Models\WalletTransaction;
use App\Services\InvoiceService;
use Illuminate\Http\Request;

class ProjectFinanceController extends Controller
{
    use AuthorizesProjectAccess;

    public function __invoke(Request $request, Project $project, InvoiceService $invoiceService): ProjectFinanceResource
    {
        $this->authorizeProjectAccess($project);

        $invoiceQuery = Invoice::query()
            ->with(['project', 'user', 'items'])
            ->where('project_id', $project->id);

        $transactionQuery = WalletTransaction::query()
            ->with(['project', 'invoice'])
            ->where('project_id', $project->id);

        if ($request->filled('from')) {
            $invoiceQuery->whereDate('issued_at', '>=', $request->date('from'));
            $transactionQuery->whereDate('created_at', '>=', $request->date('from'));
        }

        if ($request->filled('to')) {
            $invoiceQuery->whereDate('issued_at', '<=', $request->date('to'));
            $transactionQuery->whereDate('created_at', '<=', $request->date('to'));
        }

        $type = $request->string('type')->toString();

        if ($type === 'income') {
            $invoiceQuery->where('type', Invoice::TYPE_INCOME);
        } elseif ($type === 'expense') {
            $invoiceQuery->where('type', Invoice::TYPE_EXPENSE);
        }

        $invoices = $invoiceQuery->latest()->get()->map(function (Invoice $invoice) use ($invoiceService) {
            return $invoiceService->refreshLateFee($invoice);
        });

        $transactions = $transactionQuery->latest()->get();

        $income = (int) $invoices->where('type', Invoice::TYPE_INCOME)->sum('total');
        $expense = (int) $invoices->where('type', Invoice::TYPE_EXPENSE)->sum('total');

        $successfulStatuses = [Invoice::STATUS_PAID, Invoice::STATUS_APPROVED];
        $failedStatuses = [Invoice::STATUS_REJECTED];
        $monthStart = now()->startOfMonth();

        $successful = $invoices->whereIn('status', $successfulStatuses);
        $failed = $invoices->whereIn('status', $failedStatuses);
        $successfulMonth = $successful->filter(fn (Invoice $i) => $i->issued_at && $i->issued_at->gte($monthStart));
        $failedMonth = $failed->filter(fn (Invoice $i) => $i->issued_at && $i->issued_at->gte($monthStart));

        $pieChart = $invoices
            ->groupBy('type')
            ->map(fn ($group, $invoiceType) => [
                'label' => $invoiceType === Invoice::TYPE_INCOME ? 'درآمد' : 'هزینه',
                'amount' => (int) $group->sum('total'),
                'type' => $invoiceType,
            ])
            ->values()
            ->all();

        $statusChart = $invoices
            ->groupBy('status')
            ->map(fn ($group, $status) => [
                'status' => $status,
                'count' => $group->count(),
                'amount' => (int) $group->sum('total'),
            ])
            ->values()
            ->all();

        return new ProjectFinanceResource([
            'income' => $income,
            'expense' => $expense,
            'net' => $income - $expense,
            'report' => [
                'successful_total' => (int) $successful->sum('total'),
                'successful_month' => (int) $successfulMonth->sum('total'),
                'failed_total' => (int) $failed->sum('total'),
                'failed_month' => (int) $failedMonth->sum('total'),
                'expense_payments_total' => (int) $invoices->where('type', Invoice::TYPE_EXPENSE)->where('status', Invoice::STATUS_PAID)->sum('total'),
                'income_payments_total' => (int) $invoices->where('type', Invoice::TYPE_INCOME)->whereIn('status', $successfulStatuses)->sum('total'),
            ],
            'pie_chart' => $pieChart,
            'status_chart' => $statusChart,
            'transactions' => $transactions,
            'invoices' => $invoices,
        ]);
    }
}
