<?php

namespace App\Http\Controllers;

use App\DataTables\ForecastDataTable;
use App\DataTables\IncomingForecastDataTable;
use App\DataTables\IncomingForecastNewDataTable;
use App\DataTables\PastForecastDataTable;
use App\Models\Forecast;
use App\Models\ForecastUpload;
use App\Models\Helpers\General;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Yajra\DataTables\DataTables;

class ForecastController extends Controller
{

    public function __construct()
    {
        return $this->middleware('auth');
    }


    public function import_forecast(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'bulk_upload' => 'required|mimes:xlsx',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator->errors());
        } else {
            try {
                $result = DB::transaction(function () use ($request) {
                    $user_id = auth()->user()->id ?? 'N/A';
                    $email = auth()->user()->email ?? 'Unknown';
                    $file_name = time() . '_' . $email;
                    $file_path = 'public/ForecastUploads/';

                    $request->bulk_upload->storeAs($file_path, $file_name . '.xlsx');
                    ForecastUpload::create([
                        'file_name' => $file_name,
                        'status' => 'not read',
                        'user_id' => $user_id
                    ]);
                    return 'success'; //, 'File has been save successfully');
                });
            } catch (\Throwable $th) {
                return 'failed';
            }
            if ($result == 'success') {
                return back()->with('success', 'Forecast data has been store successfully');
            } else {
                return back()->with('error', 'Failed to store forecast data');
            }
        }
    }

    public function incoming_forecast()
    {
        // return $dataTable->render('forecast.incoming');
        // return $model->newQuery()->where('schedule', '>=', now()->toDateString());
        if(request()->ajax()) {
        $data = Forecast::query();
           return DataTables::of($data)
                   ->addColumn('custom_column', function($row) {
                       // Custom column content here
                   })
                   ->addColumn('action', function($query) {
                    return '
                    <div class="dropdown">
                        <button class="btn dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
                            <i class="fas fa-cog" aria-hidden="true"></i>
                        </button>
                        <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                            <a class="dropdown-item" href="'.route('forecast.edit.page', $query->id).'">Edit</a>
                            <a class="dropdown-item" href="'.route('forecast.delete', $query->id).'" onclick="return confirm(\'Do you want to delete this forecast?\')">Delete</a>
                        </ul>
                    </div>';
                   })
                   ->rawColumns(['custom_column', 'action'])
                   ->make(true);
           }

           return view('forecast.incoming');
    }

    public function past_forecast()
    {
        // return $dataTable->render('forecast.past');
        if(request()->ajax()) {
         $data = Forecast::query()->where('schedule', '<', now()->toDateString());
        return DataTables::of($data)
                ->addColumn('custom_column', function($row) {
                    // Custom column content here
                })
                ->addColumn('action', function($row) {
                    $buttons = '<a href="#" class="btn btn-sm btn-primary">Edit</a>';
                    $buttons .= '<a href="#" class="btn btn-sm btn-danger">Delete</a>';
                    return $buttons;
                })
                ->rawColumns(['custom_column', 'action'])
                ->make(true);
        }

        return view('forecast.past');
    }

    public function showCreatePage()
    {
        return view('forecast.create');
    }

    public function createForecast(Request $request)
    {
        General::logError('CREATING FORECAST DATA', json_encode($request->all()), 'createForecast method in ForecastController');

        Session::put('title', $request->title);
        Session::put('banker', $request->banker);
        Session::put('two_sure', $request->two_sure);
        Session::put('three_direct', $request->three_direct);
        Session::put('permutations', $request->permutations);
        Session::put('schedule', $request->schedule);

        $validator = $request->validate([
            'title' => 'required|string',
            'banker' => 'nullable|string',
            'two_sure' => 'nullable|string',
            'three_direct' => 'nullable|string',
            'permutations' => 'nullable|string',
            'schedule' => 'required|date'
        ]);

        $schedule_check = Forecast::query()->where('schedule', $request->schedule)->first();

        if ($schedule_check == null) {
            //Checking errors in banker
            if ($request->banker !== null) {
                if (!General::is_a_number($request->banker)) {
                    return back()->with('error', 'Banker should be a single number between 0 and 90');
                }
            }

            //Checking errors in two sure
            if ($request->two_sure !== null) {
                $error_two_sure = General::check_two_sure($request->two_sure);
                if (count($error_two_sure) > 0) {
                    return back()->with('error', 'Two sure should be only 2 numbers where each number is between 0 and 90');
                }
            }

            //Checking errors in three direct
            if ($request->three_direct !== null) {
                $error_three_direct = General::check_three_direct($request->three_direct);
                if (count($error_three_direct) > 0) {
                    return back()->with('error', 'Three direct should be only 3 numbers where each number is between 0 and 90');
                }
            }

            //Checking errors in permutations
            if ($request->permutations !== null) {
                $error_permutations = General::check_permutations($request->permutations);
                if (count($error_permutations) > 0) {
                    return back()->with('error', 'Permutation should be 2 or more numbers where each number is between 0 and 90');
                }
            }
            if (
                $request->banker == null &&
                $request->two_sure == null &&
                $request->three_direct == null &&
                $request->permutations == null
            ) {
                return back()->with('error', 'All the lotto categories cannot be empty');
            } else {
                try {
                    $data['title'] = $request->title;
                    $data['banker'] = $request->banker;
                    $data['two_sure'] = $request->two_sure;
                    $data['three_direct'] = $request->three_direct;
                    $data['permutations'] = $request->permutations;
                    $data['schedule'] = $request->schedule;
                    $data['created_by'] = auth()->user()->email ?? 'N/A';

                    Forecast::create($data);

                    General::clear_lotto_session();

                    return redirect()->route('forecast.incoming')->with('success', 'Forecast has been created successfully');
                } catch (\Throwable $th) {
                    General::logError('FORECAST CREATION', $th->getMessage(), 'createForecast method in ForecastController');
                    return back()->with('error', 'Sorry, an error occurred');
                }
            }
        } else {
            return back()->with('error', 'An existing record is already scheduled for the selected date');
        }
    }

    public function delete_forecast($id)
    {
        try {
            $forecast = Forecast::find($id) ?? null;
            if ($forecast !== null) {
                $forecast->delete();
                return back()->with('success', 'Forecast deleted successfully');
            } else {
                General::logError('DELETING A FORECAST', 'Unknown reason', 'delete_forecast in ForecastController');
                return back()->with('error', 'Failed to delete this forecast');
            }
        } catch (\Throwable $th) {
            General::logError('DELETING A FORECAST', $th->getMessage(), 'delete_forecast in ForecastController');
            return back()->with('error', 'Sorry, we encoutered an error');
        }
    }

    public function edit_forecast_page($id)
    {
        $forecast = Forecast::find($id) ?? null;
        if ($forecast !== null) {
            return view('forecast.edit', compact('forecast'));
        } else {
            General::logError('GETTING FORECAST EDIT PAGE', 'Un-identified error', 'edit_forecast_page in ForecastController');
            return back()->with('error', 'This forecast does not seem to exist');
        }
    }

    public function edit_forecast(Request $request, $id)
    {
        General::logError('EDITING FORECAST DATA', json_encode($request->all()), 'createForecast method in ForecastController');

        $validator = $request->validate([
            'title' => 'required|string',
            'banker' => 'nullable|string',
            'two_sure' => 'nullable|string',
            'three_direct' => 'nullable|string',
            'permutations' => 'nullable|string',
            'schedule' => 'required'
        ]);

        $schedule_check = Forecast::query()->where('schedule', $request->schedule)->first();

        if ($schedule_check == null || ($schedule_check !== null && $schedule_check->id == $id)) {
            //Checking errors in banker
            if ($request->banker !== null) {
                if (!General::is_a_number($request->banker)) {
                    return back()->with('error', 'Banker should be a single number between 0 and 90');
                }
            }

            //Checking errors in two sure
            if ($request->two_sure !== null) {
                $error_two_sure = General::check_two_sure($request->two_sure);
                if (count($error_two_sure) > 0) {
                    return back()->with('error', 'Two sure should be only 2 numbers where each number is between 0 and 90');
                }
            }

            //Checking errors in three direct
            if ($request->three_direct !== null) {
                $error_three_direct = General::check_three_direct($request->three_direct);
                if (count($error_three_direct) > 0) {
                    return back()->with('error', 'Three direct should be only 3 numbers where each number is between 0 and 90');
                }
            }

            //Checking errors in permutations
            if ($request->permutations !== null) {
                $error_permutations = General::check_permutations($request->permutations);
                if (count($error_permutations) > 0) {
                    return back()->with('error', 'Permutation should be 2 or more numbers where each number is between 0 and 90');
                }
            }
            if (
                $request->banker == null &&
                $request->two_sure == null &&
                $request->three_direct == null &&
                $request->permutations == null
            ) {
                return back()->with('error', 'All the lotto categories cannot be empty');
            } else {
                try {
                    $data['title'] = $request->title;
                    $data['banker'] = $request->banker;
                    $data['two_sure'] = $request->two_sure;
                    $data['three_direct'] = $request->three_direct;
                    $data['permutations'] = $request->permutations;
                    $data['schedule'] = $request->schedule;
                    $data['created_by'] = auth()->user()->email ?? 'N/A';

                    $forecast = Forecast::find($id) ?? null;
                    if ($forecast !== null) {
                        $forecast->update($data);
                        General::clear_lotto_session();
                        return back()->with('success', 'Forecast has been edited successfully');
                    } else {
                        return back()->with('error', 'Error occurred');
                    }
                } catch (\Throwable $th) {
                    General::logError('EDITING FORECAST', $th->getMessage(), 'edit_forecast method in ForecastController');
                    return back()->with('error', 'Sorry, an error occurred');
                }
            }
        } else {
            return back()->with('error', 'An existing record is already scheduled for the selected date');
        }
    }

    //NEW DIRECTIVE BEGINS HERE

    public function createForecast_new_directive(Request $request)
    {
        Session::put('lotto_title', $request->title);
        Session::put('lotto_message', $request->message);
        Session::put('lotto_schedule', $request->schedule);

        $request->validate([
            'title' => 'required',
            'message' => 'required'
        ]);

        $schedule_check = Forecast::query()->where('schedule', $request->schedule)->first();

        // $data = General::check_lotto_message($request->message);
        // if ($data['banker'] == '' && $data['two_sure'] == '' &&
        //  $data['three_direct'] == '' && $data['permutations'] == '') {
        //     return back()->with('error', 'No lotto category was found. Eg: Banker, Two Sure, Three Direct or Permutations');
        // }
        // //Checking banker
        // if ($data['banker'] !== '') {
        //     if (! General::check_banker($data['banker'])) {
        //         return back()->with('error', 'Banker should be only one number from 1 to 90');
        //     }
        // }

        // //Checking two sure
        // if ($data['two_sure'] !== '') {
        //     if (count(General::check_two_sure($data['two_sure'])) > 0) {
        //         return back()->with('error', 'Two Sure should be two numbers from 1 to 90');
        //     }
        // }

        // //Checking three direct
        // if ($data['three_direct'] !== '') {
        //     if (count(General::check_three_direct($data['three_direct'])) > 0) {
        //         return back()->with('error', 'Three direct should be three numbers from 1 to 90');
        //     }
        // }

        // //Checking permutations
        // if ($data['permutations'] !== '') {
        //     if (count(General::check_permutations($data['permutations'])) > 0) {
        //         return back()->with('error', 'Permutations should be three numbers or more from 1 to 90');
        //     }
        // }

        try {
            if ($schedule_check == null) {
                Forecast::create($request->all());
            Session::forget('lotto_title');
            Session::forget('lotto_message');
            Session::forget('lotto_schedule');
            return redirect()->route('forecast.incoming')->with('success', 'Forecast has been created successfully');
            } else {
                return back()->with('error', 'An existing forecast is already scheduled for the selected date');
            }

        } catch (\Throwable $th) {
            General::logError('TRYING TO CREATE A FORECAST', $th->getMessage(), 'createForecast_new_directive in the ForecastController');
            return back()->with('error', 'There was an error. Please forward to Administrator');
        }
    }

    public function editForecast_new_directive(Request $request, $id)
    {
        $request->validate([
            'title' => 'required',
            'message' => 'required',
            'schedule' => 'required|date'
        ]);

        $schedule_check = Forecast::query()->where('schedule', $request->schedule)->first();

        try {
            if ($schedule_check == null || $schedule_check->id == $id) {
                $forecast = Forecast::find($id) ?? null;
            if ($forecast !== null) {
                $forecast->update($request->all());
                return redirect()->route('forecast.incoming')->with('success', 'Forecast has been updated successfully');
            } else {
                return back()->with('error', 'This forecast does not seem to exist');
            }
            } else {
                return back()->with('error', 'An existing forecast is already scheduled for the selected date');
            }

        } catch (\Throwable $th) {
            General::logError('TRYING TO EDIT A FORECAST', $th->getMessage(), 'createForecast_new_directive in the ForecastController');
            return back()->with('error', 'There was an error. Please forward to Administrator');
        }
    }
}
