<?php

namespace Modules\JobPost\Http\Controllers\Buyer;

use App\Models\User;
use App\Models\Order;
use Auth, Image, File, Str;

use Illuminate\Http\Request;
use App\Models\JobRequestFile;
use Modules\City\Entities\City;
use Illuminate\Routing\Controller;

use Modules\JobPost\Entities\JobPost;
use Modules\Wallet\App\Models\Wallet;
use Modules\Category\Entities\Category;

use Modules\JobPost\Entities\JobRequest;
use Modules\Language\App\Models\Language;
use Illuminate\Contracts\Support\Renderable;
use Modules\Refund\App\Models\RefundRequest;
use Modules\JobPost\App\Models\JobPostMessage;
use Modules\JobPost\Entities\JobPostTranslation;
use Modules\JobPost\Http\Requests\JobPostRequest;
use Modules\JobPost\App\Models\JobPostMessagesDocument;

class JobPostController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index()
    {
        $user = Auth::guard('web')->user();

        $job_posts = JobPost::with('translate', 'category')->where('user_id', $user->id)->latest()->get();

        $awaiting_job_posts = JobPost::with('translate', 'category')->where('user_id', $user->id)->where('approved_by_admin', 'pending')->latest()->get();

        $active_job_posts = JobPost::with('translate', 'category')->where('user_id', $user->id)->where('approved_by_admin', 'approved')->latest()->get();

        $hired_job_posts = JobPost::with('translate', 'category')->where('user_id', $user->id)->where('approved_by_admin', 'approved')->whereHas('job_applications', function ($query) {
            $query->where('status', 'approved');
        })->latest()->get();

        return view('jobpost::buyer.index', compact('job_posts', 'awaiting_job_posts', 'active_job_posts', 'hired_job_posts'));
    }


    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create(Request $request)
    {

        $categories = Category::with('translate')->where('status', 'enable')->get();

        $cities = City::with('translate')->get();

        return view('jobpost::buyer.create', compact('categories', 'cities'));
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(JobPostRequest $request)
    {
        $job_post = new JobPost();

        if ($request->thumb_image) {
            $file_path = uploadPublicFile($request->thumb_image, 'uploads/custom-images');
            $job_post->thumb_image = $file_path;
        }

        $job_post->user_id = $request->user_id;
        $job_post->category_id = $request->category_id;
        $job_post->city_id = $request->city_id;
        $job_post->slug = $request->slug;
        $job_post->regular_price = $request->regular_price;
        $job_post->job_type = $request->job_type;
        $job_post->status = 'enable';
        $job_post->save();

        $languages = Language::all();
        foreach ($languages as $language) {
            $jobpost_translate = new JobPostTranslation();
            $jobpost_translate->lang_code = $language->lang_code;
            $jobpost_translate->job_post_id = $job_post->id;
            $jobpost_translate->title = $request->title;
            $jobpost_translate->description = $request->description;
            $jobpost_translate->save();
        }


        $notify_message = trans('translate.Created Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->route('buyer.jobpost.edit', ['jobpost' => $job_post->id, 'lang_code' => admin_lang()])->with($notify_message);
    }


    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit(Request $request, $id)
    {

        $job_post = JobPost::findOrFail($id);
        $job_post_translate = JobPostTranslation::where(['job_post_id' => $id, 'lang_code' => $request->lang_code])->first();

        $categories = Category::with('translate')->where('status', 'enable')->get();

        $cities = City::with('translate')->get();

        return view('jobpost::buyer.edit', compact('categories', 'cities', 'job_post', 'job_post_translate'));
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(JobPostRequest $request, $id)
    {
        $job_post = JobPost::findOrFail($id);

        if ($request->lang_code == admin_lang()) {

            if ($request->thumb_image) {
                $file_path = uploadPublicFile($request->thumb_image, 'uploads/custom-images', $job_post->thumb_image);
                $job_post->thumb_image = $file_path;
            }

            $job_post->category_id = $request->category_id;
            $job_post->city_id = $request->city_id;
            $job_post->slug = $request->slug;
            $job_post->regular_price = $request->regular_price;
            $job_post->job_type = $request->job_type;
            $job_post->status = 'enable';
            $job_post->save();
        }

        $jobpost_translate = JobPostTranslation::findOrFail($request->translate_id);
        $jobpost_translate->title = $request->title;
        $jobpost_translate->description = $request->description;
        $jobpost_translate->save();

        $notify_message = trans('translate.Updated Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->back()->with($notify_message);
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy($id)
    {
        $job_post = JobPost::findOrFail($id);
        $old_image = $job_post->thumb_image;

        deleteFile($old_image);

        JobPostTranslation::where('job_post_id', $id)->delete();
        JobRequest::where('job_post_id', $id)->delete();

        $job_post->delete();

        $notify_message =  trans('translate.Delete Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->route('buyer.jobpost.index')->with($notify_message);
    }

    public function assign_language($lang_code)
    {
        $jobpost_translates = JobPostTranslation::where('lang_code', admin_lang())->get();
        foreach ($jobpost_translates as $jobpost_translate) {
            $translate = new JobPostTranslation();
            $translate->job_post_id = $jobpost_translate->job_post_id;
            $translate->lang_code = $lang_code;
            $translate->title = $jobpost_translate->title;
            $translate->description = $jobpost_translate->description;
            $translate->save();
        }
    }

    public function jobpost_approval($id)
    {

        $job_post = JobPost::findOrFail($id);
        $job_post->approved_by_admin = 'approved';
        $job_post->status = 'enable';
        $job_post->save();

        $notify_message =  trans('translate.Apporval Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->back()->with($notify_message);
    }

    public function job_post_applicants($id)
    {

        $job_post = JobPost::findOrFail($id);

        $job_requests = JobRequest::with('seller')->where('job_post_id', $id)->latest()->get();

        return view('jobpost::buyer.job_applicants', ['job_requests' => $job_requests]);
    }

    public function job_application_approval($id)
    {
        $job_request = JobRequest::findOrFail($id);

        $job = JobPost::where('id', $job_request->job_post_id)->first();

        $buyer = $job_request->user_id;


        if (!checkModule('Wallet')) {
            $notify_message = trans('translate.Wallet module is not enabled, please contact with admin');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->back()->with($notify_message);
        }

        $buyer = User::find($buyer);

        $my_wallet = Wallet::where('buyer_id', $buyer->id)->first();

        $orders_by_wallet = Order::where('buyer_id', $buyer->id)->where('payment_method', 'Wallet')->sum('total_amount');

        $jobs_by_wallet = JobRequest::with('job_post:id,regular_price')
            ->where('user_id', $buyer->id)
            ->where('payment_status', 1)
            ->get();

        $job_post_paid_amount = $jobs_by_wallet->sum(function ($job) {
            return (float) optional($job->job_post)->regular_price;
        });

        $orders_by_wallet = $orders_by_wallet + $job_post_paid_amount;

        $current_balance = $my_wallet->balance - $orders_by_wallet;

        if ($job->regular_price > $current_balance) {
            $notify_message = trans('Insufficient balance in your wallet, please add funds to your wallet');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->route('buyer.wallet.create')->with($notify_message);
        }

        $approval_check = JobRequest::where('job_post_id', $job_request->job_post_id)->where('status', 'approved')->count();

        if ($approval_check == 0) {
            $job_request = JobRequest::findOrFail($id);
            $job_request->status = 'approved';
            $job_request->payment_status = 1;
            $job_request->save();

            JobRequest::where('job_post_id', $job_request->job_post_id)->where('id', '!=', $id)->update(['status' => 'rejected']);

            $notify_message = trans('translate.Job assigned successfully');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
            return redirect()->back()->with($notify_message);
        } else {
            $notify_message = trans('translate.Job already has assigned, so you can not assign again');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->back()->with($notify_message);
        }
    }

    public function chact_msg_store(Request $request)
    {

        $buyer = Auth::guard('web')->user();

        $job_request = JobRequest::findOrFail($request->request_id);

        $message = new JobPostMessage();
        $message->buyer_id = $buyer->id;
        $message->seller_id = $request->seller_id;
        $message->message = $request->message;
        $message->seller_read_msg = 0;
        $message->buyer_read_msg = 1;
        $message->send_by = 'buyer';
        $message->job_request_id = $job_request->id;
        $message->save();

        if ($request->hasFile('documents')) {
            foreach ($request->documents as $index => $request_file) {

                $file_path = uploadPrivateFile($request_file, 'uploads/custom-images');

                $document = new JobPostMessagesDocument();
                $document->message_id = $message->id;
                $document->buyer_id =  $buyer->id;
                $document->file_type =  $request->file_type;
                $document->seller_id =   $request->seller_id;
                $document->file_name = $file_path;
                $document->save();
            }
        }

        $last_message = JobPostMessage::with('documents')->where('job_request_id', $job_request->id)->where('buyer_id', $buyer->id)->where('send_by', 'buyer')->latest()->first();

        $messages =  JobPostMessage::with('documents')->where('job_request_id', $job_request->id)->where(['buyer_id' => $buyer->id, 'seller_id' => $request->seller_id])->get();

        $job_post_submition_files = JobRequestFile::where('status', 1)->where('job_request_id', $job_request->id)->first();

        return redirect()->route('buyer.chat-job-post-applicants', ['id' => $job_request->id])->with([
            'buyer' => $buyer,
            'last_message' => $last_message,
            'messages' => $messages,
            'job_request' => $job_request,
            'job_post_submition_files' => $job_post_submition_files
        ]);
    }


    public function job_application_order_approved($id)
    {
        $job_request = JobRequest::findOrFail($id);
        $job_request->approved_status = 'approved';
        $job_request->save();

        $notify_message = trans('translate.Order Accepted Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->back()->with($notify_message);
    }

    public function job_application_order_cancel(Request $request, $id)
    {
        $job_request = JobRequest::findOrFail($id);

        $job = JobPost::findOrFail($job_request->job_post_id);

        if (!checkModule('Wallet') || !checkModule('Refund')) {
            $notify_message = trans('translate.Wallet and Refund module is not enabled, please contact with admin');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->back()->with($notify_message);
        }

        $is_exist = RefundRequest::where('refund_type', 'job')->where('job_request_id', $id)->first();
        if ($is_exist) {
            $notify_message = trans('translate.Refund request already send to admin');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->back()->with($notify_message);
        }

        $refund = new RefundRequest();
        $refund->buyer_id = $job_request->user_id;
        $refund->seller_id = $job_request->seller_id;
        $refund->refund_type = 'job';
        $refund->job_request_id = $id;
        $refund->refund_amount = $job->regular_price;
        $refund->note = $request->cancel_reason_buyer;
        $refund->save();

        $job_request->approved_status = 'cancel';
        $job_request->status = 'cancel';
        $job_request->cancel_reason_buyer = $request->cancel_reason_buyer;
        $job_request->save();


        $notify_message = trans('translate.Order Cancel Request Send Successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->back()->with($notify_message);
    }

    public function chat_job_post_applicants($id)
    {
        $buyer = Auth::guard('web')->user();

        if (!checkModule('LiveChat')) {
            $notify_message = trans('translate.Live Chat module is not enabled, please contact with admin');
            $notify_message = array('message' => $notify_message, 'alert-type' => 'error');
            return redirect()->back()->with($notify_message);
        }

        $job_request = JobRequest::where('user_id', $buyer->id)->findOrFail($id);

        $last_message = JobPostMessage::with('documents')->where('buyer_id', $buyer->id)->where('job_request_id', $job_request->id)->where('send_by', 'seller')->latest()->first();

        $messages = JobPostMessage::with('seller', 'documents')->where('job_request_id', $job_request->id)->where(['buyer_id' => $buyer->id, 'seller_id' => $job_request->seller_id])->get();

        $job_post_submition_files = JobRequestFile::where('status', 1)->where('job_request_id', $job_request->id)->first();

        return view('livechat::job_application.buyer.chat', [
            'buyer' => $buyer,
            'last_message' => $last_message,
            'messages' => $messages,
            'job_request' => $job_request,
            'job_post_submition_files' => $job_post_submition_files
        ]);
    }

    public function job_application_delete($id)
    {

        $job_request = JobRequest::findOrFail($id);
        $job_request->delete();

        $notify_message = trans('translate.Deleted successfully');
        $notify_message = array('message' => $notify_message, 'alert-type' => 'success');
        return redirect()->back()->with($notify_message);
    }
}
