<?php

namespace App\Http\Controllers\Api\V1\Expense;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\Expense\StoreExpenseCategoryRequest;
use App\Http\Requests\Api\V1\Expense\StoreExpenseRequest;
use App\Http\Requests\Api\V1\Expense\UpdateExpenseRequest;
use App\Services\ExpenseService;
use App\Services\ResponseService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ExpenseController extends Controller
{
    public function __construct(
        private ExpenseService $expenseService,
        private ResponseService $responseService
    ) {}

    // ==================== EXPENSE CATEGORIES ====================

    public function categoryIndex(Request $request): JsonResponse
    {
        $categories = $this->expenseService->getAllCategories($request->boolean('active_only', false));
        return $this->responseService->success($categories, 'Expense categories retrieved successfully');
    }

    public function categoryStore(StoreExpenseCategoryRequest $request): JsonResponse
    {
        $category = $this->expenseService->createCategory($request->validated());
        return $this->responseService->success($category, 'Expense category created successfully', 201);
    }

    public function categoryShow(int $id): JsonResponse
    {
        $category = $this->expenseService->getCategoryById($id);

        if (!$category) {
            return $this->responseService->error('Expense category not found', 404);
        }

        return $this->responseService->success($category, 'Expense category retrieved successfully');
    }

    public function categoryUpdate(Request $request, int $id): JsonResponse
    {
        $category = $this->expenseService->updateCategory($id, $request->only(['name', 'description', 'is_active']));

        if (!$category) {
            return $this->responseService->error('Expense category not found', 404);
        }

        return $this->responseService->success($category, 'Expense category updated successfully');
    }

    public function categoryDestroy(int $id): JsonResponse
    {
        $deleted = $this->expenseService->deleteCategory($id);

        if (!$deleted) {
            return $this->responseService->error('Expense category not found', 404);
        }

        return $this->responseService->success(null, 'Expense category deleted successfully');
    }

    // ==================== EXPENSES ====================

    public function index(Request $request): JsonResponse
    {
        $filters = $request->only(['branch_id', 'category_id', 'status', 'payment_method', 'start_date', 'end_date']);
        $expenses = $this->expenseService->getAllExpenses($filters);
        return $this->responseService->success($expenses, 'Expenses retrieved successfully');
    }

    public function store(StoreExpenseRequest $request): JsonResponse
    {
        $expense = $this->expenseService->createExpense($request->validated());
        return $this->responseService->success($expense, 'Expense created successfully', 201);
    }

    public function show(int $id): JsonResponse
    {
        $expense = $this->expenseService->getExpenseById($id);

        if (!$expense) {
            return $this->responseService->error('Expense not found', 404);
        }

        return $this->responseService->success($expense, 'Expense retrieved successfully');
    }

    public function update(UpdateExpenseRequest $request, int $id): JsonResponse
    {
        $expense = $this->expenseService->updateExpense($id, $request->validated());

        if (!$expense) {
            return $this->responseService->error('Expense not found or cannot be updated', 404);
        }

        return $this->responseService->success($expense, 'Expense updated successfully');
    }

    public function destroy(int $id): JsonResponse
    {
        $deleted = $this->expenseService->deleteExpense($id);

        if (!$deleted) {
            return $this->responseService->error('Expense not found or cannot be deleted', 404);
        }

        return $this->responseService->success(null, 'Expense deleted successfully');
    }

    public function approve(int $id): JsonResponse
    {
        $expense = $this->expenseService->approveExpense($id, auth()->id());

        if (!$expense) {
            return $this->responseService->error('Expense not found or cannot be approved', 404);
        }

        return $this->responseService->success($expense, 'Expense approved successfully');
    }

    public function reject(Request $request, int $id): JsonResponse
    {
        $expense = $this->expenseService->rejectExpense($id, auth()->id(), $request->input('reason'));

        if (!$expense) {
            return $this->responseService->error('Expense not found or cannot be rejected', 404);
        }

        return $this->responseService->success($expense, 'Expense rejected successfully');
    }

    public function byBranch(int $branchId, Request $request): JsonResponse
    {
        $filters = array_merge(
            $request->only(['category_id', 'status', 'payment_method', 'start_date', 'end_date']),
            ['branch_id' => $branchId]
        );
        $expenses = $this->expenseService->getAllExpenses($filters);
        return $this->responseService->success($expenses, 'Branch expenses retrieved successfully');
    }
}
