<?php

namespace App\Http\Controllers;

use App\CashInHandEntry;
use App\Ledger;
use App\LedgerType;
use App\LedgerSubcategory;
use App\Services\DailyBookService;
use App\Business;
use App\BusinessPartner;
use App\Contact;
use App\DailyBookEntry;
use Illuminate\Support\Facades\DB;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
use Yajra\DataTables\Facades\DataTables; // correct import

class CashInHandController extends Controller
{
    public function index()
    {
        $entries = CashInHandEntry::with(['ledgerType', 'ledgerSubcategory', 'creator'])
            ->latest('entry_date')
            ->paginate(20);

        $business_id = request()->session()->get('user.business_id');
        $business = Business::find($business_id);
        // dd($business['cash_in_hand_open_balance']);
        // Calculate totals
        $totals = [
            'receipt' => CashInHandEntry::where('dr_cr', 'cr')->sum('amount'),  // Cash In
            'payment' => CashInHandEntry::where('dr_cr', 'dr')->sum('amount'),  // Cash Out
        ];

        // Net Balance = Cash In - Cash Out
        // $totals['balance'] = /*$business['cash_in_hand_open_balance'] +*/ ($totals['receipt'] - $totals['payment']);
        $totals['balance'] = $business['cash_in_hand_open_balance'];

        return view('cashinhand.index', compact('totals'));
    }

    /**
     * DataTable JSON response
     */
    public function getData(Request $request)
    {
        // $query = CashInHandEntry::with(['ledgerType', 'ledgerSubcategory', 'creator']);
        $query = CashInHandEntry::with(['ledgerType', 'ledgerSubcategory', 'contact', 'partner', 'creator']);


        return DataTables::of($query)
            ->addColumn('sr_no', function ($row) {
                static $count = 0;
                return ++$count;
            })
            ->editColumn('entry_date', function ($row) {
                return $row->entry_date ? $row->entry_date->format('d M Y') : '-';
            })
            ->addColumn('ledger_type', function ($row) {
                return $row->ledgerType ? $row->ledgerType->name : '-';
            })
            /*->addColumn('ledger_subcategory', function ($row) {
                return $row->ledgerSubcategory ? $row->ledgerSubcategory->name : '-';
            })*/
            ->addColumn('ledger_subcategory', function ($row) {
                if (!$row->ledgerType) {
                    return '-';
                }

                switch ($row->ledgerType->name) {
                    case 'Customer / Supplier':
                        if ($row->contact) {
                            return $row->contact->supplier_business_name 
                                ?: $row->contact->name;
                        }
                        return '-';

                    case 'Partners':
                        return $row->partner ? $row->partner->name : '-';

                    default:
                        return $row->ledgerSubcategory ? $row->ledgerSubcategory->name : '-';
                }
            })
            ->addColumn('created_by', function ($row) {
                return $row->creator ? $row->creator->name : '-';
            })
            ->editColumn('dr_cr', function ($row) {
                return $row->dr_cr == 'dr'
                    ? '<span class="badge badge-success">Debit</span>'
                    : '<span class="badge badge-danger">Credit</span>';
            })
            ->editColumn('amount', function ($row) {
                return number_format($row->amount, 2);
            })
            ->editColumn('balance', function ($row) {
                return number_format($row->balance, 2);
            })
            ->addColumn('action', function ($row) {
                $editUrl = route('cashinhand.edit', $row->id);
                $deleteUrl = route('cashinhand.destroy', $row->id);

                return '
                    <a href="'.$editUrl.'" class="btn btn-sm btn-outline-primary">
                        <button class="btn btn-sm btn-warning">
                            <i class="fa fa-edit"></i>
                        </button>
                    </a>
                    <form action="'.$deleteUrl.'" method="POST" style="display:inline;" 
                          onsubmit="return confirm(\'Delete this entry?\')">
                        '.csrf_field().method_field("DELETE").'
                        <button class="btn btn-sm btn-danger">
                            <i class="fa fa-trash"></i>
                        </button>
                    </form>
                ';
            })
            ->rawColumns(['dr_cr', 'action'])
            ->make(true);
    }

    public function create()
    {
        // Fetch all ledger types with their subcategories and ledgers
        $ledgerTypes = LedgerType::with('subcategories')
            ->orderBy('name')
            ->get();
        // $ledgerTypes = LedgerType::with(['subcategories.ledgers'])->orderBy('name')->get();
        // dd($ledgerTypes);

        return view('cashinhand.create', compact('ledgerTypes'));
    }

    public function store(Request $request)
    {
        // dd($request->all());
        /*$data = $request->validate([
            'entry_date'            => ['required', 'date'],
            // 'type'                  => ['required', 'in:receipt,payment,expense,adjustment'],
            'ledger_type_id'        => ['required', 'exists:ledger_types,id'],
            'ledger_subcategory_id' => ['required', 'exists:ledger_subcategories,id'],
            'ledger_subcategory_id' => ['required', 'integer', $ledgerRule],
            'detail'                => ['required', 'string', 'max:500'],
            'dr_cr'                 => ['required', 'in:dr,cr'],
            'amount'                => ['required', 'numeric', 'min:0.01'],
        ]);*/

        $ledgerType = \App\LedgerType::find($request->ledger_type_id);

        if ($ledgerType && $ledgerType->slug === 'customer-supplier') {
            $ledgerRule = Rule::exists('contacts', 'id')
                ->where('contact_status', 'active');
        } elseif ($ledgerType && $ledgerType->name === 'Partners') {
            $ledgerRule = Rule::exists('business_partners', 'id');
        } else {
            $ledgerRule = Rule::exists('ledger_subcategories', 'id');
        }

        

        $data = $request->validate([
            'entry_date'            => ['required', 'date'],
            // 'type'                  => ['required', 'in:receipt,payment,expense,adjustment'],
            'ledger_type_id'        => ['required', 'exists:ledger_types,id'],
            // 'ledger_subcategory_id' => ['required', 'exists:ledger_subcategories,id'],
            'ledger_subcategory_id' => ['required', 'string', $ledgerRule],
            'detail'                => ['required', 'string', 'max:500'],
            'dr_cr'                 => ['required', 'in:dr,cr'],
            'amount'                => ['required', 'numeric', 'min:0.01'],
        ]);

        // dd($data);

        /*$data = $request->validate([
            'entry_date'     => ['required', 'date'],
            'ledger_type_id' => ['required', 'exists:ledger_types,id'],
            'detail'         => ['required', 'string', 'max:500'],
            'dr_cr'          => ['required', 'in:dr,cr'],
            'amount'         => ['required', 'numeric', 'min:0.01'],
            'ledger_subcategory_id' => [
                'required',
                'integer',
                Rule::exists('ledger_subcategories', 'id')
                    ->where(function ($query) use ($request) {
                        $ledgerType = \App\LedgerType::find($request->ledger_type_id);
                        if ($ledgerType && $ledgerType->slug === 'customer-supplier') {
                            $query->from('contacts')->where('contact_status', 'active');
                        } elseif ($ledgerType && $ledgerType->name === 'Partners') {
                            $query->from('business_partners');
                        }
                    })
            ],
        ]);*/


        $data['created_by'] = auth()->user()->id;
        // dd($data['created_by']);

        // Prepare debit/credit
        // $debit  = $data['dr_cr'] === 'dr' ? $data['amount'] : 0;
        // $credit = $data['dr_cr'] === 'cr' ? $data['amount'] : 0;
        
        // Prepare debit/credit
        $debit  = $data['dr_cr'] === 'dr' ? $data['amount'] : 0;
        $credit = $data['dr_cr'] === 'cr' ? $data['amount'] : 0;

        $business_id = request()->session()->get('user.business_id');
        $business = Business::find($business_id);

        // Current balance
        $current_balance = $business->cash_in_hand_open_balance;

        // Calculate new balance
        if ($data['dr_cr'] === 'cr') {
            $new_balance = $current_balance + $data['amount'];
        } elseif ($data['dr_cr'] === 'dr') {
            $new_balance = $current_balance - $data['amount'];
        } else {
            $new_balance = $current_balance; // in case neither dr nor cr
        }

        // Store balance in $data
        $data['balance'] = $new_balance;

        $entry = CashInHandEntry::create($data);

        // Update business table with new balance
        $business->cash_in_hand_open_balance = $new_balance;
        $business->save();


        // Add to DailyBook
        DailyBookService::addEntry(
            $data['entry_date'],
            'cashinhand',
            $data['ledger_type_id'],
            $data['ledger_subcategory_id'],
            $data['detail'],
            $debit,
            $credit,
            'CashInHandEntry', // reference_type
            $entry->id              // reference_id
        );

        return redirect()
            ->route('cashinhand.index')
            ->with('success', 'Cash in Hand entry and balance saved.');
    }

    public function edit($id)
    {
        $entry = CashInHandEntry::findOrFail($id);
        $ledgerTypes = LedgerType::with('subcategories')->orderBy('name')->get();

        // for edit form prepopulation (subcategory list)
        $ledgerType = $entry->ledgerType;
        $subcategories = [];

        if ($ledgerType) {
            if ($ledgerType->slug === 'customer-supplier') {
                $business_id = request()->session()->get('user.business_id');
                $subcategories = Contact::where('business_id', $business_id)
                    ->where('contact_status', 'active')
                    ->whereIn('type', ['customer', 'supplier'])
                    ->select(
                        'id',
                        'type',
                        DB::raw("CASE 
                            WHEN supplier_business_name != '' THEN CONCAT(type, ' - ', supplier_business_name) 
                            ELSE CONCAT(type, ' - ', name) 
                        END as name")
                    )
                    ->get();
            } elseif ($ledgerType->name === 'Partners') {
                $subcategories = BusinessPartner::select('id', 'name', 'percentage')->get();
            } else {
                $subcategories = LedgerSubcategory::where('ledger_type_id', $ledgerType->id)->get();
            }
        }

        return view('cashinhand.edit', compact('entry', 'ledgerTypes', 'subcategories'));
    }

    public function update(Request $request, $id)
    {
        $entry = CashInHandEntry::findOrFail($id);

        $ledgerType = LedgerType::find($request->ledger_type_id);

        // Apply same validation logic as store()
        if ($ledgerType && $ledgerType->slug === 'customer-supplier') {
            $ledgerRule = Rule::exists('contacts', 'id')
                ->where('contact_status', 'active');
        } elseif ($ledgerType && $ledgerType->name === 'Partners') {
            $ledgerRule = Rule::exists('business_partners', 'id');
        } else {
            $ledgerRule = Rule::exists('ledger_subcategories', 'id');
        }

        $data = $request->validate([
            'entry_date'            => ['required', 'date'],
            'ledger_type_id'        => ['required', 'exists:ledger_types,id'],
            'ledger_subcategory_id' => ['required', 'string', $ledgerRule],
            'detail'                => ['required', 'string', 'max:500'],
            'dr_cr'                 => ['required', 'in:dr,cr'],
            'amount'                => ['required', 'numeric', 'min:0.01'],
        ]);

        // recalc debit / credit
        $debit  = $data['dr_cr'] === 'dr' ? $data['amount'] : 0;
        $credit = $data['dr_cr'] === 'cr' ? $data['amount'] : 0;

        // update business balance (rollback previous entry effect first)
        $business_id = request()->session()->get('user.business_id');
        $business = Business::find($business_id);

        $current_balance = $business->cash_in_hand_open_balance;

        // rollback old entry effect
        if ($entry->dr_cr === 'cr') {
            $current_balance -= $entry->amount;
        } elseif ($entry->dr_cr === 'dr') {
            $current_balance += $entry->amount;
        }

        // apply new entry effect
        if ($data['dr_cr'] === 'cr') {
            $new_balance = $current_balance + $data['amount'];
        } else {
            $new_balance = $current_balance - $data['amount'];
        }

        $data['balance'] = $new_balance;

        // update entry
        // $entry->update($data);

        // update business table
        $business->cash_in_hand_open_balance = $new_balance;
        // $business->save();

        // Update DailyBook entry
        DailyBookService::updateEntry(
            'CashInHandEntry',
            $entry->id,
            $data['entry_date'],
            'cashinhand',
            $data['ledger_type_id'],
            $data['ledger_subcategory_id'],
            $data['detail'],
            $debit,
            $credit
        );

        return redirect()->route('cashinhand.index')->with('success', 'Cash in Hand entry and balance updated.');
    }

    public function destroy($id)
    {
        $entry = CashInHandEntry::findOrFail($id);
        $business_id = request()->session()->get('user.business_id');
        $business = Business::findOrFail($business_id);

        // Delete related DailyBook record
        DailyBookService::deleteEntry('CashInHandEntry', $entry->id);

        // Adjust business balance
        if ($entry->dr_cr === 'dr') {
            // If it was Debit (Cash In), subtract it
            $business->cash_in_hand_open_balance -= $entry->amount;
        } else {
            // If it was Credit (Cash Out), add it back
            $business->cash_in_hand_open_balance += $entry->amount;
        }
        $business->save();

        // Finally delete the entry
        $entry->delete();

        return redirect()
            ->route('cashinhand.index')
            ->with('success', 'Cash in Hand entry deleted and balance updated.');
    }

    public function getSubcategories($id)
    {
        $ledgerType = LedgerType::findOrFail($id);

        if ($ledgerType->name === 'Customer / Supplier') {
            // Fetch customers & suppliers
            $business_id = request()->session()->get('user.business_id');
            /*$subcategories = Contact::where('business_id', $business_id)
                ->where('contact_status', 'active')
                ->whereIn('type', ['customer', 'supplier'])
                ->select('id', 'name', 'type', 'supplier_business_name')
                ->get();*/

            $subcategories = Contact::where('business_id', $business_id)
                ->where('contact_status', 'active')
                ->whereIn('type', ['customer', 'supplier'])
                ->select(
                    'id',
                    'type',
                    DB::raw("CASE 
                        WHEN supplier_business_name != '' THEN CONCAT(type, ' - ', supplier_business_name) 
                        ELSE CONCAT(type, ' - ', name) 
                    END as name")
                )
                ->get();

        } elseif ($ledgerType->name === 'Partners') {
            // Fetch partners
            // $business_id = request()->session()->get('user.business_id');
            $subcategories = BusinessPartner::select('id', 'name', 'percentage')->get();

        } else {
            // Default → fetch from ledger_subcategories
            $subcategories = LedgerSubcategory::where('ledger_type_id', $id)
                ->select('id', 'name')
                ->get();
        }

        return response()->json($subcategories);
    }


    public function ledgerReport()
    {
        $ledgerTypes = LedgerType::with('subcategories')->orderBy('name')->get();

        return view('cashinhand.ledger_report', compact('ledgerTypes'));
    }

    public function getLedgerReportData(Request $request)
    {
        $query = DailyBookEntry::with(['ledgerType', 'ledgerSubcategory', 'contact', 'partner', 'creator'])
            ->when($request->from && $request->to, function ($q) use ($request) {
                $q->whereBetween('entry_date', [$request->from, $request->to]);
            })
            ->when($request->ledger_type_id, function ($q) use ($request) {
                $q->where('ledger_type_id', $request->ledger_type_id);
            })
            ->when($request->ledger_subcategory_id, function ($q) use ($request) {
                $q->where('ledger_subcategory_id', $request->ledger_subcategory_id);
            })
            ->orderBy('entry_date', 'desc');

        return DataTables::of($query)
            ->addColumn('sr_no', function ($row) {
                static $count = 0;
                return ++$count;
            })
            ->editColumn('entry_date', function ($row) {
                return $row->entry_date ? $row->entry_date->format('d M Y') : '-';
            })
            ->addColumn('ledger_type', function ($row) {
                return $row->ledgerType ? $row->ledgerType->name : '-';
            })
            ->addColumn('ledger_subcategory', function ($row) {
                if (!$row->ledgerType) {
                    return '-';
                }

                switch ($row->ledgerType->name) {
                    case 'Customer / Supplier':
                        if ($row->contact) {
                            return $row->contact->supplier_business_name ?: $row->contact->name;
                        }
                        return '-';

                    case 'Partners':
                        return $row->partner ? $row->partner->name : '-';

                    default:
                        return $row->ledgerSubcategory ? $row->ledgerSubcategory->name : '-';
                }
            })
            ->addColumn('detail', function ($row) {
                return $row->detail ?? '-';
            })
            ->editColumn('debit', function ($row) {
                return number_format($row->debit, 2);
            })
            ->editColumn('credit', function ($row) {
                return number_format($row->credit, 2);
            })
            /*->addColumn('created_by', function ($row) {
                return $row->creator ? $row->creator->name : '-';
            })*/
            ->rawColumns(['detail'])
            ->make(true);
    }

    /*public function edit($id)
    {
        $entry = CashInHandEntry::findOrFail($id);
        $ledgerTypes = LedgerType::with('subcategories')->orderBy('name')->get();

        return view('cashinhand.edit', compact('entry', 'ledgerTypes'));
    }

    public function update(Request $request, $id)
    {
        $entry = CashInHandEntry::findOrFail($id);

        $data = $request->validate([
            'entry_date'            => ['required', 'date'],
            'ledger_type_id'        => ['required', 'exists:ledger_types,id'],
            'ledger_subcategory_id' => ['required', 'exists:ledger_subcategories,id'],
            'detail'                => ['nullable', 'string', 'max:500'],
            'dr_cr'                 => ['required', 'in:dr,cr'],
            'amount'                => ['required', 'numeric', 'min:0.01'],
        ]);

        $entry->update($data);

        // Update related DailyBook entry
        DailyBook::where('reference_type', 'CashInHandEntry')
            ->where('reference_id', $entry->id)
            ->update([
                'entry_date'         => $data['entry_date'],
                'ledger_type_id'     => $data['ledger_type_id'],
                'ledger_subcategory_id' => $data['ledger_subcategory_id'],
                'detail'             => $data['detail'],
                'debit'              => $data['dr_cr'] === 'dr' ? $data['amount'] : 0,
                'credit'             => $data['dr_cr'] === 'cr' ? $data['amount'] : 0,
            ]);


        return redirect()->route('cashinhand.index')->with('success', 'Cash in Hand entry updated.');
    }*/


}
