<?php

namespace App\Http\Controllers;

use App\Area;
use App\Brand;
use App\BrandDetail;
use App\Events\NotifyEvent;
use App\Helpers\Helper;
use App\Notify;
use App\Package;
use App\Station;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Store;
use App\Http\Resources\StoreResource;
use DB;
use Validator;
use Mail;

class StoreController extends Controller
{
    const ITEM_PER_PAGE = 50;

    public function index(Request $request)
    {
        $params = $request->all();
        $limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($params, 'keyword', '');

        $list = Store::select('id', 'area_id', 'station_id', 'title', 'name', 'slug', 'address')->isPublished();
        if (!empty($keyword)) $list->where('name', 'LIKE', '%' . $keyword . '%');
        $list->orderBy('rating', 'DESC')->orderBy('id', 'DESC');

        return StoreResource::collection($list->paginate($limit));
    }

    public function search(Request $request)
    {
        $params = $request->all();
        $limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($params, 'keyword', '');
        $areaSlug = Arr::get($params, 'area', '');
        $stationSlug = Arr::get($params, 'station', '');
        $brandSlug = Arr::get($params, 'brand', '');

        $list = Store::select('id', 'area_id', 'station_id', 'title', 'name', 'slug', 'address')->isPublished();

        if ($areaSlug != null && $areaSlug != "") {
            $listStationIds = [];
            $area = Area::isPublished()->where('slug', $areaSlug)->first();
            if (isset($area)) {
                if ($stationSlug != null && $stationSlug != "") {
                    $station = Station::select('id', 'area_id')
                        ->isPublished()
                        ->where('area_id', $area->id)
                        ->where('slug', $stationSlug)
                        ->first();
                    if (isset($station)) $listStationIds[] = $station->id;
                } else {
                    $listAreaChild = Area::select('id', 'parent_id')
                        ->isPublished()
                        ->where('id', '!=', $area->id)
                        ->where('parent_id', '!=', 0)
                        ->get();
                    $areaIds = $this->getChildArea($listAreaChild, $area->id);
                    $areaIds[] = $area->id;
                    $listStationIds = Station::select('id')->isPublished()->whereIn('area_id', $areaIds)->pluck('id')->toArray();
                }
            }

            $list->whereIn('station_id', $listStationIds);
        }

        if ($brandSlug != null && $brandSlug != "") {
            $storeIds = [];
            $brand = Brand::isPublished()->where('slug', $brandSlug)->first();
            if (isset($brand)) $storeIds = BrandDetail::select('store_id')->where('brand_id', $brand->id)->pluck('store_id')->toArray();

            $list->whereIn('id', $storeIds);
        }

        if (!empty($keyword)) {
            $areaItem = Area::isPublished()->where('name', $keyword)->first();
            $areaIds = [];
            if (isset($areaItem)) {
                $listAreaChild = Area::select('id', 'parent_id')
                    ->isPublished()
                    ->where('id', '!=', $areaItem->id)
                    ->where('parent_id', '!=', 0)
                    ->get();
                $areaIds = $this->getChildArea($listAreaChild, $areaItem->id);
                $areaIds[] = $areaItem->id;
            }

            $stationIds = Station::select('id', 'area_id')->isPublished()->where('name', $keyword)->pluck('id')->toArray();
            /*$brandIds = [];
            $brandItem = Brand::isPublished()->where('name', $keyword)->first();
            if (isset($brandItem)) {
                $brandIds = BrandDetail::select('store_id')->where('brand_id', $brandItem->id)->pluck('store_id')->toArray();
            }*/

            $list->where(function ($query) use ($keyword, $areaIds, $stationIds) {
                $query->where('name', 'LIKE', '%' . $keyword . '%');
                if (count($areaIds) > 0) $query->orWhereIn('area_id', $areaIds);
                if (count($stationIds) > 0) $query->orWhereIn('station_id', $stationIds);
            });
        }

        $list->orderBy('name')->orderBy('id', 'DESC');

        return StoreResource::collection($list->paginate($limit));
    }

    public function top(Request $request)
    {
        $params = $request->all();
        $limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($params, 'keyword', '');
        $areaSlug = Arr::get($params, 'area', '');

        $list = Store::select('id', 'area_id', 'station_id', 'title', 'name', 'slug', 'address')->isPublished();
        if (!empty($keyword)) $list->where('name', 'LIKE', '%' . $keyword . '%');

        if ($areaSlug != null && $areaSlug != "") {
            $listStationIds = [];
            $area = Area::isPublished()->where('slug', $areaSlug)->first();
            if (isset($area)) {
                $listAreaChild = Area::select('id', 'parent_id')
                    ->isPublished()
                    ->where('id', '!=', $area->id)
                    ->where('parent_id', '!=', 0)
                    ->get();
                $areaIds = $this->getChildArea($listAreaChild, $area->id);
                $areaIds[] = $area->id;
                $listStationIds = Station::select('id')->isPublished()->whereIn('area_id', $areaIds)->pluck('id')->toArray();
            }

            $list->whereIn('station_id', $listStationIds);
        }

        $list->orderBy('rating', 'DESC')->orderBy('id', 'DESC');

        return StoreResource::collection($list->paginate($limit));
    }

    public function position(Request $request)
    {
        $params = $request->all();
        $limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
        $lat = Arr::get($params, 'lat', '');
        $lng = Arr::get($params, 'lng', '');

        if ($lat == 'null' || $lat == 'undefined') $lat = 0;
        if ($lng == 'null' || $lng == 'undefined') $lng = 0;

        $distanceCondition = "(6371 * 2 * ASIN(SQRT(POWER(SIN(({$lat}-stores.latitude)*pi()/180/2),2)+COS({$lat}*pi()/180)*COS(stores.latitude*pi()/180)*POWER(SIN(({$lng}-stores.longitude)*pi()/180/2),2))))";

        $list = Store::with('location', 'station')
            ->select(array('stores.*', DB::raw($distanceCondition . ' as distance')))
            ->where('stores.is_deleted', false)
            ->where('stores.is_activated', true);

        if (($lat == "" || $lng == "") || ($lat == 0 && $lng == 0)) $list = $list->where('stores.id', 0);
        $list = $list->whereRaw($distanceCondition . ' <= 5')
            ->orderBy('distance')
            ->orderBy('stores.rating', 'DESC')
            ->orderBy('stores.created_at', 'ASC');

        return StoreResource::collection($list->paginate($limit));

        /*$list = DB::table('stores')
            ->select(array('stores.*', 'lc.title as location_name', 'sa.title as station_name', DB::raw($distanceCondition . ' as distance')))
            ->join('locations as lc', 'lc.id', '=', 'stores.location_id')
            ->leftJoin('locations as sa', 'sa.id', '=', 'stores.station_id')
            ->where('stores.is_deleted', false)
            ->where('stores.is_activated', true);
        if (($lat == "" || $lng == "") || ($lat == 0 && $lng == 0)) $list = $list->where('stores.id', 0);
        $list = $list->whereRaw($distanceCondition . ' <= 5')
            ->orderBy('distance')
            ->orderBy('stores.rating', 'DESC')
            ->orderBy('stores.created_at', 'ASC')
            ->paginate(self::PAGE_LIMIT);*/
    }

    public function header(Request $request)
    {
        $params = $request->all();
        $areaSlug = Arr::get($params, 'area', '');
        $stationSlug = Arr::get($params, 'station', '');
        $brandSlug = Arr::get($params, 'brand', '');
        $result = ['area' => 'All', 'station' => 'All', 'brand' => 'brands'];

        $area = Area::select('name')->isPublished()->where('slug', $areaSlug)->first();
        if (isset($area)) {
            $result['area'] = $area->name;
            $station = Station::select('name')->isPublished()->where('area_id', $area->id)->where('slug', $stationSlug)->first();
            if (isset($station)) $result['station'] = $station->name;
        }
        $brand = Brand::select('name')->isPublished()->where('slug', $brandSlug)->first();
        if (isset($brand)) $result['brand'] = $brand->name;

        return response()->json($result, 200);
    }

    public function show($id = 0)
    {
        $store = Store::select('id', 'area_id', 'station_id', 'title', 'name', 'slug', 'open_time', 'working_time', 'phone_number', 'address', 'longitude', 'latitude')
            ->isPublished()
            ->where('id', $id)
            ->first();
        if (!isset($store)) return response()->json(['data' => [], 'status' => 'error', 'errors' => 'Store is not valid.'], 200);

        return new StoreResource($store);
    }

    public function relate($id = 0, Request $request)
    {
        $params = $request->all();
        $limit = Arr::get($params, 'limit', static::ITEM_PER_PAGE);
        $list = Store::select('id', 'area_id', 'station_id', 'title', 'name', 'slug', 'address')
            ->isPublished()
            ->where('id', '!=', $id)
            ->orderBy('rating', 'DESC')
            ->orderBy('id', 'DESC');

        return StoreResource::collection($list->paginate($limit));
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'         => ['required'],
            'email'        => ['required', 'email'],
            'phone_number' => ['required'],
            'package_id'   => ['required'],
        ]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);

        $params = $request->all();
        Store::create([
            'area_id'       => 1,
            'name'          => $params['name'],
            'slug'          => Helper::slug($params['name']),
            'email'         => $params['email'],
            'phone_number'  => $params['phone_number'],
            'title'         => $params['title'],
            'package_id'    => $params['package_id'],
            'other_request' => $params['other_request'],
            'is_activated'  => 0,
            'created_at'    => date('Y-m-d H:i:s'),
            'updated_at'    => date('Y-m-d H:i:s')
        ]);

        //hunters2fujiyoshi@gmail.com
        Notify::create(['content' => "[" . $params['name'] . "] just registered a store.", 'module' => 'contact']);
        event(new NotifyEvent()); //broadcast(new NotifyEvent($notify));

        try {
            $package = Package::where('is_deleted', false)->where('is_activated', true)->where('id', $params['package_id'])->first();

            $email = $params['email'];
            $data['name'] = $params['name'];
            $data['email'] = $params['email'];
            $data['phone_number'] = $params['phone_number'];
            $data['title'] = $params['title'];
            $data['package'] = ($package != null) ? $package->name : '';
            $data['other_request'] = htmlspecialchars_decode(strip_tags($params['other_request']));

            Mail::send('emails.register', $data, function ($message) use ($email) {
                $message->from('fujiyoshi@gxo.co.jp', 'iPhone System');
                $message->to(config('settings.admin_email'));
                $message->subject('Member Register Notification');
            });
            logger("[Email] Send register email.");
        } catch (\Exception $exception) {
            logger("[Email] Error: Send register email has an error.");
        }

        return response()->json(['status' => 'success', 'message' => 'Register successfully.'], 201);
    }

    private function getChildArea($list, $parentId = 0)
    {
        $rs = [];
        foreach ($list as $item) {
            if ($item->parent_id == $parentId) {
                $rs[] = $item->id;
                $child = $this->getChildArea($list, $item->id);
                $rs = array_merge($rs, $child);
            }
        }
        return $rs;
    }
}
