<?php

namespace App\Http\Controllers\Library;

use App\Http\Controllers\Controller;
use App\Models\Account;
use App\Models\FinancialYear;
use App\Models\InvoiceSerialSetting;
use App\Models\Librarian\Books;
use App\Models\Library\BookIssue;
use App\Models\Library\BookIssueDetail;
use App\Models\Library\LibraryCard;
use App\Models\Library\MembershipPlan;
use App\Models\MasterType;
use App\Models\Product;
use App\Models\SaleInvoice;
use App\Models\Students\Student;
use App\Models\Students\StudentAdmission;
use App\Models\TblStock;
use App\Models\VoucherMaster;
use App\Models\VoucherType;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Picqer;

class BookIssueController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:book-issue-list|book-issue-create|book-issue-edit|book-issue-delete', ['only' => ['index', 'store', 'list']]);
    }

    public function index(Request $request)
    {
        $bookIssueQuery = BookIssue::with(['getStudentDetails', 'getFinancialyear', 'details'])
            ->select(['id', 'account_id', 'financial_id', 'issue_no', 'issue_date', 'return_due_date'])
            ->latest('id');

        $query = $request->get('query');
        $sort_by = $request->get('sortby') ?? 10;
        $sort_type = $request->get('sorttype');

        if (!empty($query) && $query !== " ") {
            $bookIssueQuery->whereHas('getStudentDetails', function ($q) use ($query) {
                $q->where('name', 'like', '%' . $query . '%');
            });
        }

        $BookIssue = $bookIssueQuery->paginate($sort_by);

        if ($request->ajax()) {
            return view('library.book-issue.table', compact('BookIssue'));
        } else {
            return view('library.book-issue.index', compact('BookIssue'));
        }
    }
    public function create()
    {
        $financialYears = FinancialYear::select(['financialyearid', 'financial_year_name', 'is_default'])->where(['status' => '1'])->orderBy('financialyearid', 'desc')->get();
        return view('library.book-issue.create', compact('financialYears'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'student_name' => 'required',
            'book_id'      => 'required',
        ]);

        $Studentdata = Account::select('id')->where('id', $request->student_name)->first();

        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'INVENTORY')->first();
        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'MATERAIL_ISSUE')->first();

        # last voucher count for main invoice number
        $voucher_count      = BookIssue::select('last_issue_no_count')->orderBy('created_at', 'DESC')->first();
        $last_voucher_count = isset($voucher_count) && isset($voucher_count->last_issue_no_count) ? $voucher_count->last_issue_no_count + 1 : ($voucher_type->voucherSeries->start_from ?? 1);

        $issue_no = $this->generateCode(
            $last_voucher_count,
            ($voucher_type->voucherSeries->prefix ?? 'MI'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );



        $return_due_date = bookexpirecalculate($request->student_name, $request->financial_year_id, date('Y-m-d', strtotime($request->issue_date)));
        // getBook Limit
        $BookLimit = bookLimit($request->student_name, $request->financial_year_id);

        $BookIsue = BookIssue::where('account_id', $Studentdata->id)->get();
        $totalqty = 0;

        foreach ($BookIsue as $issue) {
            $qnts = BookIssueDetail::where('book_issue_id', $issue->id)->where('return_status', 'No')->sum('qnt');
            $totalqty += $qnts;
        }
        if ($BookLimit >= $totalqty) {

            $InserBookIsseu['account_id']             =   $Studentdata->id;
            $InserBookIsseu['financial_id']           =   $request->financial_year_id;
            $InserBookIsseu['issue_date']             =   date('Y-m-d', strtotime($request->issue_date));
            $InserBookIsseu['issue_no']               =   $issue_no;
            $InserBookIsseu['last_issue_no_count']    =   $last_voucher_count;
            $InserBookIsseu['return_due_date']        =   $return_due_date;
            $booksissue = BookIssue::create($InserBookIsseu);
            $book_issue_id = $booksissue->id;

            $cart = session()->get('issueCart');

            foreach ($request->book_id as $key => $list) {

                $BookIsue = BookIssue::where('account_id', $Studentdata->id)->get();
                $totalqty = 0;

                foreach ($BookIsue as $issue) {
                    $qnts = BookIssueDetail::where('book_issue_id', $issue->id)->where('return_status', 'No')->sum('qnt');
                    $totalqty += $qnts;
                }

                if ($BookLimit >= $totalqty) {
                    $books = Product::select('id')->where('id', $list)->first();
                    $InsertBookDetails = [
                        'book_issue_id'     =>  $book_issue_id,
                        'product_id'        =>  $books->id,
                        'qnt'               =>  $request->qnt[$key],
                        'return_due_date'   =>  $return_due_date,
                    ];
                    $BookIssueDeatisl = BookIssueDetail::create($InsertBookDetails);
                    $InsertStock =   [
                        'financial_id'     =>  $request->financial_year_id,
                        'invoice_id'        =>  $book_issue_id,
                        'stock_type'        =>  'Book Issue',
                        'stock_item_date'   =>  date('Y-m-d'),
                        'stock_item_id'     =>  $books->id,
                        'stock_out'         =>  $request->qnt[$key],
                        'stock_company_id'  =>  Auth::user()->company_id,

                    ];
                    TblStock::create($InsertStock);
                }

                if (isset($cart[$list])) {
                    unset($cart[$list]);
                    session()->put('issueCart', $cart);
                }
            }
            return to_route('book-issue.index')->with('success', 'Book issue Create successfully');
        } else {
            return to_route('book-issue.index')->with('error', 'You Have Already Limited Book Issue');
        }
    }

    public function edit($id, Request $request)
    {
        $data['bookIssue'] = BookIssue::with(['getStudentDetails', 'issueDetails.book'])->find($id);
        $data['financialYears'] = FinancialYear::select(['financialyearid', 'financial_year_name', 'is_default'])->where(['status' => '1'])->orderBy('financialyearid', 'desc')->get();
        return view('library.book-issue.edit', $data);
    }

    public function show($id, Request $request)
    {
        $bookIssue = BookIssue::with(['getStudentAllDetails', 'issueDetails.book'])->find($id);
        $data['bookIssue'] = $bookIssue;

        $generator = new Picqer\Barcode\BarcodeGeneratorHTML();
        $data['borcode'] = $generator->getBarcode($bookIssue->issue_no, $generator::TYPE_CODE_128) ? $generator->getBarcode($bookIssue->issue_no, $generator::TYPE_CODE_128) : "";
        return view('library.book-issue.show', $data);
    }

    public function update($id, Request $request)
    {
        $request->validate([
            'student_name' => 'required',
            'book_id' => 'required',
        ]);
        $bookIssue = BookIssue::find($id);
        $financialYears = FinancialYear::select('financialyearid')->latest('financialyearid')->where('status', '1')->first();

        $return_due_date = bookexpirecalculate($request->student_name, $request->financial_year_id, date('Y-m-d', strtotime($request->issue_date)));


        $Studentdata = Account::select('id')->where('id', $request->student_name)->first();
        $InserBookIsseu['accounnt_id']        =   $Studentdata->id;
        $InserBookIsseu['financial_id']     =   $request->financial_year_id;
        $InserBookIsseu['issue_date']       =   date('Y-m-d', strtotime($request->issue_date));
        $InserBookIsseu['return_due_date']  =   $return_due_date;
        $bookIssue->update($InserBookIsseu);
        $book_issue_id = $id;

        $cart = session()->get('issueCart');
        foreach ($request->book_id as $key => $list) {
            $books = Product::select('id')->where('id', $list)->first();
            if ($request->book_issue_details_id[$key] != '' || $request->book_issue_details_id[$key] != NULL) {
                $BookIssueDeatisl = BookIssueDetail::find($request->book_issue_details_id[$key]);
                $InsertBookDetails  =   [
                    'book_issue_id'    =>  $book_issue_id,
                    'product_id'           =>  $books->id,
                    'qnt'               =>  $request->qnt[$key],
                    'return_due_date'   =>  $return_due_date,
                ];
                $BookIssueDeatisl->update($InsertBookDetails);
            } else {
                $InsertBookDetails = [
                    'book_issue_id'    =>  $book_issue_id,
                    'product_id'           =>  $books->id,
                    'qnt'               =>  $request->qnt[$key],
                    'return_due_date'   =>  $return_due_date,
                ];
                $BookIssueDeatisl = BookIssueDetail::create($InsertBookDetails);
                $InsertStock    =   [
                    'financial_id'     =>  $request->financial_year_id,
                    'invoice_id'        =>  $book_issue_id,
                    'stock_type'        =>  'Book Issue',
                    'stock_item_date'   =>  date('Y-m-d'),
                    'stock_item_id'     =>  $books->id,
                    'stock_out'         =>  $request->qnt[$key],
                    'stock_company_id'  =>  Auth::user()->company_id,

                ];
                TblStock::create($InsertStock);
            }


            if (isset($cart[$list])) {
                unset($cart[$list]);
                session()->put('issueCart', $cart);
            }
        }
        return to_route('book-issue.index')->with('success', 'Book issue Update successfully');
    }

    public function deletebookitem(Request $request)
    {
        $license    =   BookIssueDetail::find($request->id);
        $invoice_id =   $license->book_issue_id;
        $book_id    =   $license->book_id;
        $license->delete();

        /*************************Stock Table Remove Stock Out *******************************/
        TblStock::where(['invoice_id' => $invoice_id, 'stock_item_id' => $book_id, 'stock_type' => 'Book Issue'])->delete();

        $Redirect = '/library/book-issue';
        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data' => [
                'redirect' => $Redirect,
            ]
        ]);
    }

    public function delete(Request $request)
    {
        $BookIssue  = BookIssue::find($request->id);
        $BookIssue->delete();


        /************************************ book Issue Details Delete Item ******************************/
        $BookIssuedetails   = BookIssueDetail::where('book_issue_id', $request->id);
        $BookIssuedetails->delete();


        /************************************ Stock Delete Item ******************************/
        $Stock = TblStock::where(['invoice_id' => $request->id, 'stock_type' => 'Book Issue']);
        $Stock->delete();


        $Redirect = 'book-issue';
        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data' => [
                'redirect' => $Redirect,
            ]
        ]);
    }


    public function studentssearch(Request $request)
    {

        $query = $request->get('q');

        $account_types      = MasterType::where('account_types.type_name', 'like', '%Student%')->first();

        $filterResult = Account::where('name', 'LIKE', '%' . $query . '%')
            ->OrWhere('unique_register_no', 'LIKE', '%' . $query . '%')
            ->where('account_type_id', $account_types->id)
            ->select(['id', 'name'])
            ->get();


        return response()->json(['result' => $filterResult, 'status' => true]);
    }

    public function bookssearch(Request $request)
    {
        $query = $request->get('q');
        $data = Product::select(['id', 'short_name as name', 'shortcode'])
            ->where('is_book', 1)
            ->where('short_name', 'LIKE',  $query . '%')
            ->OrWhere('shortcode', 'LIKE', $query . '%')
            ->OrWhere('hsncode', 'LIKE', $query . '%')
            ->limit(20)
            ->get();
        return response()->json(['result' => $data, 'status' => true]);
    }
    public function print($id, Request $request)
    {
        $bookIssue = BookIssue::with(['getStudentAllDetails', 'issueDetails.book'])->find($id);
        $data['bookIssue'] = $bookIssue;
        $generator = new Picqer\Barcode\BarcodeGeneratorHTML();
        $data['borcode'] = $generator->getBarcode($bookIssue->issue_no, $generator::TYPE_CODE_128) ? $generator->getBarcode($bookIssue->issue_no, $generator::TYPE_CODE_128) : "";
        return view('library.book-issue.print', $data);
    }


    /*******************Generate Book Issue No ********************/
    public function generatebookIssueNo()
    {
        /*********************Book Issue Count **********************/
        $getDataSerial = InvoiceSerialSetting::where('module_type', 'Book Issue')->first();
        $bookIssueCount = BookIssue::count();
        if ($bookIssueCount > 0) {
            return $IssueNo = $getDataSerial->prefix . '00' . $bookIssueCount + 1;
        } else {

            if ($getDataSerial) {
                return $IssueNo = $getDataSerial->prefix . '00' . $getDataSerial->startfrom + 1;
            } else {
                return $IssueNo = 'BI001';
            }
        }
    }

    /********************************* */


    public function booksstoreopenapi(Request $request)
    {
        return $request;
    }



    public function addtoissuecart(Request $request)
    {
        $Product = Product::findOrFail($request->book_id);

        $cart = session()->get('issueCart', []);

        if (isset($cart[$request->book_id])) {
            $cart[$request->book_id]['quantity']++;
        } else {
            $cart[$request->book_id] = [
                "name"          => $Product->short_name,
                "isbn"          => $Product->shortcode??'',
                'account_id'    => $request->student_id,
                'author'        => $Product->book_details->author ?? '',
                'publisher'     => $Product->book_details->publisher ?? '',
                "quantity"      => 1,
            ];
        }

        session()->put('issueCart', $cart);
        if ($cart) {
            return response()->json([
                'success' => true,
            ]);
        } else {
            return response()->json([
                'success' => false,
            ]);
        }
    }

    public function getcartissues(Request $request)
    {
        $data = Session::get('issueCart') ?? [];
        return view('library.book-issue.cart', compact('data'));
    }

    public function getcartissuesupdate(Request $request)
    {
        $data = Session::get('issueCart') ?? [];
        return view('library.book-issue.update-cart', compact('data'));
    }

    public function removecartissues(Request $request)
    {
        $data = Session::get('issueCart') ?? [];
        $id   = $request->id;
        $issue_id= $request->issue_id;
        if($issue_id)
        {
            BookIssueDetail::where('id',$issue_id)->delete();
        }

        if ($request->id) {
            $cart = session()->get('issueCart');
            if (isset($cart[$request->id])) {
                unset($cart[$request->id]);
                session()->put('issueCart', $cart);
            }
        }

        return response()->json(['success' => true]);
    }

    public function checkmembership(Request $request)
    {

        $membership = LibraryCard::where('account_id', $request->student_id)->first();
        if ($membership) {
            return response()->json([
                'success' => true,
                'message' => ['Library Card Generate'],
            ]);
        } else {
            return response()->json([
                'success' => false,
                'message' => ['Please Generate Library Card For This Student'],
            ]);
        }
    }
}
