<?php

namespace App\Http\Controllers;

use App\Models\Expense;
use App\Models\Expense_categorie;
use App\Models\Expense_detail;
use App\Models\Transaction;
use App\Models\Transaction_detail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ExpenseController extends Controller
{
    public function show(Request $request)
    {
        $expenses = Expense_detail::with('expense_categorie');

        // Apply search filter
        if ($request->filled('search_query')) {
            $expenses->where(function ($query) use ($request) {
                $query->where('description', 'like', '%' . $request->search_query . '%');
            });
        }

        // Apply class filter if selected
        if ($request->filled('date_filter')) {
            $expenses->where('date', $request->date_filter);
        }
        if ($request->filled('category_filter')) {
            $expenses->where('expense_account_id', $request->category_filter);
        }
        if ($request->filled('amount_filter')) {
            $expenses->where('amount', $request->amount_filter);
        }
        $expenses = $expenses->paginate(10);

        if ($request->ajax()) {
            return view('expense.allExpSearch', compact('expenses'))->render();
        }

        $categories = Expense_detail::with('expense_categorie')->select('expense_account_id')->groupBY('expense_account_id')->paginate(10);
        $amounts    = Expense_detail::select('amount')->get();
        // dd($categories);
        return view('expense.allExp', compact('expenses', 'categories', 'amounts'));
    }

    public function create()
    {
        $categories = Expense_categorie::all();
        return view('expense.addExp', compact('categories'));
    }

    public function store(Request $request)
    {
        DB::beginTransaction();
        try {
            // Validate the request
            $request->validate([
                'expense_head.*'        => 'required|exists:expense_categories,head_code',
                'expense_name.*'        => 'required|string|max:255',
                'date'        => 'required|date',
                'expense_amount.*'      => 'required|numeric',
                'expense_attachment.*'  => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:2048',
                'expense_description.*' => 'nullable|string|max:255',
            ]);

            // Calculate the sum of amounts
            $totalAmount = collect($request->expense_amount)->sum();

            $id            = Expense::max('id');
            $voucherNumber = 'EXP-' . ($id == null ? 1 : $id + 1);

            // Create the main expense record
            $expenseId = Expense::create([
                'date'           => $request->date,
                'voucher_number' => $voucherNumber,
                'amount'         => $totalAmount,
            ])->id;

            $transactionId = Transaction::create([
                'transaction_type'  => "expense",
                'trans_type_id'    => $expenseId,
                'transaction_date'  => $request->date,
                'total_amount'   => $totalAmount,
                'remarks'   => "Expense",
            ])->id;

            foreach ($request->expense_head as $index => $expenseHead) {

                $expCatgId =  Expense_categorie::where('head_code', $expenseHead)->value('id');

                Expense_detail::create([
                    'expense_id'         => $expenseId,
                    'expense_account_id' => $expCatgId,
                    'description'        => $request->expense_description[$index],
                    'amount'             => $request->expense_amount[$index],
                    'status'             => 'active',
                    'date'               => $request->date,
                    'receipt_file'       => $request->hasFile('expense_attachment.' . $index)
                        ? $request->file('expense_attachment.' . $index)->store('expenses_receipts', 'public')
                        : null,
                ]);

                Transaction_detail::create([
                    'transaction_id'  => $transactionId,
                    'coa_id'    => $expenseHead,
                    'transaction_type'  => "expense",
                    'debit'   =>  $request->expense_amount[$index],
                    'credit'   => 0,
                ]);
            }

            // do work for Cash in hand
            // Cash in hand head code is 20500
            Transaction_detail::create([
                'transaction_id' => $transactionId,
                'coa_id'       => "20500",
                'transaction_type'         => "expense",
                'debit'         => 0,
                'credit'         => $totalAmount,
            ]);


            DB::commit();

            return redirect()->route('show.expenses')->with('success', 'Expense added successfully!');
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('Error storing expenses: ' . $e->getMessage());
            return redirect()->back()->with('error', 'Failed to add expense. Please try again.' . $e->getMessage());
        }
    }

    public function update($id, Request $request)
    {
        DB::beginTransaction();
        try {
            $request->validate([
                'expense_head'        => 'required|exists:expense_categories,id',
                'expense_date'        => 'required|date',
                'expense_amount'      => 'required|numeric',
                'expense_description' => 'nullable|string|max:255',
            ]);

            // Find the expense detail by ID
            $expense_detail = Expense_detail::findOrFail($id);

            // Update the expense detail
            $expense_detail->update([
                'expense_account_id' => $request->expense_head,
                'date'               => $request->expense_date,
                'amount'             => $request->expense_amount,
                'description'        => $request->expense_description,
            ]);

            // Calculate the total amount for the associated expense
            $amount          = 0;
            $expense_details = Expense_detail::where('expense_id', $expense_detail->expense_id)->get();
            foreach ($expense_details as $expense) {
                $amount += $expense->amount;
            }

            // Update the associated expense's total amount
            $expense = Expense::find($expense_detail->expense_id);
            $expense->update([
                'amount' => $amount,
            ]);
            DB::commit();

            return redirect()->back()->with('success', 'Expense updated successfully!');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error updating expense: ' . $e->getMessage());

            // Redirect back with an error message
            return redirect()->back()->with('error', 'Failed to update expense. Please try again. Error: ' . $e->getMessage());
        }
    }

    public function delete($id)
    {
        DB::beginTransaction();
        try {
            $expense_detail = Expense_detail::findOrFail($id);

            // Calculate the total amount for the associated expense
            $amount          = 0;
            $expense_details = Expense_detail::where('expense_id', $expense_detail->expense_id)->get();
            foreach ($expense_details as $expense) {
                $amount += $expense->amount;
            }
            $amount -= $expense_detail->amount;
            // Update the associated expense's total amount
            $expense         = Expense::find($expense_detail->expense_id);
            $expense->amount = $amount;
            $expense->save();

            // Delete the expense detail
            $expense_detail->delete();

            // Commit the transaction if everything is successful
            DB::commit();

            return redirect()->back()->with('success', 'Expense deleted successfully!');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error deleting expense: ' . $e->getMessage());
            return redirect()->back()->with('error', 'Failed to delete expense. Please try again. Error: ' . $e->getMessage());
        }
    }


}
