<?php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\ChequeBook;
use App\Models\ChequeLeaf;
use App\Models\bookAccount;
use App\Models\LedgerMaster;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;

class ChequeBookController extends Controller
{
   

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

    $books = ChequeBook::with([
            'bank',
            'bookAccount',
            'organize',
            'status',
            'ChequeFormate'
        ])
        ->when($request->Org_Id, fn($q, $v) => $q->where('Org_Id', $v))
        ->when($request->cheque_format_id, fn($q, $v) => $q->where('cheque_format_id', $v))
        ->when($request->Bank_Id, fn($q, $v) => $q->where('Bank_Id', $v))
        ->when($request->Lg_Id, fn($q, $v) => $q->where('Lg_Id', $v))
        ->when($request->status_id, fn($q, $v) => $q->where('status_id', $v))
        ->when($request->book_reference, fn($q, $v) => $q->where('book_reference', 'LIKE', "%{$v}%"))
        ->when($request->leaf_from, fn($q, $v) => $q->where('leaf_from', $v))
        ->when($request->leaf_to, fn($q, $v) => $q->where('leaf_to', $v))
        ->when($request->issued_by_bank, fn($q, $v) => $q->where('issued_by_bank', $v))
        ->when($request->received_date, fn($q, $v) => $q->whereDate('received_date', $v))

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

                $query->where('book_reference', 'LIKE', "%{$search}%")
                    ->orWhere('leaf_from', 'LIKE', "%{$search}%")
                    ->orWhere('leaf_to', 'LIKE', "%{$search}%")
                    ->orWhere('issued_by_bank', 'LIKE', "%{$search}%")
                    ->orWhere('remarks', 'LIKE', "%{$search}%")

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

                    ->orWhereHas('bookAccount', function ($account) use ($search) {
                        $account->where('account_name', 'LIKE', "%{$search}%")
                                ->orWhere('account_number', 'LIKE', "%{$search}%");
                    })

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

        ->orderByDesc('created_at')
        ->paginate($perPage);

    $books->getCollection()->transform(function ($book) {

        return [
            'cheque_book_id'   => $book->cheque_book_id,
            'cheque_format_id'   => $book->cheque_format_id,
            'cheque_format' => $book->ChequeFormate,
            'book_reference'   => $book->book_reference,
            'leaf_from'        => $book->leaf_from,
            'leaf_to'          => $book->leaf_to,
            'total_leaves'     => $book->total_leaves,
            'used_leaves'      => $book->used_leaves,
            'issued_by_bank'      => $book->issued_by_bank,
            'available_leaves' => $book->total_leaves - $book->used_leaves,
            'received_date' => $book->received_date,
            'remarks'       => $book->remarks,
            'bank'         => $book->bank,
            'bank_account' => $book->bookAccount,
            'organization' => $book->organize,
            'status'       => $book->status,
        ];
    });

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

public function show($id)
{
    $book = ChequeBook::with([
        'bank',
        'bookAccount',
        'organize',
        'status',
        'ChequeFormate'
    ])->findOrFail($id);

    return response()->json([
        'cheque_book_id'   => $book->cheque_book_id,
        'cheque_format_id'   => $book->cheque_format_id,
        'cheque_format' => $book->ChequeFormate,
        'book_reference'   => $book->book_reference,
        'leaf_from'        => $book->leaf_from,
        'leaf_to'          => $book->leaf_to,
        'total_leaves'     => $book->total_leaves,
        'used_leaves'      => $book->used_leaves,
        'available_leaves' => $book->total_leaves - $book->used_leaves,
         'received_date' => $book->received_date,
        'remarks'       => $book->remarks,
        'bank'         => $book->bank,
        'bank_account' => $book->bookAccount,
        'organization' => $book->organize,
        'status' => $book->status,
    ]);
}

public function getAll(Request $request)
{
    try {

        $search = $request->get('search');

        $query = ChequeBook::with([
            'bank',
            'bookAccount',
            'organize',
            'status',
            'ChequeFormate'
        ])
        ->when($request->Org_Id, fn($q, $v) => $q->where('Org_Id', $v))
         ->when($request->cheque_format_id, fn($q, $v) => $q->where('cheque_format_id', $v))
        ->when($request->Bank_Id, fn($q, $v) => $q->where('Bank_Id', $v))
        ->when($request->Lg_Id, fn($q, $v) => $q->where('Lg_Id', $v))
        ->when($request->status_id, fn($q, $v) => $q->where('status_id', $v))
        ->when($request->book_reference, fn($q, $v) => $q->where('book_reference', 'LIKE', "%{$v}%"))
        ->when($request->leaf_from, fn($q, $v) => $q->where('leaf_from', $v))
        ->when($request->leaf_to, fn($q, $v) => $q->where('leaf_to', $v))
        ->when($request->received_date, fn($q, $v) => $q->whereDate('received_date', $v))

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

                $query->where('book_reference', 'LIKE', "%{$search}%")
                    ->orWhere('leaf_from', 'LIKE', "%{$search}%")
                    ->orWhere('leaf_to', 'LIKE', "%{$search}%")
                    ->orWhere('issued_by_bank', 'LIKE', "%{$search}%")
                    ->orWhere('remarks', 'LIKE', "%{$search}%")

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

                    ->orWhereHas('bookAccount', function ($account) use ($search) {
                        $account->where('account_name', 'LIKE', "%{$search}%")
                                ->orWhere('account_number', 'LIKE', "%{$search}%");
                    })

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

        ->orderByDesc('cheque_book_id');

        $books = $request->filled('per_page')
            ? $query->paginate($request->per_page)
            : $query->get()->map(function ($book) {

                return [
                    'cheque_book_id'   => $book->cheque_book_id,
                    'cheque_format_id'   => $book->cheque_format_id,
                    'cheque_format' => $book->ChequeFormate,
                    'Org_Id'           => $book->Org_Id,
                    'Bank_Id'          => $book->Bank_Id,
                    'Lg_Id'  => $book->Lg_Id,
                    'status_id'        => $book->status_id,

                    'book_reference'   => $book->book_reference,
                    'leaf_from'        => $book->leaf_from,
                    'leaf_to'          => $book->leaf_to,
                    'total_leaves'     => $book->total_leaves,
                    'used_leaves'      => $book->used_leaves,
                    'available_leaves' => $book->total_leaves - $book->used_leaves,

                    'received_date'    => $book->received_date,
                    'issued_by_bank'   => $book->issued_by_bank,
                    'remarks'          => $book->remarks,
                    'created_at'       => $book->created_at,
                    'updated_at'       => $book->updated_at,

                    'bank'          => $book->bank,
                    'bank_account'  => $book->bookAccount,
                    'organization'  => $book->organize,
                    'status_detail' => $book->status,
                ];
            });

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

    } catch (\Exception $e) {

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


    public function store(Request $request)
{
    try {

        $data = $request->validate([
            'Lg_Id' => 'required|exists:ledger_master,Lg_Id',
            'cheque_format_id' => 'nullable|exists:cheque_formats,cheque_format_id',
            'book_reference' => 'nullable|string|unique:cheque_books,book_reference',
            'leaf_from' => 'required|string|max:20',
            'leaf_to' => 'required|string|max:20',
            'total_leaves' => 'required|integer|min:1',
            'received_date' => 'nullable|date',
            'issued_by_bank' => 'nullable|string|max:200',
            'remarks' => 'nullable|string',
        ]);

        $account = LedgerMaster::findOrFail($data['Lg_Id']);

        DB::transaction(function () use ($data, $account, $request) {

            ChequeBook::create([
                ...$data,
                'Org_Id' => $account->Org_Id,
                'Bank_Id' => $account->Bank_Id,
                'used_leaves' => 0,
                'status' => $account->Act_Id,
                
            ]);

        });

        return response()->json([
            'success' => true,
            'message' => 'Cheque book added successfully.'
        ], 201);

    } catch (\Illuminate\Validation\ValidationException $e) {

        return response()->json([
            'success' => false,
            'message' => 'Validation failed.',
            'errors' => $e->errors()
        ], 422);

    } catch (\Exception $e) {

        Log::error('Cheque Book Store Error', [
            'message' => $e->getMessage(),
            'file' => $e->getFile(),
            'line' => $e->getLine(),
        ]);

        return response()->json([
            'success' => false,
            'message' => config('app.debug')
                ? $e->getMessage()
                : 'Something went wrong. Please try again later.'
        ], 500);
    }
}

public function update(Request $request, $id)
{
    $book = ChequeBook::findOrFail($id);

    $data = $request->validate([
        'Lg_Id' => 'nullable|exists:ledger_master,Lg_Id',
        'cheque_format_id' => 'nullable|exists:cheque_formats,cheque_format_id',
        'book_reference' => [
            'nullable',
            'string',
            Rule::unique('cheque_books', 'book_reference')
                ->ignore($book->cheque_book_id, 'cheque_book_id'),
        ],
        'leaf_from'      => 'nullable|string|max:20',
        'leaf_to'        => 'nullable|string|max:20',
        'total_leaves'   => 'nullable|integer|min:1',
        'received_date'  => 'nullable|date',
        'issued_by_bank' => 'nullable|string|max:200',
        'remarks'        => 'nullable|string',
        'status'         => 'nullable|integer',
    ]);

    if ($request->filled('Lg_Id')) {
        $account = LedgerMaster::findOrFail($request->Lg_Id);

        $data['Org_Id']  = $account->Org_Id;
        $data['Bank_Id'] = $account->Bank_Id;
    }

    $book->update($data);

    return response()->json([
        'success' => true,
        'message' => 'Cheque book updated successfully',
        'data' => $book->fresh()
    ]);
}

    public function close(Request $request, $id)
    {
        $book = ChequeBook::findOrFail($id);
        if ($book->status !== 'active') {
            return response()->json(['message' => 'Book is already closed.'], 422);
        }
        DB::transaction(function () use ($book, $request) {
           
        });
        return response()->json(['message' => 'Cheque book closed.']);
    }


public function destroy($id)
{
    try {

        $account = ChequeBook::find($id);

        if (!$account) {
            return response()->json([
                'success' => false,
                'message' => "Bank account not found. ID: {$id}"
            ], 404);
        }

        $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);
    }
}


}
