<?php

namespace App\Http\Controllers\Api\v2;

use App\Components\Functions;
use App\Components\MomoServices;
use App\Models\District;
use App\Models\Hostel;
use App\Models\HostelPostCrawl;
use App\Models\HostelPostCrawlMedia;
use App\Models\HostelPostCrawlVip;
use App\Models\Order;
use App\Models\Province;
use App\Models\ReportSale;
use App\Models\ReportSaleType;
use App\Models_v2\Conversation;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class HostelPostCrawlController extends BaseController
{
    //
    /**
     * @api {get} v2/hostel-post-crawl/list Danh sách crawl
     * @apiName /list
     * @apiGroup HostelPostCrawl
     * * @apiParam {String} limit
     * @apiParam {String} offset
     * @apiParam {String} q
     *
     * @apiDescription Api Danh sách crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getList(Request $request)
    {
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);
        $query = $request->input('q');
        $provinceId = $request->input('province_id');
        $districtId = $request->input('district_id');
        $wardId = $request->input('ward_id');
        $sort = $request->input('sort');
        $priceMin = $request->input('price_min');
        $priceMax = $request->input('price_max');
        $type = $request->input('type');
        $centerLat = $request->input('center_lat');
        $centerLng = $request->input('center_lng');
        $radius = $request->input('radius');
        $user = $this->user;

        $items = HostelPostCrawl::query()
            ->where('is_active', true)
            ->when(!empty($centerLat) && !empty($centerLng) && !empty($radius), function ($q) use ($centerLat, $centerLng, $radius) {
                $q->isWithinMaxDistance([
                    'lat' => $centerLat,
                    'lng' => $centerLng
                ], round($radius / 1000, 2));
            })
            ->with('medias')
            ->with('userWishlists')
            ->whereNotNull('content')
            ->has('medias')
            ->when(!empty($query), function ($q) use ($query) {
                $q->where('content', 'LIKE', '%' . $query . '%');
            })
            ->when(!empty($provinceId), function ($q) use ($provinceId) {
                $q->where('province_id', $provinceId);
            })
            ->when(!empty($districtId), function ($q) use ($districtId) {
                $q->where('district_id', $districtId);
            })
            ->when(!empty($wardId), function ($q) use ($wardId) {
                $q->where('ward_id', $wardId);
            })
            ->when(!empty($type), function ($q) use ($type) {
                $q->where('type', $type);
            })
            ->when(!empty($priceMin), function ($q) use ($priceMin) {
                $q->where('price_min', '>=', $priceMin);
            })
            ->when(!empty($priceMax), function ($q) use ($priceMax) {
                $q->where('price_max', '<=', $priceMax);
            })
            ->when(!empty($sort), function ($q) use ($sort) {
                if ($sort == 'price_asc') {
                    $q->orderBy('price', 'asc');
                } else if ($sort == 'price_desc') {
                    $q->orderBy('price', 'desc');
                } else if ($sort == 'latest') {
                    $q->orderBy('created_at', 'desc');
                }
            })
            ->limit($limit)
            ->offset($offset)
            ->orderBy('from', 'desc')
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($item) use ($user) {
                $arr = $item->toArray();
                unset($arr['user_wishlists']);
                $arr['province_name'] = optional($item->province)->name;
                $arr['district_name'] = optional($item->district)->name;
                $arr['ward_name'] = optional($item->ward)->name;
                $wishlisted = false;
                if ($user) {
                    if (in_array($user->id, $item->userWishlists->pluck('id')->toArray())) {
                        $wishlisted = true;
                    }
                }
                $arr['is_wishlist'] = $wishlisted;

                return $arr;
            });

        return response([
            'status' => 1,
            'message' => 'Success',
            'data' => $items
        ]);
    }

    public function getHostelPostCrawlVip(Request $request)
    {
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);
        $query = $request->input('q');
        $provinceId = $request->input('province_id');
        $districtId = $request->input('district_id');
        $wardId = $request->input('ward_id');
        $sort = $request->input('sort');
        $priceMin = $request->input('price_min');
        $priceMax = $request->input('price_max');
        $type = $request->input('type');
        $centerLat = $request->input('center_lat');
        $centerLng = $request->input('center_lng');
        $radius = $request->input('radius');
        $user = $this->user;
        $vipItems = HostelPostCrawlVip::query()
            ->where('is_active', true)
            ->take(10)->pluck('hostel_id')->unique()->toArray();

        $items = HostelPostCrawl::query()
            ->where('is_active', true)
            ->when(!empty($centerLat) && !empty($centerLng) && !empty($radius), function ($q) use ($centerLat, $centerLng, $radius) {
                $q->isWithinMaxDistance([
                    'lat' => $centerLat,
                    'lng' => $centerLng
                ], round($radius / 1000, 2));
            })
            ->whereIn('id', $vipItems)
            ->with('medias')
            ->with('userWishlists')
            ->whereNotNull('content')
            ->has('medias')
            ->when(!empty($query), function ($q) use ($query) {
                $q->where('content', 'LIKE', '%' . $query . '%');
            })
            ->when(!empty($provinceId), function ($q) use ($provinceId) {
                $q->where('province_id', $provinceId);
            })
            ->when(!empty($districtId), function ($q) use ($districtId) {
                $q->where('district_id', $districtId);
            })
            ->when(!empty($wardId), function ($q) use ($wardId) {
                $q->where('ward_id', $wardId);
            })
            ->when(!empty($type), function ($q) use ($type) {
                $q->where('type', $type);
            })
            ->when(!empty($priceMin), function ($q) use ($priceMin) {
                $q->where('price_min', '>=', $priceMin);
            })
            ->when(!empty($priceMax), function ($q) use ($priceMax) {
                $q->where('price_max', '<=', $priceMax);
            })
            ->when(!empty($sort), function ($q) use ($sort) {
                if ($sort == 'price_asc') {
                    $q->orderBy('price', 'asc');
                } else if ($sort == 'price_desc') {
                    $q->orderBy('price', 'desc');
                } else if ($sort == 'latest') {
                    $q->orderBy('created_at', 'desc');
                }
            })
            ->limit($limit)
            ->offset($offset)
            ->orderBy('from', 'desc')
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($item) use ($user) {
                $arr = $item->toArray();
                unset($arr['user_wishlists']);
                $arr['province_name'] = optional($item->province)->name;
                $arr['district_name'] = optional($item->district)->name;
                $arr['ward_name'] = optional($item->ward)->name;
                $wishlisted = false;
                if ($user) {
                    if (in_array($user->id, $item->userWishlists->pluck('id')->toArray())) {
                        $wishlisted = true;
                    }
                }
                $arr['is_wishlist'] = $wishlisted;

                return $arr;
            });

        return response([
            'status' => 1,
            'message' => 'Success',
            'data' => $items
        ]);
    }

    /**
     * @api {post} v2/hostel-post-crawl/create Thêm thông tin crawl
     * @apiName /create
     * @apiGroup HostelPostCrawl
     * @apiParam {String} user_post Tên người đăng
     * @apiParam {String} user_post_image Ảnh người đăng
     * @apiParam {String} user_post_phone SĐT người đăng
     * @apiParam {String} content nội dung
     * @apiParam {String} source_link Link nguồn
     * @apiParam {String} province Tỉnh
     * @apiParam {String} district Quận
     * @apiParam {String} ward Xã
     * @apiParam {String} address Địa chỉ
     * @apiParam {Array} medias Ảnh / video
     *
     *
     * @apiDescription Api Thêm thông tin crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function store(Request $request)
    {
        $data = $request->except([
            'medias',
            'province',
            'district',
            'ward'
        ]);

        $medias = $request->input('medias');
        $province = $request->input('province');
        $district = $request->input('district');
        $ward = $request->input('ward');

        if (!empty($province)) {
            $provinceItem = Province::query()->where('name', $province)->first();
            $data['province_id'] = optional($provinceItem)->provinceid;
        }

        if (!empty($district)) {
            $districtItem = District::query()->where('name', $district)->first();
            $data['district_id'] = optional($districtItem)->districtid;
        }

        if (!empty($ward)) {
            $wardItem = Province::query()->where('name', $ward)->first();
            $data['ward_id'] = optional($wardItem)->wardid;
        }

        if (isset($data['post_id'])) {
            $check = HostelPostCrawl::query()
                ->where('post_id', $data['post_id'])
                ->count();

            if ($check > 0) {
                return response([
                    'status' => 0,
                    'message' => 'Đã tồn tại post_id trước đó'
                ]);
            }
        }

        if (empty($request->input('content'))) {
            return response([
                'status' => 0
            ]);
        }

        if (empty($medias)) {
            return response([
                'status' => 0
            ]);
        }
        $item = HostelPostCrawl::create($data);
        if (is_array($medias)) {
            foreach ($medias as $media) {
                HostelPostCrawlMedia::create([
                    'hostel_post_crawl_id' => $item->id,
                    'media' => $media
                ]);
            }
        }

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }

    /**
     * @api {post} v2/hostel-post-crawl/create-vip Thêm vip
     * @apiName /create-vip
     * @apiGroup HostelPostCrawl
     * @apiParam {String} amount Số tiền
     * @apiParam {String} hostel_id id nhà trọ đẩy vip
     * @apiParam {String} customer_number
     * @apiParam {String} number_days số ngày đẩy vip
     * @apiParam {String} started_at thời điểm tính vip dạng Y-m-d H:i:s
     * @apiParam {String} ended_at thời điểm dừng vip dạng Y-m-d H:i:s
     * @apiParam {String} partner_ref_id
     * @apiParam {String} partner_trans_id
     * @apiParam {String} token
     * @apiParam {Array} medias Ảnh / video
     *
     *
     * @apiDescription Api Thêm vip
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function storeVip(Request $request)
    {
        $amount = $request->input('amount');
        $hostelId = $request->input('hostel_id');
        $customerNumber = $request->input('customer_number');
        $numberDays = $request->input('number_days');
        $startedAt = $request->input('started_at');
        $endedAt = $request->input('ended_at');
        $params = $request->only([
            'partner_ref_id',
            'partner_trans_id',
            'token'
        ]);
        $params['amount'] = $amount;
        $params['customer_number'] = $customerNumber;
        $params['description'] = 'Mua gói đăng tin';
        $momoClient = new MomoServices();
        $holdMoney = $momoClient->createAppPayRequest($params);
        if (isset($holdMoney['status'])) {
            if ($holdMoney['status'] == 0) {
                $order = HostelPostCrawlVip::create([
                    'hostel_id' => $hostelId,
                    'user_id' => $this->user->id,
                    'is_active' => false,
                    'started_at' => $startedAt,
                    'ended_at' => $endedAt,
                    'wallet_trans_id' => $holdMoney['transid'],
                    'request_log' => $params,
                    'response_log' => $holdMoney,
                    'amount' => $amount,
                    'number_days' => $numberDays,
                    'desc' => $params['description'],
                ]);
                $holdMoney['status'] = 1;
                $processOrder = $this->confirmMomoVip($order, $customerNumber);
                if ($processOrder['status']) {
                    return response([
                        'status' => 1,
                        'message' => 'Thanh toán thành công',
                        'data' => $processOrder['data']
                    ]);
                }

                return response([
                    'status' => 0,
                    'message' => 'Thanh toán thất bại'
                ]);
            }
        }
        return response([
            'status' => 0
        ]);
    }

    public function confirmMomoVip(HostelPostCrawlVip $order, $customerNumber)
    {
        $momoConfirmParam = [
            'partner_ref_id' => strval($order->id),
            'momo_trans_id' => strval($order->wallet_trans_id)
        ];
        $momoService = new MomoServices();
        try {
            \DB::beginTransaction();
            $order->is_active = true;
            $order->save();

            \DB::commit();
            $success = true;
            $momoConfirmParam['request_type'] = 'capture';

        } catch (\Exception $exception) {
            \DB::rollBack();
            $success = false;
            $momoConfirmParam['request_type'] = 'revertAuthorize';
            $momoConfirmParam['description'] = 'Hoàn lại vì lỗi exception trong quá trình thanh toán';
        }

        $response = $momoService->confirmPayApp($momoConfirmParam);
        return [
            'status' => $success,
            'data' => $response
        ];
    }

    /**
     * @api {post} v2/hostel-post-crawl/update Cập nhật thông tin crawl
     * @apiName /update
     * @apiGroup HostelPostCrawl
     * @apiParam {String} user_post Tên người đăng
     * @apiParam {String} user_post_image Ảnh người đăng
     * @apiParam {String} user_post_phone SĐT người đăng
     * @apiParam {String} content nội dung
     * @apiParam {String} source_link Link nguồn
     * @apiParam {String} province Tỉnh
     * @apiParam {String} district Quận
     * @apiParam {String} ward Xã
     * @apiParam {String} address Địa chỉ
     *
     *
     * @apiDescription Api Cập nhật thông tin crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function update(Request $request)
    {

        $data = $request->except([
            'province',
            'district',
            'ward',
            'id'
        ]);

        $medias = $request->input('medias');
        $province = $request->input('province');
        $district = $request->input('district');
        $ward = $request->input('ward');
        $id = $request->input('id');
        $item = HostelPostCrawl::find($id);
        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if (!empty($province)) {
            $data['province_id'] = $province;
        }

        if (!empty($district)) {
            $data['district_id'] = $district;
        }

        if (!empty($ward)) {
            $data['ward_id'] = $ward;
        }

        if (isset($data['post_id'])) {
            $check = HostelPostCrawl::query()
                ->where('post_id', $data['post_id'])
                ->count();

            if ($check > 0) {
                return response([
                    'status' => 0,
                    'message' => 'Đã tồn tại post_id trước đó'
                ]);
            }
        }
        $item->update($data);

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }


    /**
     * @api {post} v2/hostel-post-crawl/delete Xóa thông tin crawl
     * @apiName /delete
     * @apiGroup HostelPostCrawl
     * @apiParam {String} id
     *
     *
     * @apiDescription Api Xóa thông tin crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function destroy(Request $request)
    {
        HostelPostCrawl::query()
            ->where('id', $request->input('id'))
            ->delete();

        return response([
            'status' => 1,
            'message' => 'Success',
        ]);
    }

    /**
     * @api {post} v2/hostel-post-crawl/active Ẩn hiện tin đăng
     * @apiName /active
     * @apiGroup HostelPostCrawl
     * @apiParam {String} hostel_id (ID của nhà trọ trên hệ thống)
     *
     *
     * @apiDescription Api Ẩn hiện tin đăng
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function updateActive(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $item = HostelPostCrawl::query()->where('hostel_id', $hostelId)->first();
        if (!$item) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }

        if ($item->is_active) {
            $item->is_active = false;
        } else {
            $item->is_active = true;
        }
        $item->save();
        return response([
            'status' => 1
        ]);
    }

    /**
     * @api {get} v2/hostel-post-crawl/detail Chi tiet thông tin crawl
     * @apiName /detail
     * @apiGroup HostelPostCrawl
     * @apiParam {String} id
     *
     *
     * @apiDescription Api Chi tiet thông tin crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function detail(Request $request)
    {
        $id = $request->input('id');
        $item = HostelPostCrawl::query()
            ->with('medias')
            ->where('id', $id)
            ->first();
        $item->province_name = optional($item->province)->name;
        $item->district_name = optional($item->district)->name;
        $item->ward_name = optional($item->ward)->name;
        $wishlisted = false;
        if ($this->user) {
            if (in_array($this->user->id, $item->userWishlists->pluck('id')->toArray())) {
                $wishlisted = true;
            }
        }
        $item->is_wishlist = $wishlisted;
        $item->content = strip_tags($item->content);

        if($item->hostel)
        {
            $item->videos = $item->hostel->videos;
        }

        unset($item->province);
        unset($item->district);
        unset($item->ward);
        return response([
            'status' => 1,
            'data' => $item
        ]);
    }

    /**
     * @api {post} /report Báo cáo
     * @apiName report
     * @apiGroup HostelPostCrawl
     * @apiDescription Báo cáo
     * @apiParam {String} hostel_id
     * @apiParam {String} post_crawl_id
     * @apiParam {Array} types Các loại
     * @apiParam {String} content
     *
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function reportSale(Request $request)
    {
        $userId = $this->user->id;
        $conversationId = $request->input('conversation_id');
        $hostelId = $request->input('hostel_id');
        $content = $request->input('content');
        $types = $request->input('types');
        $hostelPostCrawlId = $request->input('post_crawl_id');

        $conversation = Conversation::find($conversationId);
        $owner = null;
        if ($conversation) {
            $owner = $conversation->users()
                ->where('users.id', '<>', $userId)
                ->first();
        } else {
            if (!empty($hostelId)) {
                $hostel = Hostel::find($hostelId);
                if ($hostel) {
                    $owner = $hostel->owner;
                }
            }
        }

        $sale = ReportSale::create([
            'user_id' => $userId,
            'conversation_id' => $conversationId,
            'owner_id' => !empty($owner) ? $owner->id : null,
            'content' => $content,
            'hostel_id' => $hostelId,
            'hostel_post_crawl_id' => $hostelPostCrawlId
        ]);

        if (is_array($types)) {
            foreach ($types as $type) {
                ReportSaleType::create([
                    'report_sale_id' => $sale->id,
                    'type' => $type
                ]);
            }
        }


        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }


}
