<?php

namespace App\Http\Controllers\Accounting;

use App\Classes\EditLogHistory;
use Carbon\Carbon;
use App\Models\Expense;
use App\Models\Employee;
use App\Models\ExpenseHead;
use App\Models\FundTransfer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Models\UserAccounting;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;

class ExpenseController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:expense-entry|expense-section', ['only' => ['index', 'show']]);
        $this->middleware('permission:expense-section', ['only' => ['create', 'store']]);
        $this->middleware('permission:expense-section', ['only' => ['edit', 'update','expenseApprove']]);
    }

    public function index()
    {

        if (auth()->user()->hasPermissionTo('all-expense-show')) {
            $expenses = Expense::with('head')->get();
        }else{
            $user_id = auth()->user()->id;
            $expenses = Expense::with('head')->where('created_by',$user_id)->get();
        }



        $data = [
            'expenses'      => $expenses,
            'expenseHead'   => ExpenseHead::where('id','!=',6)->get(),
            'employes'      => Employee::where('status','active')->get()
        ];


        return view('accounts.expense.index', $data);
    }


    public function create()
    {
        $expenseHead = ExpenseHead::all();
        $employes = Employee::where('status','active')->get();

        return view('accounts.expense.create', compact('expenseHead','employes'));
    }


    public function store(Request $request)
    {
        $request->validate([
            'attach_document' => 'mimes:jpeg,jpg,png,webp,gif,pdf|max:10240',
            'amount'          => 'required',
        ]);

        // dd($request->all());

        try {
            if(!empty($request->employee)){
               $employee =  Employee::find($request->employee);
               $note = $request->description;
            }else{
                $note = $request->description;
            }


            $expense = new Expense();

            $expense->name = $request->name;
            $expense->invoice_number = $request->invoice_number;
            $expense->date = Carbon::parse($request->date);
            $expense->amount = $request->amount;
            $expense->description =  $note;
            $expense->expenseHead = $request->expenseHead;
            $expense->created_by = auth()->user()->id;
            $expense->employee_id = $request->employee;


            if ($request->attach_document != null) {
               // for s3 upload
               if (checkSettings('store_image_to_s3') === 'enable') {
                    $fileName = time() . '.' . $request->attach_document->extension();
                    $path = 'expenseDocument/' . $fileName;

                    // Store to S3
                    $request->attach_document->storeAs('expenseDocument', $fileName, 's3');

                    // Optionally make public (if needed)
                    Storage::disk('s3')->setVisibility($path, 'public');

                    // ✅ Save full URL or path
                    $expense->attach_document = Storage::disk('s3')->url($path); // or just $path
                } else {
                    $fileName = time() . '.' . $request->attach_document->extension();
                    $request->attach_document->move(storage_path('app/public/expenseDocument'), $fileName);
                    $expense->attach_document = $fileName;
                }



            }
            $expense->save();

            DB::commit();

            Toastr::success('success','Expense Successfully Submitted',['success' => 'alert alert-success']);
            return redirect()->back();


        } catch (\Throwable $th) {
            //throw $th;
            dd($th);

            DB::rollBack();
        }



        return redirect()->route('expense.index');
    }


    public function expenseApprove(request $request,$id)
    {

        DB::beginTransaction();

        try {

            $expense = Expense::find($id);

            // dd($expense->fund_transfer_id);
            if($expense->user_accounting_id != null ){

                $user_accounting = UserAccounting::where('id',$expense->user_accounting_id)->update([
                    'received_amount'  =>  0,
                    'paid_amount'      => $expense->amount,
                    'actions'          =>  $expense->description.' approved by '.auth()->user()->name,
                    'comments'         => null,
                    'user_id'          => $expense->created_by,

                ]);

            }else{
                $user_accounting = UserAccounting::create([
                    'received_amount'  =>  0,
                    'paid_amount'      => $expense->amount,
                    'actions'          =>  $expense->description.' approved by '.auth()->user()->name,
                    'comments'         => null,
                    'user_id'          => $expense->created_by,

                ]);
                $expense->user_accounting_id = $user_accounting->id;
            }


            $expense->status = 'approved';
            $expense->save();

            DB::commit();



            Toastr::success('success','Expense Approved',['success' => 'alert alert-success']);
            return redirect()->back();


        } catch (\Throwable $th) {

            DB::rollBack();
        }
    }


    public function show(Expense $expense)
    {
        // return view('expenseReport.index');
    }


    public function edit($id)
    {
        $expense = Expense::with('head')->find($id);

        if($expense->head->name == "BandWith Buy"){
            Toastr::error("THis expense can not edit from here");
            return redirect()->back();
        }
        $data = [
            'model' => $expense,
            'expenseHead' => ExpenseHead::all(),
            'title' => 'Expense',
            'employees' => Employee::where('status','active')->get()
        ];
        // dd($data);
        return view('accounts.expense.edit', $data);
    }


    public function update(Request $request)
    {
        $type = 'Expense';
        $old_info = Expense::where('id', $request->id)->first();

        $expense = Expense::find($request->id);
        $expense->name = $request->name;
        $expense->invoice_number = $request->invoice_number;
        $expense->employee_id = $request->employee_id;
        $expense->date = Carbon::parse($request->date)->format('Y-m-d 00:00:00');
        $expense->amount = $request->amount;
        $expense->description = $request->description;
        $expense->expenseHead = $request->expenseHead;
        // $expense->created_by = auth()->user()->id;


        if ($request->attach_document != null) {
            // for s3 upload
            if (checkSettings('store_image_to_s3') === 'enable') {
              if ($expense->attach_document != null) {
                    // Extract the path after the domain
                    $parsedUrl = parse_url($expense->attach_document);
                    $oldPath = ltrim($parsedUrl['path'], '/'); // remove leading slash

                    // Delete the old file from S3
                    Storage::disk('s3')->delete($oldPath);
                }

                $fileName = time() . '.' . $request->attach_document->extension();
                $path = 'expenseDocument/' . $fileName;

                // Store the new file to S3
                $request->attach_document->storeAs('expenseDocument', $fileName, 's3');

                // Make it public (optional)
                Storage::disk('s3')->setVisibility($path, 'public');

                // Save the new file URL
                $expense->attach_document = Storage::disk('s3')->url($path);
            } else {
                  File::delete(public_path('storage/expenseDocument/' . $expense->attach_document));
                $fileName = time() . '.' . $request->attach_document->extension();
                $request->attach_document->move(storage_path('app/public/expenseDocument'), $fileName);
                $expense->attach_document = $fileName;
            }



        }

        $expense->save();

        $new_info = Expense::find($expense->id);
        (new EditLogHistory)->editLogSave($expense, $type, $old_info, $new_info);
        Toastr::success('success','Expense Updated Successfully',['success' => 'alert alert-success']);

        return redirect()->back();
    }


    public function destroy(Expense $expense)
    {
        Db::beginTransaction();
        try{
            $fund_transfer = FundTransfer::where('id',$expense->fund_transfer_id)->delete();
            $expense->delete();
            DB::commit();
            Toastr::success('success','Expense Deleted',['success' => 'alert alert-success']);
            return redirect()->route('expense.index');
        }catch(\Throwable $th){
            DB::rollBack();
            Toastr::error('error','Something Went Wrong',['error' => 'alert alert-danger']);
        }

    }

    public function expenseReport()
    {
        // dd('hello');
        $start = Carbon::now()->today()->firstOfMonth();;

        // dd($start);
        $end = today();
        return view('accounts.expenseReport.index', [
            'start' => $start,
            'end'   => $end,
            'expenseHeads' => ExpenseHead::all(),
        ]);
    }

    public function expenseSearchResult(Request $request)
    {


        $start = Carbon::parse($request->from_date)->format('Y-m-d 00:00:00');
        $end = Carbon::parse($request->to_date)->format('Y-m-d 23:59:59');
        if($request->expenseHead == 'all'){
            $expenses = Expense::whereBetween('date', [$start, $end])->orderBy('id','DESC')->get();
        }else{
            $expenses = Expense::whereBetween('date', [$start, $end])->where('expenseHead',$request->expenseHead)->orderBy('id','DESC')->get();
        }

        $data = [
            'expenses' => $expenses,
        ];
        return view('accounts.expenseReport.result',$data);


    }

    public function changeExpenseDate()
    {
        $expenses = Expense::wherebetween('date', ['2022-12-19 00:00:00', '2022-12-31 23:59:59'])->get();
        foreach ($expenses as $expense) {
            $expense->date = Carbon::parse($expense->date)->subMonth()->format('Y-m-d 00:00:00');
            $expense->save();
        }
        Toastr::success('success','Expense Date Changed',['success' => 'alert alert-success']);
        return redirect()->back();
    }
}
