<?php

namespace App\Http\Controllers\Resources;

use Illuminate\Http\Request;
use App\Http\Requests\UserRequest;
use App\Http\Requests\ExportRequest;
use App\Http\Requests\ImportRequest;
use App\Http\ReportGenerator\PdfReport;
use App\Http\ReportGenerator\ExcelReport;
use App\Http\Controllers\Controller;
use App\Http\Filters\QueryBuilder;

use App\User;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $queryBuilder = new QueryBuilder(new User, $request);

        return response()->json($queryBuilder->build()->withTrashed()->paginate(10),200);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  App\Http\Requests\UserRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(UserRequest $request)
    {
      return response()->json(tap(new User($request->all()), function ($user) use ($request){
          $user->password = bcrypt($request->password);
          $user->save();
          $user->assignRole($request->role);
      }), 201);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
      $user=User::find($id);

  		if (!$user) {
  			return response()->json(['errors'=>array(['code'=>404,'message'=>__('users.not_find')])],404);
  		}

  		return response()->json(['status'=>'ok','data'=>$user],200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  App\Http\Requests\UserRequest  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(UserRequest $request, $id)
    {
        $user=User::withTrashed()->find($id);
        $user->assignRole($request->role);

        if (!$user) {
    			return response()->json(['errors'=>array(['code'=>404,'message'=>__('users.not_find')])],404);
    		}

        if (isset($request->password)) {
          return tap($user)->update([
            'name' => $request->name,
            'email' => $request->email,
            'password' =>  bcrypt($request->password),
          ]);
        } else {
          return tap($user)->update([
            'name' => $request->name,
            'email' => $request->email,
          ]);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(UserRequest $request, $id)
    {
      $user=User::withTrashed()->find($id);

      if (!$user) {
        return response()->json(['errors'=>array(['code'=>404,'message'=>__('users.not_find')])],404);
      }

      if ($user->email === 'admin@example.com') {
        return response()->json(['errors'=>array(['code'=>404,'message'=>__('errors.action_unauthorized')])],404);
      }

      $user->forceDelete();

      return response()->json(['code'=>204,'message'=>__('strings.deleted_successfully')],204);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  array  $id
     * @return \Illuminate\Http\Response
     */
    public function destroyMany(UserRequest $request)
    {
      foreach ($request->input('ids') as $id) {
        $user=User::withTrashed()->find($id);

        if (!$user) {
          return response()->json(['errors'=>array(['code'=>404,'message'=>__('users.not_find')])],404);
        }

        if ($user->email === 'admin@example.com') {
          return response()->json(['errors'=>array(['code'=>404,'message'=>__('errors.action_unauthorized')])],404);
        }
      }

      foreach ($request->input('ids') as $id) {
        $user=User::find($id);

        $user->forceDelete();
      }

      return response()->json(['code'=>204,'message'=>__('strings.deleted_successfully')],204);
    }

    /**
     * Display report from a listing of the resource.
     *
     * @param  App\Http\Requests\ExportRequest $request
     * @return PDF CSV or XLS
     */
    public function export(ExportRequest $request)
    {
      $format = $request->input('format');
      $orderBy = $request->input('order_by');
      $betweenDates = ($request->input('between_dates')) ? explode(',', $request->input('between_dates')): ['',''];

      $queryBuilder = new QueryBuilder(new User, $request);

      $meta = [ // For displaying filters description on header
          __('strings.registered_on') => $betweenDates[0].' - '.$betweenDates[1],
          __('strings.order_by') => $orderBy,
      ];

      $columns = [ // Set Column to be displayed
          __('users.name') => 'name',
          __('users.email') => 'email',
          __('users.role') => function ($user)
          {
            return $user->view_permissions[0];
          },
          __('users.status') => 'status',
      ];

      switch ($format) {
        case 'pdf':
          $report = new PdfReport();
          return $report->of(__('users.report_title'), $meta, $queryBuilder->build()->withTrashed()->get(), $columns)->download(__('users.report_title'));
        case 'excel':
          $report = new ExcelReport();
          return $report->of(__('users.report_title'), $meta, $queryBuilder->build()->withTrashed()->get(), $columns)->setView('reports.list-excel-template')->download(__('users.report_title'));
        case 'csv':
          $report = new ExcelReport();
          return $report->of(__('users.report_title'), $meta, $queryBuilder->build()->withTrashed()->get(), $columns)->simple()->setFormat('csv')->download(__('users.report_title'));
        default:
          $report = new PdfReport();
          return $report->of(__('users.report_title'), $meta, $queryBuilder->build()->withTrashed()->get(), $columns)->stream();
      }
    }

    public function inactived($id)
    {
      $user=User::withTrashed()->find($id);

      if ($user->deleted_at) {
        return response()->json(['errors'=>array(['code'=>400,'message'=>__('users.inactived_error')])],400);
      }

      if ($user->email === 'admin@example.com') {
        return response()->json(['errors'=>array(['code'=>404,'message'=>__('errors.action_unauthorized')])],404);
      }

      $user->delete();

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

    public function actived($id)
    {
      $user=User::withTrashed()->find($id);

      if (!$user->deleted_at) {
        return response()->json(['errors'=>array(['code'=>400,'message'=>__('users.actived_error')])],400);
      }

      $user->restore();

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