<?php

namespace App\Http\Controllers\TestManager;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\TestItemNormalRange;
use App\Models\TestItem;
use App\Models\SpecialCase;
use App\Models\Gender;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\ImportTestItemRange;
use App\Exports\ExportTestItemRangeFormat;
use Session;

class TestItemNormalRangesController extends Controller
{
    function __construct()
    {
        $this->middleware('permission:test-item-normal-range-list', ['only' => ['index']]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, $id)
    {
        if($id){

            $test_name = TestItem::select('name')->find($id);

            $item_id = $id;

            $data = TestItemNormalRange::select([
                        'test_item_normal_ranges.id',
                        'test_item_normal_ranges.test_item_id',
                        'test_item_normal_ranges.from_age',
                        'test_item_normal_ranges.to_age',
                        'test_item_normal_ranges.age_factor',
                        'test_item_normal_ranges.low_value',
                        'test_item_normal_ranges.high_value',
                        'test_item_normal_ranges.report_output',
                        'test_item_normal_ranges.status',
                        'special_cases.name as special_case',
                        'genders.name as gender',
                    ])
                    ->leftjoin('special_cases', 'special_cases.id', 'test_item_normal_ranges.special_case_id')
                    ->leftjoin('genders', 'genders.id', 'test_item_normal_ranges.gender_id')
                    ->where('test_item_id', $id)
                    ->orderBy('genders.name', 'ASC');

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

                $data = $data->when(!empty($search_query), function ($query) use ($search_query) {
                    return $query->where('test_item_normal_ranges.from_age', 'like', '%'.$search_query.'%')
                        ->orWhere('test_item_normal_ranges.to_age', 'like', '%'.$search_query.'%')
                        ->orWhere('test_item_normal_ranges.age_factor', 'like', '%'.$search_query.'%')
                        ->orWhere('test_item_normal_ranges.low_value', 'like', '%'.$search_query.'%')
                        ->orWhere('test_item_normal_ranges.high_value', 'like', '%'.$search_query.'%')
                        ->orWhere('test_item_normal_ranges.report_output', 'like', '%'.$search_query.'%')
                        ->orWhere('special_cases.name', 'like', '%'.$search_query.'%')
                        ->orWhere('genders.name', 'like', '%'.$search_query.'%');
                })
                ->where('test_item_id', $id)
                ->paginate($sort_by);

                return view('test-item-normal-ranges.table', compact('data', 'item_id'));
            }
            else
            {
                $data = $data->paginate(10);

                return view('test-item-normal-ranges.index', compact('data', 'item_id', 'test_name'));
            }
        }else{
            return abort(404);
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create($id)
    {
        $item_id = $id;

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

        $genders = Gender::select(['id', 'name'])->get();

        return view('test-item-normal-ranges.create', compact('item_id', 'special_cases', 'genders'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request, $id)
    {
        if(!$id){
            return abort(404);
        }

        $item_id = $id;

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

        if ($request->gender_id == 'All') {

            $genders = Gender::select('id')->get();

            foreach ($genders as $gender_id) {

                if ($request->age_factor == 'Years') {
                    $data['from_age'] = $from_age = yearsToHours($request->from_age);
                    $data['to_age']   = $to_age   = yearsToHours($request->to_age);
                } else if ($request->age_factor == 'Days') {
                    $data['from_age'] = $from_age = daysToHours($request->from_age);
                    $data['to_age']   = $to_age   = daysToHours($request->to_age);
                } else {
                    $data['from_age'] = $from_age = $request->from_age;
                    $data['to_age']   = $to_age   = $request->to_age;
                }

                $existingRange = TestItemNormalRange::where(['gender_id' => $gender_id->id, 'test_item_id' => $item_id])
                ->where(function ($query) use ($from_age, $to_age) {
                    $query->where('to_age', '>=', $from_age)
                          ->where('from_age', '<=', $to_age);
                })
                ->first();

                if ($existingRange) {
                    return response()->json(['success' => false, 'message' => 'Range already exists for this age.']);
                }

                $data['gender_id']    = $gender_id->id;
                $data['test_item_id'] = $item_id;

                $TestItemRange = TestItemNormalRange::create($data);
            }
        } else {

            if ($request->age_factor == 'Years') {
                $data['from_age'] = $from_age = yearsToHours($request->from_age);
                $data['to_age']   = $to_age   = yearsToHours($request->to_age);
            } else if ($request->age_factor == 'Days') {
                $data['from_age'] = $from_age = daysToHours($request->from_age);
                $data['to_age']   = $to_age   = daysToHours($request->to_age);
            } else {
                $data['from_age'] = $from_age = $request->from_age;
                $data['to_age']   = $to_age   = $request->to_age;
            }

            $data['test_item_id'] = $item_id;

            $existingRange = TestItemNormalRange::where(['gender_id' => $request->gender_id, 'test_item_id' => $item_id])
            ->where(function ($query) use ($from_age, $to_age) {
                $query->where('to_age', '>=', $from_age)
                    ->where('from_age', '<=', $to_age);
            })
            ->first();

            if ($existingRange) {
                return response()->json(['success' => false, 'message' => 'Range already exists for this age.']);
            }

            $TestItemRange = TestItemNormalRange::create($data);
        }

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Range created successfully',
                'data'    => $TestItemRange
            ]);
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $range = TestItemNormalRange::find($id);

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

        $genders = Gender::select(['id', 'name'])->get();

        return view('test-item-normal-ranges.edit', compact('range', 'special_cases', 'genders'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        if(!$id){
            return abort(404);
        }

        $item = TestItemNormalRange::select('test_item_id')->where('id', $id)->first();

        $item_id = $item->test_item_id;

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

        $range = TestItemNormalRange::find($id);

        if ($request->age_factor == 'Years') {
            $data['from_age'] = $from_age = yearsToHours($request->from_age);
            $data['to_age']   = $to_age   = yearsToHours($request->to_age);
        } else if ($request->age_factor == 'Days') {
            $data['from_age'] = $from_age = daysToHours($request->from_age);
            $data['to_age']   = $to_age   = daysToHours($request->to_age);
        } else {
            $data['from_age'] = $from_age = $request->from_age;
            $data['to_age']   = $to_age   = $request->to_age;
        }

        $existingRange = TestItemNormalRange::where(['gender_id' => $request->gender_id, 'test_item_id' => $item_id])
        ->whereNot('id', $id)
        ->where(function ($query) use ($from_age, $to_age) {
            $query->where('to_age', '>=', $from_age)
                  ->where('from_age', '<=', $to_age);
        })
        ->first();

        if ($existingRange) {
            return response()->json(['success' => false, 'message' => 'Range already exists for this age.']);
        }



        $TestItemRangeUpdate = $range->update($data);

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

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

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

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

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

    public function importCreate($id)
    {
        if ($id) {
            $item_id = $id;

            $item_name = TestItem::select('name')->where('id', $item_id)->first();

            return view('test-item-normal-ranges.import', compact('item_id', 'item_name'));
        }
    }

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

        Session::put('TestItemNormalRangesData', $test_item_normal_ranges_data);

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

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

            return view('test-item-normal-ranges.preview', compact('data'));

        } catch (\Exception $e) {

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

    public function importSessionDestroy(Request $request)
    {
        $test_item_normal_ranges_data = Session::get('TestItemNormalRangesData');

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

        Session::put('TestItemNormalRangesData', $test_item_normal_ranges_data);

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

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

        if ($data){
            $item_id = $id;

            foreach ($data as $row){

                $gender = Gender::select('id')->where('name', $row[0])->first();

                if ($gender) {
                    $gender_id = $gender->id;
                } else {
                    return redirect()->back()
                        ->with('error','Gender not found.');
                }

                $special_case = SpecialCase::select('id')->where('name', $row[7])->first();

                if ($special_case) {
                    $special_case_id = $special_case->id;
                } else {
                    return redirect()->back()
                        ->with('error','Special Case not found.');
                }

                $test_item_normal_ranges = ([
                    'test_item_id'    => $item_id,
                    'gender_id'       => $gender_id,
                    'special_case_id' => $special_case_id,
                    'from_age'        => $row[1],
                    'to_age'          => $row[2],
                    'age_factor'      => $row[3],
                    'low_value'       => $row[4],
                    'high_value'      => $row[5],
                    'report_output'   => $row[6],
                    'status'          => ($row[8] == 'Inactive') ? '0' : '1',
                ]);

                TestItemNormalRange::create($test_item_normal_ranges);
            }

            return redirect()->route('test-item-normal-ranges.index', $item_id)
                ->with('success','Test Item Normal Ranges uploaded successfully');
        }else{
            return redirect()->back()
                ->with('error','Empty file uploaded');
        }
    }

    public function exportFormat()
    {
        return Excel::download(new ExportTestItemRangeFormat, 'test-item-normal-range-format.xlsx');
    }
}
