<?php

namespace Modules\JobPost\Http\Controllers\API\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\Http\Requests\ApiJobPostRequest;
use Modules\JobPost\App\Models\JobPostMessagesDocument;

class JobPostController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index()
    {

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

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

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

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

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

        return response()->json([
            'job_posts' => $job_posts,
            'awaiting_job_posts' => $awaiting_job_posts,
            'active_job_posts' => $active_job_posts,
            'hired_job_posts' => $hired_job_posts,
        ]);
    }


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

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

        $cities = City::all();

        $job_types = array(
            'Hourly',
            'Daily',
            'Monthly',
            'Yearly'
        );

        return response()->json([
            'categories' => $categories,
            'cities' => $cities,
            'job_types' => $job_types,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(ApiJobPostRequest $request)
    {

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

        $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 = $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');

        return response()->json([
            'message' => $notify_message,
            'job_post' => $job_post,
        ]);
    }

    public function jobpost_thumbnail(Request $request)
    {
        $request->validate([
            'job_post_id' => 'required',
            'thumb_image' => 'required',
        ], [
            'job_post_id.required' => trans('Job id is required'),
            'thumb_image.required' => trans('translate.Image is required'),
        ]);

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

        $job_post = JobPost::where(['user_id' => $user->id, 'id' => $request->job_post_id])->first();

        if (!$job_post) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }


        if ($request->thumb_image) {
            $old_image = $job_post->thumb_image;
            $image_name = 'jobpost' . date('-Y-m-d-h-i-s-') . rand(999, 9999) . '.webp';
            $image_name = 'uploads/custom-images/' . $image_name;
            Image::make($request->thumb_image)
                ->encode('webp', 80)
                ->save(public_path() . '/' . $image_name);
            $job_post->thumb_image = $image_name;
            $job_post->save();

            if ($old_image) {
                if (File::exists(public_path() . '/' . $old_image)) unlink(public_path() . '/' . $old_image);
            }
        }


        $notify_message = trans('translate.Updated Successfully');

        return response()->json([
            'message' => $notify_message
        ]);
    }


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


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

        $job_post = JobPost::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_post) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

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

        $cities = City::all();

        $job_types = array(
            'Hourly',
            'Daily',
            'Monthly',
            'Yearly'
        );

        return response()->json([
            'categories' => $categories,
            'cities' => $cities,
            'job_types' => $job_types,
            'job_post' => $job_post,
            'job_post_translate' => $job_post_translate,
        ]);
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(ApiJobPostRequest $request, $id)
    {

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

        $job_post = JobPost::where(['user_id' => $user->id, 'id' => $id])->first();

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

        if (!$job_post) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

        $jobpost_translate = JobPostTranslation::where(['id' => $request->translate_id, 'job_post_id' => $id])->first();

        if (!$jobpost_translate) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

            $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->title = $request->title;
        $jobpost_translate->description = $request->description;
        $jobpost_translate->save();

        $notify_message = trans('translate.Updated Successfully');

        return response()->json([
            'message' => $notify_message
        ]);
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy($id)
    {
        $user = Auth::guard('api')->user();

        $job_post = JobPost::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_post) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

        return response()->json([
            'message' => $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 job_post_applicants($id)
    {

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

        $job_post = JobPost::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_post) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

        return response()->json([
            'job_requests' => $job_requests
        ]);
    }

    public function job_application_approval($id)
    {

        if (!checkModule('Wallet')) {
            $notify_message = trans('translate.Wallet module is not enabled, please contact with admin');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }

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

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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



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

        if ($approval_check == 0) {


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

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

            $jobs_by_wallet = JobRequest::with('job_post:id,regular_price')
                ->where('user_id', $user->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');
                return response()->json([
                    'message' => $notify_message
                ], 403);
            }


            $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');
            return response()->json([
                'message' => $notify_message
            ]);
        } else {
            $notify_message = trans('translate.Job already has assigned, so you can not assign again');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }
    }


    public function message_box_by_jobpost($id)
    {
        $user = Auth::guard('api')->user();

        if (!checkModule('LiveChat')) {
            $notify_message = trans('translate.Live Chat module is not enabled, please contact with admin');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

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

        $seller = User::select('id', 'name', 'designation', 'email', 'phone', 'image')->find($job_request->seller_id);

        return response()->json([
            'messages' => $messages,
            'seller' => $seller,
            'job_request' => $job_request,
            'job_post_submition_files' => $job_post_submition_files
        ]);
    }

    public function message_list_by_jobpost($id)
    {
        $user = Auth::guard('api')->user();

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

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

        return response()->json([
            'messages' => $messages
        ]);
    }

    public function jobpost_message_store(Request $request, $id)
    {
        $request->validate([
            'message' => 'required',
        ], [
            'message.required' => trans('translate.Message is required'),
        ]);

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

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

        $message = new JobPostMessage();
        $message->buyer_id = $user->id;
        $message->seller_id = $job_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 =  $user->id;
                $document->file_type =  $request->file_type;
                $document->seller_id =   $job_request->seller_id;
                $document->file_name = $file_path;
                $document->save();
            }
        }

        return response()->json([
            'message' => trans('translate.Message sent successfully')
        ]);
    }


    public function job_application_order_approved($id)
    {
        $user = Auth::guard('api')->user();

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

        if ($job_request->approved_status == 'approved') {
            return response()->json([
                'message' => trans('translate.Order already approved')
            ], 403);
        }

        $job_request->approved_status = 'approved';
        $job_request->save();

        $notify_message = trans('translate.Order Accepted Successfully');
        return response()->json([
            'message' => $notify_message
        ]);
    }


    public function job_application_order_cancel(Request $request, $id)
    {
        $request->validate([
            'cancel_reason' => 'required',
        ], [
            'cancel_reason.required' => trans('translate.Cancel reason is required'),
        ]);

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

        $job_request = JobRequest::where(['user_id' => $user->id, 'id' => $id])->first();

        if (!$job_request) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

        if (!checkModule('Wallet') || !checkModule('Refund')) {
            $notify_message = trans('translate.Wallet and Refund module is not enabled, please contact with admin');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }

        $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');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }

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

        if (!$job) {
            return response()->json([
                'message' => trans('Not Found')
            ], 403);
        }

        if ($job_request->approved_status == 'cancel' || $job_request->approved_status == 'approved') {
            $notify_message = trans('translate.Order already canceled or approved');
            return response()->json([
                'message' => $notify_message
            ], 403);
        }

        $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;
        $refund->save();

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


        $notify_message = trans('translate.Order Cancel Request Send Successfully');
        return response()->json([
            'message' => $notify_message
        ]);
    }
}
