<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\TourGuide;
use App\Models\Region;
use App\Models\OtherLanguage;
use App\Models\User;
use App\Models\TourGuideHistory;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
// use App\Helpers\Helper;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContractMail;
use App\Jobs\SendScheduledMail;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Mail\NewPasswordMail;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Services\BreadcrumbService;

class TourGuideController extends Controller
{
    public $breadcrumbs;

    public function __construct(BreadcrumbService $breadcrumbs)
    {
        $this->breadcrumbs = $breadcrumbs;
    }
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $breadcrumbService = $this->breadcrumbs;
        $breadcrumbService->add(__('common.tour_guides'), route('admin.tour-guides.index'));
        $breadcrumbs = $breadcrumbService->get();
        $perPage = $request->input('perPage', 5);
        $tour_guides = TourGuide::with(['region', 'prefecture', 'city'])->orderBy('created_at', 'desc')->paginate($perPage);
        $regions = Region::all();
        return view('admin.tour_guide.index', compact('tour_guides', 'regions', 'breadcrumbs', 'perPage'));
    }

    public function search(Request $request)
    {
        $query = TourGuide::with(['region', 'prefecture', 'city'])->select(
            'id',
            'status',
            'first_name',
            'last_name',
            'email',
            'phone',
            'region_id',
            'prefecture_id',
            'city_id',
            'position'
        );

        if ($request->filled('status') && $request->status !== 'All') {
            $query->where('status', $request->status);
        }

        if ($request->filled('region')) {
            $query->where('region_id', $request->region);
        }

        if ($request->filled('prefecture')) {
            $query->where('prefecture_id', $request->prefecture);
        }

        if ($request->filled('city')) {
            $query->where('city_id', $request->city);
        }

        if ($request->filled('name')) {
            $query->where(function ($q) use ($request) {
                $q->where('first_name', 'like', "%{$request->name}%")
                ->orWhere('last_name', 'like', "%{$request->name}%");
            });
        }

        if ($request->filled('position') && $request->position !== 'All') {
            $query->where('position', $request->position);
        }

        // if ($request->filled('invoice')) {
        //     $query->where('invoice_registration', $request->invoice === 'registered');
        // }

        return response()->json($query->get());
    }


    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        $tourGuide = TourGuide::with(['region', 'prefecture', 'city', 'otherLanguages'])->findOrFail($id);
        $other_languages = OtherLanguage::all();
        $managers = User::role('manager')->get();
        return view('admin.tour_guide.show', compact('tourGuide', 'other_languages', 'managers'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        $guide = TourGuide::with('otherLanguages')->findOrFail($id);
        $other_languages = OtherLanguage::orderBy('name', 'asc')->get();
        $managers = User::role('manager')->get();
        $regions = Region::all();
        return view('admin.tour_guide.edit', compact('guide', 'other_languages', 'managers', 'regions'));
    }

    /**
     * Update the specified resource in storage.
     */
        public function update(Request $request, $id)
        {
            $request->merge([
                'type_of_tours' => is_array($request->type_of_tours) ? $request->type_of_tours : explode(',', $request->type_of_tours),
            ]);
            $validator = \Validator::make($request->all(), [
                'status' => 'nullable|integer',
                'position' => 'required|string',
                'first_name' => 'required|string|max:255',
                'last_name' => 'nullable|string|max:255',
                'japanese_name' => 'nullable|string|max:255',
                'gender' => 'nullable|string',
                'email' => "required|email",
                'phone' => 'required|string|max:20',
                'region_id' => 'nullable|exists:regions,id',
                'prefecture_id' => 'nullable|exists:prefectures,id',
                'city_id' => 'nullable|exists:cities,id',
                'station' => 'nullable|string|max:255',
                'dob' => 'nullable|date',
                'work_area' => 'nullable|string',
                'address' => 'nullable|string',
                'lat_long' => 'nullable|string',
                'interpreter_license' => 'required|string',
                'license_number' => 'nullable|string|max:50',
                'certifications' => 'nullable|string',
                'private_vehicle' => 'nullable|string',
                'car_type' => 'nullable|string',
                'capacity' => 'nullable|integer',
                'invoice_registration' => 'nullable|string',
                'invoice_registration_number' => 'nullable|string',
                'bank_information' => 'nullable|string',
                'number_of_tours' => 'required|string',
                'years_of_experience' => 'required|string',
                'english_fluency' => 'required|integer|min:1|max:5',
                'type_of_tours' => 'nullable|array',
                'experience_area' => 'nullable|string',
                'availability' => 'required|string',
                'notes' => 'nullable|string',
                'other_languages' => 'nullable|array',
                'referred_person' => 'nullable|string',
                'interviewed_by' => 'nullable|string',
                'interview_date' => 'nullable|date',
                'interiewer_observations' => 'nullable|string',
                'english_fluency_rating' => 'nullable|string',
                'communication_preferred' => 'nullable|string',
                'recording_of_interview' => 'nullable|string',
                'starting_rate' => 'nullable|integer',
                'guide_fee' => 'nullable|json',
                'important_notes' => 'nullable|json',
                'comment' => 'nullable|string',
                'contract' => 'nullable|file|mimes:pdf,doc,docx',
                'sign_date' => 'nullable|date',
            ]);
            if ($validator->fails()) {
                return redirect()->back()->withErrors($validator)->withInput();
            }
            $tourGuide = TourGuide::findOrFail($id);

            if ($request->hasFile('contract')) {
                if ($tourGuide->contract) {
                    Storage::disk('public')->delete($tourGuide->contract);
                }
                $file = $request->file('contract');
                $filename = time() . '_' . $file->getClientOriginalName();
                $filePath = $file->storeAs('contracts', $filename, 'public');
                $tourGuide->contract = $filePath;
            }

            $changes = [];
            $excludedFields = ['_token', '_method'];
            $oldValues = $tourGuide->toArray();
            foreach ($request->except($excludedFields) as $key => $newValue) {
                $oldValue = $oldValues[$key] ?? null;

                if (is_string($oldValue) && isJson($oldValue)) {
                    $oldValue = json_decode($oldValue, true);
                }
                if (is_string($newValue) && isJson($newValue)) {
                    $newValue = json_decode($newValue, true);
                }

                if ($key === 'sign_date') {
                    $oldValue = $oldValue ? \Carbon\Carbon::parse($oldValue)->format('Y-m-d H:i:s') : null;
                    $newValue = $newValue ? \Carbon\Carbon::parse($newValue)->format('Y-m-d H:i:s') : null;
                }

                if ($oldValue != $newValue) {
                    $changes[] = [
                        'tour_guide_id' => $tourGuide->id,
                        'field_name' => $key,
                        'old_value' => is_array($oldValue) ? json_encode($oldValue) : $oldValue,
                        'new_value' => is_array($newValue) ? json_encode($newValue) : $newValue,
                        'changed_by' => auth()->id(),
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                }
            }

            $tourGuide->update([
                'status' => $request->status,
                'position' => $request->position,
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'japanese_name' => $request->japanese_name,
                'gender' => $request->gender,
                'email' => $request->email,
                'phone' => $request->phone,
                'region_id' => $request->region_id,
                'prefecture_id' => $request->prefecture_id,
                'city_id' => $request->city_id,
                'station' => $request->station,
                'dob' => $request->dob,
                'work_area' => $request->work_area,
                'address' => $request->address,
                'lat_long' => $request->lat_long,
                'interpreter_license' => $request->interpreter_license,
                'license_number' => $request->license_number,
                'certifications' => $request->certifications,
                'private_vehicle' => $request->private_vehicle,
                'car_type' => $request->car_type,
                'capacity' => $request->capacity,
                'invoice_registration' => $request->invoice_registration,
                'invoice_registration_number' => $request->invoice_registration_number,
                'bank_information' => $request->bank_information,
                'number_of_tours' => $request->number_of_tours,
                'years_of_experience' => $request->years_of_experience,
                'english_fluency' => $request->english_fluency,
                'type_of_tours' => json_encode($request->type_of_tours),
                'experience_area' => $request->experience_area,
                'availability' => $request->availability,
                'notes' => $request->notes,
                'other_languages' => json_encode($request->other_languages),
                'referred_person' => $request->referred_person,
                'interviewed_by' => $request->interviewed_by,
                'interview_date' => $request->interview_date,
                'interiewer_observations' => $request->interiewer_observations,
                'english_fluency_rating' => $request->english_fluency_rating,
                'communication_preferred' => $request->communication_preferred,
                'recording_of_interview' => $request->recording_of_interview,
                'starting_rate' => $request->starting_rate,
                'guide_fee' => $request->guide_fee ? json_decode($request->guide_fee, true) : null,
                'important_notes' => $request->important_notes ? json_decode($request->important_notes, true) : null,
                'comment' => $request->comment,
                // 'line_user_id' => $request->line_user_id,
                'contract' => $tourGuide->contract,
                'sign_date' => $request->sign_date,
            ]);

            // Maintain History
            if (!empty($changes)) {
                TourGuideHistory::insert($changes);
            }
            return back()->with('success', 'Tour Guide updated successfully!');
        }

    public function switchToInterviewed($id){
        $tourGuide = TourGuide::findOrFail($id);

        if (is_null($tourGuide->interviewed_by) || is_null($tourGuide->interview_date)) {
            return redirect()->back()->with('error', 'Interviewed first name and date are required');
        }
        $tourGuide->status = 3;
        $tourGuide->save();

        return redirect()->route('admin.tour_guides.index')->with('success', 'Updated successfully!');
    }

    public function makeActiveUser($id){
        $tourGuide = TourGuide::findOrFail($id);

        $tourGuide->status = 1;
        $tourGuide->save();

        return redirect()->route('admin.tour-guides.index')->with('success', 'Updated successfully!');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        $tourGuide = TourGuide::findOrFail($id);
        $tourGuide->delete(); // Soft delete
        return redirect()->route('admin.tour-guides.index')->with('success', 'Tour Guide soft deleted successfully.');
    }

    public function declineTourGuide($id){
        $tourGuide = TourGuide::findOrFail($id);

        $tourGuide->status = 4;
        $tourGuide->save();

        return redirect()->route('admin.tour-guides.index')->with('success', 'Updated successfully!');
    }

    public function rejectTourGuide($id){
        $tourGuide = TourGuide::findOrFail($id);

        $tourGuide->status = 5;
        $tourGuide->save();

        return redirect()->route('admin.tour-guides.index')->with('success', 'Updated successfully!');
    }

    public function sendContractMail(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'subject' => 'required|string',
            'body' => 'required|string',
            'title' => 'required|string',
        ]);

        $pdf = PDF::loadHTML($request->pdf);
        $pdfPath = 'contracts/' . time() . '_contract.pdf';

        Storage::disk('public')->put($pdfPath, $pdf->output());
        if ($request->is_scheduled) {
            SendScheduledMail::dispatch($request->email, $request->subject, $request->body, $request->title, $pdfPath)
                ->delay(now()->addMinutes(30));
            return response()->json(['message' => 'Contract email is scheduled.']);
        }
        Mail::to($request->email)->send(new ContractMail(
            $request->subject,
            $request->body,
            $request->title,
            $pdfPath
        ));

        return response()->json(['message' => 'Contract email sent successfully.']);
    }

    public function loginWithoutPassword(Request $request)
    {
        $user = User::where('email', $request->email)->first();

        if ($user) {
            Auth::login($user);
            return redirect()->route('admin.dashboard');
        }

        return redirect()->back()->with('error', 'User not found');
    }

    function sendResetPassword(Request $request)
    {
        $user = User::where('email', $request->email)->first();
        if (!$user) {
            return back()->with('error', 'User not found.');
        }
        $newPassword = Str::random(8);
        $user->password = Hash::make($newPassword);
        $user->save();

        Mail::to($user->email)->send(new NewPasswordMail($user, $newPassword));
        return redirect()->route('admin.tour-guides.index')->with('success', 'New password has been sent to the user\'s email!');
    }
}
