<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\BankAccount;
use App\Models\ChequeLeaf;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class BankAccountController extends Controller
{
public function index(Request $request)
{
    $perPage = $request->get('per_page', 10);
    $search  = $request->get('search');

    $accounts = BankAccount::with(['bank', 'organize'])

        ->when($request->Org_Id, fn ($q, $v) =>
            $q->where('Org_Id', $v))

        ->when($request->Bank_Id, fn ($q, $v) =>
            $q->where('Bank_Id', $v))

        ->when($request->Org_Name, function ($q, $v) {
            $q->whereHas('organize', function ($org) use ($v) {
                $org->where('Org_Name', 'LIKE', "%{$v}%");
            });
        })

        ->when($request->Bank_name, function ($q, $v) {
            $q->whereHas('bank', function ($bank) use ($v) {
                $bank->where('bank_name', 'LIKE', "%{$v}%");
            });
        })

        ->when($request->account_name, fn ($q, $v) =>
            $q->where('account_name', 'LIKE', "%{$v}%"))

        ->when($request->account_number, fn ($q, $v) =>
            $q->where('account_number', 'LIKE', "%{$v}%"))

        ->when($request->branch_name, fn ($q, $v) =>
            $q->where('branch_name', 'LIKE', "%{$v}%"))

        ->when($request->ifsc, fn ($q, $v) =>
            $q->where('ifsc', 'LIKE', "%{$v}%"))

        ->when($request->filled('is_active'), fn ($q) =>
            $q->where('is_active', $request->boolean('is_active'))
        )

        ->when($search, function ($q) use ($search) {
            $q->where(function ($query) use ($search) {

                $query->where('account_name', 'LIKE', "%{$search}%")
                    ->orWhere('account_number', 'LIKE', "%{$search}%")
                    ->orWhere('branch_name', 'LIKE', "%{$search}%")
                    ->orWhere('ifsc', 'LIKE', "%{$search}%")

                    ->orWhereHas('bank', function ($bank) use ($search) {
                        $bank->where('bank_name', 'LIKE', "%{$search}%");
                    })

                    ->orWhereHas('organize', function ($org) use ($search) {
                        $org->where('Org_Name', 'LIKE', "%{$search}%");
                    });
            });
        })

        ->orderBy('account_name', 'ASC')
        ->paginate($perPage);

    $accounts->getCollection()->transform(function ($a) {
        return [
            ...$a->toArray(),
            'bank_name' => $a->bank?->bank_name,
            'Org_Name'  => $a->organize?->Org_Name,
        ];
    });

    return response()->json([
        'success' => true,
        'message' => 'Bank accounts fetched successfully.',
        'data'    => $accounts
    ]);
}

 public function show($id)
{
    $a = BankAccount::with(['bank', 'organize'])->findOrFail($id);

    return response()->json([
        'success' => true,
        'message' => 'Bank account fetched successfully.',
        'data' => [
            ...$a->toArray(),
            'bank_name' => $a->bank?->bank_name,
            'Org_Name'  => $a->organize?->Org_Name,
        ]
    ]);
}

    
    public function info($id)
    {
        $account = BankAccount::with('bank')->findOrFail($id);
        
        return response()->json([
            'bank_name'       => $account->bank?->bank_name,
            'account_name'    => $account->account_name,
            'account_number'  => $account->account_number,
            'ifsc'            => $account->ifsc,
            
        ]);
    }

 public function getAll(Request $request)
{
    $search = $request->get('search');

    $accounts = BankAccount::with(['bank', 'organize'])
        ->when($request->Org_Id, fn ($q, $v) => $q->where('Org_Id', $v))
        ->when($request->Bank_Id, fn ($q, $v) => $q->where('Bank_Id', $v))

        ->when($request->account_name, fn ($q, $v) =>
            $q->where('account_name', 'LIKE', "%{$v}%"))

        ->when($request->account_number, fn ($q, $v) =>
            $q->where('account_number', 'LIKE', "%{$v}%"))

        ->when($request->branch_name, fn ($q, $v) =>
            $q->where('branch_name', 'LIKE', "%{$v}%"))

        ->when($request->ifsc_code, fn ($q, $v) =>
            $q->where('ifsc_code', 'LIKE', "%{$v}%"))

        ->when($request->filled('is_active'), fn ($q) =>
            $q->where('is_active', $request->boolean('is_active'))
        )

        ->when($search, function ($q) use ($search) {
            $q->where(function ($query) use ($search) {
                $query->where('account_name', 'LIKE', "%{$search}%")
                    ->orWhere('account_number', 'LIKE', "%{$search}%")
                    ->orWhere('branch_name', 'LIKE', "%{$search}%")
                    ->orWhere('ifsc_code', 'LIKE', "%{$search}%")
                    ->orWhereHas('bank', function ($bank) use ($search) {
                        $bank->where('bank_name', 'LIKE', "%{$search}%");
                    })
                    ->orWhereHas('organize', function ($org) use ($search) {
                        $org->where('Org_Name', 'LIKE', "%{$search}%");
                    });
            });
        })

        ->orderBy('account_name', 'ASC')
        ->get()
        ->map(function ($a) {
            return [
                ...$a->toArray(),
                'bank_name' => $a->bank?->bank_name,
                'Org_Name'  => $a->organize?->Org_Name,
            ];
        });

    return response()->json([
        'success' => true,
        'count'   => $accounts->count(),
        'data'    => $accounts
    ]);
}

    public function store(Request $request)
    {
        $data = $request->validate([
            'Org_Id'      => 'required|exists:org_master,Org_Id',
            'Bank_Id'         => 'required|exists:banks,Bank_Id',
            'account_code'    => 'required|string|unique:bank_accounts,account_code',
            'account_name'    => 'required|string|max:200',
            'account_number'  => 'required|string|max:30',
            'account_type'    => 'in:current,savings,cc,od',
            'ifsc'            => 'nullable|string|max:15',
            'micr'            => 'nullable|string|max:15',
            'branch_name'     => 'nullable|string|max:150',
            'branch_code'     => 'nullable|string|max:20',
            'city'            => 'nullable|string|max:100',
            'address'         => 'nullable|string',
            'opening_balance' => 'nullable|numeric',
            'od_limit'        => 'nullable|numeric',
            'is_active'       => 'boolean',
        ]);
        $account = BankAccount::create($data);
        return response()->json($account, 201);
    }

    public function update(Request $request, $id)
    {
        $account = BankAccount::findOrFail($id);
        $data = $request->validate([
            'account_name'    => 'required|string|max:200',
            'account_code' => [
                'required',
                'string',
                Rule::unique('bank_accounts', 'account_code')
                    ->ignore($id, 'bank_account_id'),
            ],
            'account_number'  => 'required|string|max:30',
            'account_type'    => 'in:current,savings,cc,od',
            'ifsc'            => 'nullable|string|max:15',
            'micr'            => 'nullable|string|max:15',
            'branch_name'     => 'nullable|string|max:150',
            'branch_code'     => 'nullable|string|max:20',
            'city'            => 'nullable|string|max:100',
            'address'         => 'nullable|string',
            'opening_balance' => 'nullable|numeric',
            'od_limit'        => 'nullable|numeric',
            'is_active'       => 'boolean',
        ]);
        $account->update($data);
        return response()->json($account);
    }

    public function destroy($id)
{
    try {

        $account = BankAccount::findOrFail($id);

        $account->delete();

        return response()->json([
            'success' => true,
            'message' => 'Bank account deleted successfully.'
        ]);

    } catch (\Exception $e) {

        return response()->json([
            'success' => false,
            'message' => 'Failed to delete bank account.',
            'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
        ], 500);
    }
}
}
