<?php

namespace App\Services\Finance;

use Illuminate\Support\Facades\DB;

class FinancialReportService
{
    public function __construct(
        private FinancialPaymentService $payments,
        private FinancialSchoolYearService $schoolYears
    ) {
    }

    public function getReport(?string $dateFrom, ?string $dateTo, ?string $schoolYear): array
    {
        $invoiceQuery = DB::table('invoices')
            ->selectRaw("invoices.*, CONCAT(users.firstname, ' ', users.lastname) AS parent_name")
            ->join('users', 'users.id', '=', 'invoices.parent_id');

        $refundQuery = DB::table('refunds');
        $discountQuery = DB::table('discount_usages');
        $expenseQuery = DB::table('expenses');
        $reimbQuery = DB::table('reimbursements');

        if (!empty($schoolYear)) {
            $invoiceQuery->where('invoices.school_year', $schoolYear);
            $refundQuery->where('school_year', $schoolYear);
            $discountQuery->where('school_year', $schoolYear);
            $expenseQuery->where('school_year', $schoolYear);
            $reimbQuery->where('school_year', $schoolYear);
        }

        if (!empty($dateFrom)) {
            $invoiceQuery->whereRaw('DATE(COALESCE(invoices.issue_date, invoices.created_at)) >= ?', [$dateFrom]);
            $refundQuery->whereRaw('DATE(COALESCE(refunded_at, created_at)) >= ?', [$dateFrom]);
            $discountQuery->whereRaw('DATE(COALESCE(used_at, created_at)) >= ?', [$dateFrom]);
            $expenseQuery->whereRaw('DATE(created_at) >= ?', [$dateFrom]);
            $reimbQuery->whereRaw('DATE(created_at) >= ?', [$dateFrom]);
        }

        if (!empty($dateTo)) {
            $invoiceQuery->whereRaw('DATE(COALESCE(invoices.issue_date, invoices.created_at)) <= ?', [$dateTo]);
            $refundQuery->whereRaw('DATE(COALESCE(refunded_at, created_at)) <= ?', [$dateTo]);
            $discountQuery->whereRaw('DATE(COALESCE(used_at, created_at)) <= ?', [$dateTo]);
            $expenseQuery->whereRaw('DATE(created_at) <= ?', [$dateTo]);
            $reimbQuery->whereRaw('DATE(created_at) <= ?', [$dateTo]);
        }

        $invoices = $invoiceQuery->get()->map(fn ($row) => (array) $row)->all();

        $payments = $this->payments->paymentsByInvoice($schoolYear, $dateFrom, $dateTo);
        $paymentBreakdown = $this->payments->paymentBreakdown($schoolYear, $dateFrom, $dateTo);
        $paymentTotals = $this->payments->paymentTotals($schoolYear, $dateFrom, $dateTo);

        $refunds = $refundQuery
            ->selectRaw('invoice_id, school_year, SUM(refund_paid_amount) AS total_refunded')
            ->whereNotNull('invoice_id')
            ->whereIn('status', ['Partial', 'Paid'])
            ->groupBy('invoice_id', 'school_year')
            ->get()
            ->map(fn ($row) => (array) $row)
            ->all();

        $discounts = $discountQuery
            ->selectRaw('invoice_id, school_year, SUM(discount_amount) AS discount_amount')
            ->whereNotNull('invoice_id')
            ->groupBy('invoice_id', 'school_year')
            ->get()
            ->map(fn ($row) => (array) $row)
            ->all();

        $expenses = $expenseQuery
            ->selectRaw('category, SUM(amount) AS total_amount')
            ->groupBy('category')
            ->get()
            ->map(fn ($row) => (array) $row)
            ->all();

        $reimbursements = $reimbQuery
            ->selectRaw('status, SUM(amount) AS total_amount')
            ->groupBy('status')
            ->get()
            ->map(fn ($row) => (array) $row)
            ->all();

        $schoolYears = $this->schoolYears->listYears($schoolYear);

        return [
            'selectedYear' => $schoolYear,
            'dateFrom' => $dateFrom,
            'dateTo' => $dateTo,
            'schoolYears' => $schoolYears,
            'invoices' => $invoices,
            'payments' => $payments,
            'paymentBreakdown' => $paymentBreakdown,
            'paymentTotals' => $paymentTotals,
            'refunds' => $refunds,
            'expenses' => $expenses,
            'reimbursements' => $reimbursements,
            'discounts' => $discounts,
        ];
    }
}
