<?php

namespace App\Http\Controllers\TestManager;

use App\Http\Controllers\Controller;
use App\Models\TestItem;
use App\Models\TestItemOption;
use App\Models\TestItemNormalRange;
use App\Models\TestPackage;
use App\Models\TestPackageGroup;
use App\Models\TestPackageNote;
use App\Models\TestPackageGroupNote;
use App\Models\TestPackageGroupTestItem;
use App\Models\Department;
use App\Models\TestMethod;
use App\Models\SampleType;
use App\Models\ProductTestPackage;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\ImportPackage;
use App\Exports\ExportPackageFormat;
use App\Models\Product;
use Session;

class TestPackagesController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:test-package-list', ['only' => ['index']]);
    }

    public function index(Request $request)
    {
        $departments = Department::where('status', '1')
                        ->get(['id', 'name']);
        $data = TestPackage::select([
                    'test_packages.id',
                    'test_packages.name',
                    'test_packages.short_name',
                    'test_packages.code',
                    'test_packages.priority',
                    'test_packages.report_delivery_tat',
                    'test_packages.pre_booking_required',
                    'test_packages.is_page_break',
                    'test_packages.show_in_report',
                    'test_packages.status',
                    'test_departments.name as department',
                    'sample_types.name as sample_type',
                ])
                ->orderBy('priority', 'asc')
                ->leftjoin('sample_types', 'sample_types.id', 'test_packages.sample_type_id')
                ->leftjoin('test_departments', 'test_departments.id', 'test_packages.department_id');

        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');
            $department_id = $request->get('department_id');

            $data = $data->when(!empty($department_id) && !empty($department_id),
                function ($query) use ($department_id) {
                    $query->where('test_packages.department_id', $department_id);
                }
            );

            $data = $data->when(!empty($search_query) && !empty($search_type),
                function ($query) use ($search_query, $search_type) {
                    if ($search_type == 'name') {
                        $query->where('test_packages.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'code') {
                        $query->where('test_packages.code', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'sample_type') {
                        $query->where('sample_types.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'short_name') {
                        $query->where('test_packages.short_name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'priority') {
                        $query->where('test_packages.priority', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'department') {
                        $query->where('test_departments.name', 'like', '%'.$search_query.'%');
                    }
                }
            )
            ->orderBy('priority', 'asc')
            ->paginate($sort_by);

            return view('test-packages.table', compact('data','sort_by'));
        }
        else
        {
            $data = $data->paginate(10);

            return view('test-packages.index', compact('data','departments'));
        }
    }

    public function create()
    {
        $departments = Department::select(['id', 'name'])
                ->where('status', '1')
                ->whereNull('deleted_at')
                ->get();
        $test_methods = TestMethod::select(['id', 'name'])
                ->where('status', '1')
                ->whereNull('deleted_at')
                ->get();

        $sample_types = SampleType::select(['id', 'name'])
                ->where('status', '1')
                ->whereNull('deleted_at')
                ->get();
        $priority = TestPackage::max('priority');
        $priority = $priority != '' ? $priority : 0;

        return view('test-packages.create', compact('departments', 'sample_types','priority','test_methods'));
    }

    public function store(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'name' => 'required|unique:test_packages,name,NULL,id,deleted_at,NULL',
        ]);

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

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

        // $latest_priority = TestPackage::max('priority');
        // $priority = ($latest_priority ?? 0) + 1;

        // $data['priority'] = $priority;

        if($request->pre_booking_required == 'on'){
            $data['pre_booking_required'] = 1;
        }else{
            $data['pre_booking_required'] = 0;
        }

        $package = TestPackage::create($data);

        // Create package group
        $package_group = [
            'test_package_id' => $package->id,
            'group_name'      => $package->name,
            'priority'        => 1,
        ];

        $group = TestPackageGroup::create($package_group);

        // Create group note
        $group_note = [
            'test_package_id'       => $package->id,
            'test_package_group_id' => $group->id,
        ];

        TestPackageGroupNote::create($group_note);

        // Create package note
        $package_note = [
            'test_package_id' => $package->id,
        ];

        TestPackageNote::create($package_note);

        return redirect()->route('test-package-groups.index', $group->test_package_id)
            ->with('success','Test Package created successfully');
    }

    public function edit($id)
    {
        $data = TestPackage::find($id);

        $departments = Department::select(['id', 'name'])
                ->where('status', '1')
                ->whereNull('deleted_at')
                ->get();

        $sample_types = SampleType::select(['id', 'name'])
                ->where('status', '1')
                ->whereNull('deleted_at')
                ->get();

        return view('test-packages.edit',compact('data', 'departments', 'sample_types'));
    }

    public function update(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'name' => 'required|unique:test_packages,name,'.$id.',id,deleted_at,NULL',
        ]);

        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'
        ]);

        if($request->pre_booking_required == 'on'){
            $data['pre_booking_required'] = 1;
        }else{
            $data['pre_booking_required'] = 0;
        }

        $package = TestPackage::find($id);

        if (!$package) {
            return redirect()->back()
                ->with('error','Test Package not found!');
        }

        $package->update($data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Test Package Updated successfully.',
                'data'    => $package
            ]);
        }
    }

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

            $Redirect = 'test-packages';

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

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

            $Redirect = 'test-packages';

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

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

            $Redirect = 'test-packages';

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

    public function destroy(Request $request)
    {
        $item = TestPackageGroupTestItem::select('test_item_id')->where('test_package_id', $request->id)->get();

        // DELETE OPTION AND RANGE
        TestItemOption::whereIn('test_item_id', $item)->delete();
        TestItemNormalRange::whereIn('test_item_id', $item)->delete();

        // DELETE TESTITEM
        TestItem::whereIn('id', $item)->delete();
        TestPackageGroupTestItem::where('test_package_id', $request->id)->delete();

        // DELETE PACKAGE_NOTE AND GROUP_NOTE
        TestPackageGroupNote::where('test_package_id', $request->id)->delete();
        TestPackageNote::where('test_package_id', $request->id)->delete();

        // DELETE PACKAGE AND GROUP
        TestPackageGroup::where('test_package_id', $request->id)->delete();
        TestPackage::find($request->id)->delete();

        $Redirect = 'test-packages';

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

    public function importCreate()
    {
       return view('test-packages.import');
    }

    public function importPreview(Request $request)
    {
        $package_data = [];

        Session::put('PackageData', $package_data);

        try {
            Excel::import(new ImportPackage, $request->file('packages'));

            $data = Session::get('PackageData');

            return view('test-packages.preview', compact('data'));

        } catch (\Exception $e) {

            return response()->json([
                'success' => false,
                'message' => [$e->getMessage()],
            ]);
        }
    }

    public function importSessionDestroy(Request $request)
    {
        $package_data = Session::get('PackageData');

        unset($package_data[$request->id]);

        Session::put('PackageData', $package_data);

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

    public function importStore(Request $request)
    {
        $data = Session::get('PackageData');

        if ($data) {

            foreach ($data as $row){

                $latest_priority = TestPackage::max('priority');
                $priority        = ($latest_priority ?? 0) + 1;

                $department = Department::select('id')->where('name', $row[1])->first();
                // create department if not exist
                if (!$department) {
                    $package_department = [
                        'name' => $row[1],
                    ];

                    $department = Department::create($package_department);
                }

                $sample = SampleType::select('id')->where('name', $row[2])->first();
                // create sample type if not exist
                if (!$sample) {
                    $package_sample = [
                        'name' => $row[2],
                    ];

                    $sample = SampleType::create($package_sample);
                }

                $packages = ([
                    'name'          => $row[0],
                    'department_id' => $department->id,
                    'department_id' => $sample->id,
                    'short_name'    => $row[3],
                    'code'          => $row[4],
                    'priority'      => $row[5] ?? $priority,
                    'is_page_break' => ($row[6] == 'Yes') ? '1' : '0',
                    'status'        => ($row[7] == 'Inactive') ? '0' : '1',
                ]);

                $exist_packages = TestPackage::where('name', $row[0])->exists();

                if (!$exist_packages){

                    $data = TestPackage::create($packages);

                    $package_id = $data->id;

                    // Create package note
                    $package_note = [
                        'test_package_id' => $package_id,
                    ];

                    TestPackageNote::create($package_note);

                    // Create group
                    $package_group = [
                        'test_package_id' => $package_id,
                        'group_name'      => $data->name,
                        'priority'        => 1,
                    ];

                    $group = TestPackageGroup::create($package_group);

                    // Create group note
                    $group_note = [
                        'test_package_id'       => $package_id,
                        'test_package_group_id' => $group->id,
                    ];

                    TestPackageGroupNote::create($group_note);
                }
            }

            return redirect()->route('test-packages.index')
                ->with('success','Packages uploaded successfully');
        } else {
           return redirect()->back()
                ->with('error','Empty file uploaded');
        }
    }

    public function exportFormat()
    {
        return Excel::download(new ExportPackageFormat, 'package-format.xlsx');
    }

    public function testPackageProducts($id)
    {
        $test_package_products = ProductTestPackage::select('product_test_packages.id','products.name','product_prices.sale_price')
            ->leftjoin('products','product_test_packages.product_id','products.id')
            ->leftjoin('product_prices','product_prices.product_id','products.id')
            ->where('product_test_packages.test_package_id', $id)
            ->get();

       return view('test-packages.products', compact('test_package_products','id'));
    }

    public function productLink(Request $request,$id){
        $test_package_products = ProductTestPackage::select('product_id')
            ->where('test_package_id', $id)
            ->get()
            ->pluck('product_id');

        $products = Product::select(['products.id','products.name'])
            ->leftjoin('business_divisions','business_divisions.id','products.business_division_id')
            ->whereIn('business_divisions.code',['PATHOLOGY','RADIOLOGY'])
            ->where('products.status',1)
            ->whereNotIn('products.id', $test_package_products)
            ->get();

        return view('test-packages.product-link-create',compact('products','id'));
    }

    public function getSelectedTestProducts(Request $request)
    {
        if (isset($request->id) && !empty($request->id)) {
            $test_products = Product::select(['id','name'])->whereIn('id', $request->id)->get();

            $sno = 1;
            $row = '';
            foreach($test_products as $product){

                $row .= '
                <tr>
                    <td>'. $sno++ .'</td>
                    <td>'. ucfirst($product->name) .'</td>
                    <td>
                        <a class="remove-btn itme_id btn-sm btn-danger" data-value="'. $product->id .'">
                        <i class="bi bi-trash-fill text-white"></i></a>
                    </td>
                </tr>';
            }

            return $row;
        }
    }
    public function testProductStore(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'test_id'   =>  '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());
        }

        foreach($request->test_product_id as $key => $value) {
            $data = [
                'test_package_id' => $request->test_id,
                'product_id'      => $value
            ];

            ProductTestPackage::updateOrCreate($data);
        }

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Test packages linked successfully',
            ]);
        }
        return redirect()->back()
            ->with('success','Test packages linked successfully');
    }

}
