<?php

namespace App\Http\Controllers\AcademicManager;

use DB;
use Hash;
use File;
use App\Models\Product;
use App\Models\BookDetails;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use App\Models\ProductImages;
use App\Exports\StudentsExport;
use App\Imports\ImportStudent;
use Yajra\DataTables\DataTables;
use Spatie\Permission\Models\Role;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;
use App\Models\Language;
use App\Models\Library\BookBulkUploadTemp;
use App\Models\LibrarySetting\Stream;
use App\Models\LibrarySetting\Places;
use App\Models\LibrarySetting\BookClass;
use App\Models\LibrarySetting\Translators;
use App\Models\LibrarySetting\LibrarianTags;
use App\Models\LibrarySetting\LibrarianGernes;
use App\Models\LibrarySetting\LibrarianAuthors;
use App\Models\LibrarySetting\LibrarianPublishers;
use App\Models\LibrarySetting\LibrarianBookLanguages;
use App\Models\ProductPrice;
use App\Models\VoucherMaster;
use App\Models\VoucherType;
use Illuminate\Support\Facades\Auth;

class BooksController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:books-list|books-create|books-edit|books-delete', ['only' => ['index', 'store']]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if (!$this->modulePermissionCheck('BOOKS')) {
            abort(404);
        }

        $data = Product::query()->latest();

        if ($request->ajax()) {
            $sort_by      = $request->get('sortby') ?? 10;
            $sort_type    = $request->get('sorttype');
            $search_query = $request->get('query');
            $search_type = $request->get('search_type');

            $data = $data->where('is_book', 1)
                ->when(!empty($search_query) && !empty($search_type),
                    function ($query) use ($search_query, $search_type) {
                        if ($search_type == 'short_name') {
                            $query->where('short_name', 'like', '%'.$search_query.'%');
                        } else if ($search_type == 'shortcode') {
                            $query->where('shortcode', 'like', '%'.$search_query.'%');
                        }
                    }
                )
                ->paginate($sort_by);

            return view('books.table', compact('data'));
        } else {
            $data = $data->where('is_book', 1)->paginate(10);

            return view('books.index', compact('data'));
        }
    }

    public function list(Request $request)
    {
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $categories  = LibrarianGernes::all();
        $authors     = LibrarianAuthors::all();
        $publishers  = LibrarianPublishers::all();
        $languages   = Language::all();
        $streams     = Stream::all();
        $bookClasses = BookClass::all();
        $tags        = LibrarianTags::all();
        $translators = Translators::all();

        return view('books.create', compact(
            'categories',
            'authors',
            'publishers',
            'languages',
            'streams',
            'bookClasses',
            'tags',
            'translators'
        ));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

        $rules = [
            'shortcode'     => 'nullable|unique:products,shortcode',
            'short_name'    => 'required',
            // 'category_id'   => 'required',
            // 'author_id'     => 'required',
            // 'publisher_id'  => 'required',
            // 'laguages_id'   => 'required',
            // 'stream_id'  => 'required',
            // 'book_class_id' => 'required',
            // 'book_tag_id'   => 'required',
            // 'translator_id' => 'required'
        ];

        $validator = \Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }

            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method',
            'author_id',
            'publisher_id',
            'laguages_id',
            'stream_id',
            'book_class_id',
            'book_url',
            'book_tag_id',
            'translator_id',
            'no_of_pages',
            'dimensions',
        ]);

        if ($request->hasFile('image')) {
            $path          = 'books/' . date('Y') . '/' . date('M');
            $response      = uploadImage($path, $request->image);

            if ($response['status'] == true) {
                $data['image'] = $response['file_name'];
            } else {
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => $response['message'],
                        'data'    => []
                    ]);
                }

                return redirect()->back()->with('error', $response['message']);
            }
        }
        if (substr($request->shortcode, 0, 4) == 'ISBN') {
            $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Book')->first();
            $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'ISBN')->first();

            # last voucher count for main invoice number
            $voucher_count      = Product::select('last_isbn_no_count')->orderBy('created_at', 'DESC')->first();
            $last_isbn_no_count = isset($voucher_count) && isset($voucher_count->last_isbn_no_count) ? $voucher_count->last_isbn_no_count + 1 : ($voucher_type->voucherSeries->start_from ?? 1);
            $data['last_isbn_no_count']       = $last_isbn_no_count;
        }
        $data['is_book']    = 1;
        $data['company_id'] = auth()->user()->company_id;
        $data['name']       = $request->short_name;
        $product            = Product::create($data);

        if ($product) {
            BookDetails::create([
                'book_id'       => $product->id,
                'author_id'     => $request->author_id,
                'publisher_id'  => $request->publisher_id,
                'book_url'      => $request->book_url,
                'laguages_id'   => $request->laguages_id,
                'stream_id'     => $request->stream_id,
                'book_class_id' => $request->book_class_id,
                'book_tag_id'   => $request->book_tag_id,
                'translator_id' => $request->translator_id,
                'no_of_pages'   => $request->no_of_pages,
                'dimensions'    => $request->dimensions,
            ]);
        }

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Book has been created successfully',
            ]);
        }
        return redirect()->back()
            ->with('success', 'Book has been created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $data = Product::find($id);

        return view('books.show', compact('data'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $categories  = LibrarianGernes::all();
        $authors     = LibrarianAuthors::all();
        $publishers  = LibrarianPublishers::all();
        $languages   = Language::all();
        $streams     = Stream::all();
        $bookClasses = BookClass::all();
        $tags        = LibrarianTags::all();
        $translators = Translators::all();
        $data        = Product::find($id);

        return view('books.edit', compact(
            'data',
            'categories',
            'authors',
            'publishers',
            'languages',
            'streams',
            'bookClasses',
            'tags',
            'translators'
        ));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $rules = [
            'shortcode'     => 'nullable|unique:products,shortcode,' . $id,
            'short_name'    => 'required',
            // 'category_id'   => 'required',
            // 'author_id'     => 'required',
            // 'publisher_id'  => 'required',
            // 'laguages_id'   => 'required',
            // 'book_class_id' => 'required',
            // 'book_tag_id'   => 'required',
            // 'translator_id' => 'required'
        ];

        $validator = \Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }

            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method',
            'author_id',
            'publisher_id',
            'laguages_id',
            'stream_id',
            'book_class_id',
            'book_url',
            'book_tag_id',
            'translator_id',
            'no_of_pages',
            'dimensions',
        ]);
        // dd($data);

        if ($request->hasFile('image')) {
            $path          = 'books/' . date('Y') . '/' . date('M');
            $response      = uploadImage($path, $request->image);

            if ($response['status'] == true) {
                $data['image'] = $response['file_name'];
            } else {
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => $response['message'],
                        'data'    => []
                    ]);
                }

                return redirect()->back()->with('error', $response['message']);
            }
        }

        $data['is_book'] = 1;
        $data['name']    = $request->short_name;
        $product         = Product::whereId($id)->update($data);

        if ($product) {
            BookDetails::where('book_id', $id)->update([
                // 'book_id'    => $product->id,
                'author_id'     => $request->author_id,
                'publisher_id'  => $request->publisher_id,
                'laguages_id'   => $request->laguages_id,
                'book_url'      => $request->book_url,
                'stream_id'     => $request->stream_id,
                'book_class_id' => $request->book_class_id,
                'book_tag_id'   => $request->book_tag_id,
                'translator_id' => $request->translator_id,
                'no_of_pages'   => $request->no_of_pages,
                'dimensions'    => $request->dimensions,
            ]);
        }

        if (!$product) {
            return redirect()->route('books.index')
                ->with('error', 'Book not found!');
        }

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Book has been updated successfully.',
            ]);
        }

        return redirect()->route('books.index')
            ->with('success', 'Book has been updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {
        $data = Product::find($request->id);

        if (isset($data->image) && $data->image != '') {
            deleteImage($data->image);
        }

        $data = $data->delete();
        BookDetails::where('book_id', $request->id)->delete();

        $Redirect = 'books';

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

    public function changeStatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('status' => $request->status);
            $Update = Product::where('id', '=', $request->id)->update($data);

            if ($Update) {
                return response()->json([
                    'success' => true,
                    'message' => ['Product status successfully change'],
                    'data' => [
                        'redirect' => '/books/',
                        'reload' => true,
                    ]
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => ['Error for change status'],
                    'data' => [
                        'redirect' => '',
                    ]
                ]);
            }
        }
    }

    public function bookImages($id)
    {
        $data = ProductImages::orderBy('id', 'DESC')
            ->where('product_id', $id)
            ->get();

        return view('book-images.table', compact('data'));
    }

    public function imageCreate()
    {
        return view('book-images.create');
    }

    public function storeImage(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'image_type' => 'required',
            'image_url'  => 'required'
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method',
            'image_url'
        ]);

        if ($request->hasFile('image_url')) {
            $path          = 'books/' . date('Y') . '/' . date('M');
            $response      = uploadImage($path, $request->image_url);

            if ($response['status'] == true) {
                $data['image_url'] = $response['file_name'];
            } else {
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => $response['message'],
                        'data'    => []
                    ]);
                }

                return redirect()->back()->with('error', $response['message']);
            }
        }

        $data['product_id'] = $request->book_id;
        $data               = ProductImages::create($data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Book Image has been created successfully',
            ]);
        }
        return redirect()->back()
            ->with('success', 'Book Image has been created successfully.');
    }

    public function imageStatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('status' => $request->status);
            $Update = ProductImages::where('id', '=', $request->id)->update($data);

            if ($Update) {
                return response()->json([
                    'success' => true,
                    'message' => ['Image status successfully change'],
                    'data' => [
                        'redirect' => '/books/',
                        'reload' => true,
                    ]
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => ['Error for change status'],
                    'data' => [
                        'redirect' => '',
                    ]
                ]);
            }
        }
    }

    public function editImage($id)
    {
        $data = ProductImages::find($id);

        return view('book-images.edit', compact('data'));
    }

    public function updateImage(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'image_type' => 'required',
            // 'image_url'  => 'required'
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method',
            'image_url'
        ]);

        if ($request->hasFile('image_url')) {
            $path          = 'books/' . date('Y') . '/' . date('M');
            $response      = uploadImage($path, $request->image_url);

            if ($response['status'] == true) {
                $data['image_url'] = $response['file_name'];
            } else {
                if ($request->ajax()) {
                    return response()->json([
                        'success' => false,
                        'message' => $response['message'],
                        'data'    => []
                    ]);
                }

                return redirect()->back()->with('error', $response['message']);
            }
        }

        $data = ProductImages::whereId($id)->update($data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Book image has been updated successfully',
            ]);
        }
        return redirect()->back()
            ->with('success', 'Book image has been updated successfully.');
    }

    public function imageDestroy(Request $request)
    {
        $data = ProductImages::find($request->id);

        if (isset($data->image_url) && $data->image_url != '') {
            deleteImage($data->image_url);
        }

        $data = $data->delete();
        $Redirect = 'books';

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

    public function importView(Request $request)
    {
        return view('books.import');
    }

    public function import(Request $request)
    {
        $extension = File::extension($request->file->getClientOriginalName());
        $extension = strtolower($extension);

        if ($extension == 'xlsx' || $extension == 'csv') {
            $file = $request->file('file')->getRealPath();
            $data = Excel::toArray(new ImportStudent, $request->file('file'));

            if (isset($data[0])) {
                $data = $data[0];
                unset($data[0]);
            }

            $collection = [];
            foreach ($data as $key => $record) {
                if ($record[0] == '' && $record[1] == '' && $record[2] == '' && $record[3] == '' && $record[4] == '' && $record[5] == '' && $record[6] == '' && $record[7] == '' && $record[8] == '' && $record[9] == '' && $record[10] == '') {
                    continue;
                }

                // if ($record[0] == '') {
                //     $message = 'ISBN No is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[1] == '') {
                //     $message = 'Book Title is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[2] == '') {
                //     $message = 'Category is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[3] == '') {
                //     $message = 'Author is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[4] == '') {
                //     $message = 'Stream is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[5] == '') {
                //     $message = 'Translator is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[6] == '') {
                //     $message = 'Publisher is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[7] == '') {
                //     $message = 'Language is required.';
                // } elseif ($record[9] == '') {
                //     $message = 'Class is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // } elseif ($record[10] == '') {
                //     $message = 'Tag is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // }
                // elseif ($record[13] == '') {
                //     $message = 'Item Min stock quantity is required.';

                //     return redirect()->back()
                //         ->with('error', $message);
                // }

                $category   = $record[2];
                $author     = $record[3];
                $stream     = $record[4];
                $translator = $record[5];
                $publisher  = $record[6];
                $language   = $record[7];
                $class      = $record[9];
                $tag        = $record[10];
                $streams    = array();
                // Need to dynamic this.
                // $record[4]  = 0;



                $collection[] = $record;
            }

            $details = [];
            foreach ($collection as $key => $book) {
                $details['isbn_no']             = $book[0];
                $details['user_id']             = Auth::user()->id;
                $details['book_title']          = $this->generateStringFormate($book[1]);
                $details['catgory_genres']      = $this->generateStringFormate($book[2]);
                $details['authors']             = $this->generateStringFormate($book[3]);
                $details['stream']              = $this->generateStringFormate($book[4]);
                $details['translator']          = $this->generateStringFormate($book[5]);
                $details['publishers']          = $this->generateStringFormate($book[6]);
                $details['laguages']            = $this->generateStringFormate($book[7]);
                $details['pages']               = $book[8];
                $details['book_class']          = $this->generateStringFormate($book[9]);
                $details['book_tag']            = $this->generateStringFormate($book[10]);
                $details['book_url']            = $book[11];
                $details['about_book']          = $this->generateStringFormate($book[12]);
                $details['qnt']                 = $book[13];
                $details['sale_price']          = $book[14];
                $details['mrp']                 = $book[15];
                $details['book_formate']        = $this->generateStringFormate($book[16]);
                $details['released_date']       = $book[17];
                $details['edition']             = $this->generateStringFormate($book[18]);
                $details['racks']               = $book[19];
                $tempBooks = BookBulkUploadTemp::where('isbn_no', $book[0])->first();
                if (empty($tempBooks)) {
                    BookBulkUploadTemp::insert($details);
                }
            }

            return response()->json([
                'success' => true,
                'message' => 'Books are imported successfully',
                'data' => [
                    'redirect' => '/book-bulk-list',
                    'reload' => false,
                ]
            ]);
        }
    }



    public function genere()
    {
        return view('books.genre');
    }

    public function author()
    {
        return view('books.author');
    }

    public function publisher()
    {
        $places = Places::all();

        return view('books.publisher', compact('places'));
    }

    public function language()
    {
        return view('books.language');
    }

    public function stream()
    {
        return view('books.stream');
    }
    public function genearte_isbn()
    {
        $voucher_master = VoucherMaster::with('voucherSeries')->where('voucher_code', 'Book')->first();
        $voucher_type   = VoucherType::with('voucherSeries')->where('code', 'ISBN')->first();

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

        $isbn_no = $this->generateCode(
            $last_isbn_no_count,
            ($voucher_type->voucherSeries->prefix ?? 'IS'),
            ($voucher_type->voucherSeries->postfix ?? ''),
            ($voucher_type->voucherSeries->separator ?? '-'),
            ($voucher_type->voucherSeries->length ?? 5)
        );

        echo $isbn_no;
    }
}
