<?php

namespace App\Services\Reimbursements;

use App\Models\Expense;
use App\Models\Reimbursement;
use RuntimeException;

class ReimbursementCrudService
{
    public function store(array $payload, int $userId, string $schoolYear, string $semester, ?string $receiptName): Reimbursement
    {
        $expenseId = (int) ($payload['expense_id'] ?? 0);
        if ($expenseId > 0) {
            $expense = Expense::query()->find($expenseId);
            if ($expense && strcasecmp((string) $expense->category, 'Donation') === 0) {
                throw new RuntimeException('Donation expenses are tracked but should not be reimbursed.');
            }
        }

        $methodRaw = (string) ($payload['reimbursement_method'] ?? '');
        $method = ucfirst(strtolower($methodRaw));

        $reimb = Reimbursement::query()->create([
            'expense_id' => $expenseId ?: null,
            'amount' => $payload['amount'],
            'reimbursed_to' => (int) $payload['reimbursed_to'],
            'description' => $payload['description'] ?? null,
            'reimbursement_method' => $method,
            'check_number' => $method === 'Check' ? ($payload['check_number'] ?? null) : null,
            'receipt_path' => $receiptName,
            'school_year' => $payload['school_year'] ?? $schoolYear,
            'semester' => $payload['semester'] ?? $semester,
            'added_by' => $userId ?: null,
            'approved_by' => $userId ?: null,
            'status' => 'Paid',
        ]);

        if ($expenseId > 0) {
            Expense::query()->where('id', $expenseId)->update(['reimbursement_id' => $reimb->id]);
        }

        return $reimb;
    }

    public function process(array $payload, int $userId, string $schoolYear, string $semester, ?string $receiptName): Reimbursement
    {
        $expenseId = (int) ($payload['expense_id'] ?? 0);
        if ($expenseId > 0) {
            $expense = Expense::query()->find($expenseId);
            if ($expense && strcasecmp((string) $expense->category, 'Donation') === 0) {
                throw new RuntimeException('Donation expenses are tracked but should not be reimbursed.');
            }
        }

        $reimb = Reimbursement::query()->create([
            'expense_id' => $expenseId ?: null,
            'amount' => $payload['amount'],
            'reimbursed_to' => (int) $payload['reimbursed_to'],
            'approved_by' => $userId ?: null,
            'receipt_path' => $receiptName,
            'description' => $payload['description'] ?? 'Expense reimbursement',
            'status' => 'Paid',
            'added_by' => $userId ?: null,
            'school_year' => $payload['school_year'] ?? $schoolYear,
            'semester' => $payload['semester'] ?? $semester,
            'check_number' => $payload['check_number'] ?? null,
            'reimbursement_method' => $payload['reimbursement_method'] ?? null,
        ]);

        if ($expenseId > 0) {
            Expense::query()->where('id', $expenseId)->update(['reimbursement_id' => $reimb->id]);
        }

        return $reimb;
    }

    public function update(Reimbursement $reimb, array $payload, int $userId, ?string $receiptName): Reimbursement
    {
        $methodRaw = (string) ($payload['reimbursement_method'] ?? $reimb->reimbursement_method);
        $method = ucfirst(strtolower($methodRaw));

        $updateData = [
            'amount' => $payload['amount'],
            'reimbursed_to' => (int) $payload['reimbursed_to'],
            'description' => $payload['description'] ?? null,
            'reimbursement_method' => $method,
            'check_number' => $method === 'Check' ? ($payload['check_number'] ?? null) : null,
            'receipt_path' => $receiptName,
            'updated_by' => $userId ?: null,
        ];

        $reimb->update($updateData);

        return $reimb->refresh();
    }
}
