<?php

namespace App\Modules\Bookings;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\App;
use Illuminate\Http\Request;
use App\Http\Controllers\BaseController;
use App\Models\Status;

class OrdersControllerRESTv1 extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index(Request $request)
    {
        $query = Order::select('tasks.*')->orders()->with('status', 'creator', 'parts');

        if ($request->input('assigned_to')) {
            $query = $query->where('assigned_to', $request->input('assigned_to'));
        }

        if ($request->input('client_id')) {
            $query = $query->where('client_id', $request->input('client_id'));
        }

        if ($request->input('status_id')) {
            $query = $query->where('status_id', $request->input('status_id'));
        }

        if ($request->input('results')) {
            switch ($request->input('results')) {
                case 'own':
                    $query = $query->where('assigned_to', '=', $request->input('user_id', Auth::user()->id)); break;
                case 'unassigned':
                    $query = $query->where('completed', '=', 0);
            }
        }

        // Display only orders that have not been completed
        if ($request->input('completed')) {
            $query->where('completed', 1);
        }

        // Sort results based on priority
        $query->join('severities', 'severities.id', '=', 'tasks.severity_id', 'left')
              ->orderBy('severities.priority', 'desc');

        // Apply limits and execute the query
        $query = $query->paginate($request->input('limit', 30));

        foreach ($query as $value) {
            // Load all the clients
            // unfortuately eager loading is not available
            // for polymorphic relationships at the moment..
            if ($request->input('client') && $request->input('client') != 'false') {
                $value->client;
            }

            // Load all the comment stats
            $value->comments_count = [
                'total'   => $value->comments()->count(),
                'unread'  => $value->comments()->unread()->count(),
            ];
        }

        $response = [
            'success'      => true,
            'data'         => $query->getCollection()->toArray(),
            'total'        => $query->total(),
            'current_page' => $query->currentPage(),
            'last_page'    => $query->lastPage(),
            'from'         => $query->firstItem(),
            'to'           => $query->lastItem(),
        ];

        return response()->json($response, ($response['success']) ? 200 : 400);
    }

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

        if (count($request->input('parts', [])) == 0) {
            return response()->json(['errors' => 'It is no possible to create an order without parts.'], 400);
        }

        return DB::transaction(function () use ($request) {
            $order = Order::create([
                'client_id'        => $request->input('client_id'),
                'client_type'      => $request->input('client_type'),
                'site_id'          => $request->input('site_id'),
                'site_user_id'     => $request->input('site_user_id'),
                'project_id'       => $request->input('project_id'),
                'status_id'        => 2,
            ]);

            if ($order->id) {
                $partService = App::make('App\Modules\Bookings\PartService');
                $partRequester = App::make('App\Modules\Bookings\PartRequester');

                foreach ($request->input('parts') as $p) {
                    $p['related_type'] = 'task';
                    $p['related_id'] = $order->id;

                    if (isset($p['on_order']) && $p['on_order']) {
                        $part = $partRequester->request($p);
                    } else {
                        $part = $partService->create($p);
                    }

                    if (! $part->exists) {
                        DB::rollback();

                        return response()->json(['errors' => $part->errors->all()], 400);
                    }
                }
                $response = [
                    'success' => true,
                    'data'    => $order->toArray(),
                ];
            } else {
                $response = [
                    'success' => false,
                    'errors'  => $order->errors->all(),
                ];
            }

            return response()->json($response, ($response['success']) ? 200 : 400);
        });
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     *
     * @return Response
     */
    public function show($id)
    {
        $order = Order::find($id);

        $order->load('user', 'client', 'creator', 'parts');

        $order->statuses = Status::orders()->get();

        if ($order->client_type == 'client') {
            $order->load('client.sites', 'client.sites.users', 'site', 'site_user');
        }

        if (! $order) {
            return response()->json(['error' => 'Order not found.'], 404);
        }

        return response()->json($order->toArray());
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     *
     * @return Response
     */
    public function update($id)
    {
        $order = Order::find($id);

        //Check if the order is being cancelled
        $cancelling = $request->has('status_id') && $request->input('status_id') == '29' && $order->status_id != '29';

        if ($cancelling && $order->completed) {
            return response()->json([
                'errors' => 'A completed order can not be cancelled!',
            ], 400);
        }

        $order->fill($request->except('id'));

        if ($order->save()) {
            //If cancelling the order put back all the parts.
            if ($cancelling) {
                foreach ($order->parts as $part) {
                    \Event::dispatch('PartDeleted', $part);
                }
            }

            $order->load('user');

            if ($order->client_type == 'client') {
                $order->load('client.sites', 'client.sites.users', 'site', 'site_user');
            }

            return response()->json($order->toArray());
        } else {
            return response()->json([
                'errors' => $order->errors->all(),
            ], 400);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     *
     * @return Response
     */
    public function destroy($id)
    {
        $order = Order::find($id);

        // Access validations
        // should be implemented here...

        if (! $order) {
            return response()->json(['error' => 'Order not found.'], 404);
        }

        if ($order->delete()) {
            return response()->json($order->toArray());
        } else {
            return response()->json([
                'errors' => $order->errors->all(),
            ], 400);
        }
    }
        private function SendToXero($fields){
            $xeroService = app(\App\Modules\Xero\Services\XeroService::class);
            return $xeroService->sendToXero($fields, $fields->type ?? 'invoice');
        }

}
