<?php
/**
 * File UserController.php
 *
 * @author Tuan Duong <bacduong@gmail.com>
 * @package Laravue
 * @version 1.0
 */

namespace App\Http\Controllers;

use App\Http\Resources\PermissionResource;
use App\Http\Resources\ProductResource;
use App\Http\Resources\UserResource;
use App\Laravue\JsonResponse;
use App\Laravue\Models\Permission;
use App\Laravue\Models\Role;
use App\Laravue\Models\User;
use App\Product;
use App\UserType;
use App\UserWishlist;
use App\Services\IdentityVerificationService;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Validator;

/**
 * Class UserController
 *
 * @package App\Http\Controllers
 */
class UserController extends Controller
{
	const ITEM_PER_PAGE = 20;
	private $_limitedItems;
	
	public function __construct()
	{
		$user = auth('api')->user();
		$this->_limitedItems = ['hasLimited' => false, 'data' => []];
		if ($user != null && !$user->hasRole('admin') && !$user->hasRole('manager') && !$user->hasPermissionTo('manage-user')) {
			$this->_limitedItems['hasLimited'] = true;
			$this->_limitedItems['data'] = User::select('id')->where('created_by', $user->id)->pluck('id')->toArray();
			if ($this->_limitedItems['data'] == null || count($this->_limitedItems['data']) <= 0) {
				$this->_limitedItems['data'][] = 0;
			}
		}
	}
	
	/**
	 * Display a listing of the user resource.
	 *
	 * @param \Illuminate\Http\Request $request
	 * @return \Illuminate\Http\Response|ResourceCollection
	 */
	public function index(Request $request)
	{
		$searchParams = $request->all();
		$userQuery = User::query();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$role = Arr::get($searchParams, 'role', '');
		$keyword = Arr::get($searchParams, 'keyword', '');
		$verificationStatus = Arr::get($searchParams, 'verificationStatus', '');
		
		if ($role != "" && $role != null) {
			$userQuery->whereHas('roles', function ($q) use ($role) {
				$q->where('name', $role);
			});
		}
		
		if ($keyword != "" && $keyword != null) {
			$userQuery->where(function ($query) use ($keyword) {
				// Kiểm tra nếu keyword là số (ID)
				if (is_numeric($keyword)) {
					$query->where('id', $keyword)
						->orWhere('name', 'LIKE', '%' . $keyword . '%')
						->orWhere('email', 'LIKE', '%' . $keyword . '%');
				} else {
					$query->where('name', 'LIKE', '%' . $keyword . '%')
						->orWhere('email', 'LIKE', '%' . $keyword . '%');
				}
			});
		}
		
		// Filter theo trạng thái xác thực
		if ($verificationStatus != "" && $verificationStatus != null) {
			if ($verificationStatus === 'not_submitted') {
				// not_submitted bao gồm cả null
				$userQuery->where(function ($q) {
					$q->where('identity_status', 'not_submitted')
						->orWhereNull('identity_status');
				});
			} else {
				$userQuery->where('identity_status', $verificationStatus);
			}
		}
		
		if ($this->_limitedItems['hasLimited']) {
			$userQuery->whereIn('id', $this->_limitedItems['data']);
		}
		
		return UserResource::collection($userQuery->paginate($limit));
	}
	
	public function assigned(Request $request)
	{
		$searchParams = $request->all();
		$userQuery = User::query();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		
		if ($this->_limitedItems['hasLimited']) {
			$userQuery->whereIn('id', $this->_limitedItems['data']);
		}
		
		return UserResource::collection($userQuery->paginate($limit));
	}
	
	/**
	 * Store a newly created resource in storage.
	 *
	 * @param \Illuminate\Http\Request $request
	 * @return \Illuminate\Http\Response
	 */
	public function store(Request $request)
	{
		$validator = Validator::make(
			$request->all(),
			array_merge(
				$this->getValidationRules(),
				[
					'password'        => ['required', 'min:6'],
					'confirmPassword' => 'same:password',
				]
			)
		);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		} else {
			$params = $request->all();
			$user = User::create([
				'name'       => isset($params['full_name']) ? $params['full_name'] : '',
				'point_rate' => 0,
				'email'      => $params['email'],
				'password'   => Hash::make($params['password']),
				'login_url'  => $params['login_url'],
				'created_by' => auth('api')->user()->id,
			]);
			$role = Role::findByName($params['role']);
			$user->syncRoles($role);
			
			return new UserResource($user);
		}
	}
	
	/**
	 * Display the specified resource.
	 *
	 * @param User $user
	 * @return UserResource|\Illuminate\Http\JsonResponse
	 */
	public function show(User $user)
	{
		if ($this->_limitedItems['hasLimited']) {
			$userCheck = User::select('id')->where('id', $user->id)->whereIn('id', $this->_limitedItems['data'])->first();
			if ($userCheck === null || !isset($userCheck->id)) {
				return response()->json(['error' => __('messages.user_not_found')], 404);
			}
		}
		
		return new UserResource($user);
	}
	
	/**
	 * Update the specified resource in storage.
	 *
	 * @param Request $request
	 * @param User $user
	 * @return UserResource|\Illuminate\Http\JsonResponse
	 */
	public function update(Request $request, User $user)
	{
		if ($this->_limitedItems['hasLimited']) {
			$userCheck = User::select('id')->where('id', $user->id)->whereIn('id', $this->_limitedItems['data'])->first();
			if ($userCheck === null || !isset($userCheck->id)) {
				return response()->json(['error' => __('messages.user_not_found')], 404);
			}
		}
		
		if ($user === null) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$currentUser = Auth::user();
		/*if ($currentUser->id != 1 && $user->isAdmin()) {
			return response()->json([ 'error' => 'Admin can not be modified' ], 403);
		}*/
		
		/*$currentUser = Auth::user();
		if (
			!$currentUser->isAdmin()
			&& $currentUser->id !== $user->id
			&& !$currentUser->hasPermission(\App\Laravue\Acl::PERMISSION_USER_MANAGE)
			&& !$currentUser->hasPermission(\App\Laravue\Acl::PERMISSION_USER_EDIT_MANAGE)
		) {
			echo "<pre>";print_r('okoko');echo "</pre>";die();
			return response()->json(['error' => 'Permission denied'], 403);
		}*/
		
		$validator = Validator::make($request->all(), $this->getValidationRules(false));
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		} else {
			$params = $request->all();
			
			$foundEmail = User::where('email', $params['email'])->first();
			if ($foundEmail && $foundEmail->id !== $user->id) {
				return response()->json(['error' => __('messages.email_has_been_taken')], 403);
			}
			
			$username = $user->username;
			if (isset($params['username'])) {
				$username = str_replace(" ", "", $params['username']);
				$foundUsername = User::where('username', $username)->first();
				if ($foundUsername && $foundUsername->id !== $user->id) {
					return response()->json(['error' => __('messages.username_has_been_taken')], 403);
				}
			}
			
			$fullName = isset($params['full_name']) ? $params['full_name'] : $user->full_name;
			if (($fullName == null || $fullName == "") && isset($params['first_name'])) {
				$fullName = $params['first_name'];
				if (isset($params['last_name'])) $fullName .= " " . $params['last_name'];
			}
			if ($fullName == null || $fullName == "") {
				$fullName = $user->name ?: ($user->email ?: '');
			}
			
			$furiganaName = isset($params['furigana_name']) ? $params['furigana_name'] : $user->furigana_name;
			if (($furiganaName == null || $furiganaName == "") && isset($params['furigana_first_name'])) {
				$furiganaName = $params['furigana_first_name'];
				if (isset($params['furigana_last_name'])) $furiganaName .= $params['furigana_last_name'];
			}
			
			$cardVerify = $user->verify_card;
			if (isset($params['verify_card'])) {
				$cardVerify = ($params['verify_card'] == true || $params['verify_card'] == "true") ? 1 : 0;
			}
			
			// Xử lý identity_status - gọi IdentityVerificationService khi thay đổi từ pending
			$identityStatusChanged = false;
			$newIdentityStatus = null;
			if (isset($params['identity_status'])) {
				$newStatus = $params['identity_status'];
				// Chỉ cho phép thay đổi nếu status hiện tại là pending
				if ($user->identity_status === 'pending' && in_array($newStatus, ['approved', 'rejected'])) {
					$identityStatusChanged = true;
					$newIdentityStatus = $newStatus;
				}
			}
			
			$updateData = [
				'username'            => $username,
				'email'               => isset($params['email']) ? $params['email'] : $user->email,
				'first_name'          => $fullName,
				'last_name'           => $fullName,
				'full_name'           => $fullName,
				'furigana_first_name' => $furiganaName,
				'furigana_last_name'  => $furiganaName,
				'furigana_name'       => $furiganaName,
				'name'                => $fullName,
				'gender'              => isset($params['gender']) ? $params['gender'] : $user->gender,
				'date_of_birth'       => isset($params['date_of_birth']) ? $params['date_of_birth'] : $user->date_of_birth,
				'slug'                => isset($params['username']) ? str_replace(" ", "", $params['username']) : $user->slug,
				'post_code'           => isset($params['post_code']) ? $params['post_code'] : $user->post_code,
				'city'                => isset($params['city']) ? $params['city'] : $user->city,
				'district'            => isset($params['district']) ? $params['district'] : $user->district,
				'address'             => isset($params['address']) ? $params['address'] : $user->address,
				'phone_number'        => isset($params['phone_number']) ? $params['phone_number'] : $user->phone_number,
				'mobile_tel'          => isset($params['mobile_tel']) ? $params['mobile_tel'] : $user->mobile_tel,
				'verify_card'         => $cardVerify,
				'introduction'        => isset($params['introduction']) ? $params['introduction'] : $user->introduction,
				'login_url'           => '/',
				'updated_at'          => date('Y-m-d H:i:s')
			];
			
			if ($request->has('password') && trim($request->get('password')) != "" && trim($request->get('password')) != null) {
				$updateData['password'] = Hash::make($request->get('password'));
			}
			
			$user->update($updateData);
			
			// Xử lý identity verification thông qua service
			if ($identityStatusChanged) {
				$admin = auth('api')->user();
				$identityService = new IdentityVerificationService();
				
				// Refresh user để có data mới nhất
				$user->refresh();
				// Đặt lại status về pending để service xử lý đúng
				$user->identity_status = 'pending';
				$user->save();
				
				try {
					if ($newIdentityStatus === 'approved') {
						$identityService->approve($user, $admin);
					} elseif ($newIdentityStatus === 'rejected') {
						$reason = $params['identity_rejection_reason'] ?? 'other';
						$identityService->reject($user, $admin, $reason);
					}
				} catch (\Exception $e) {
					\Log::error('Identity verification error: ' . $e->getMessage());
				}
				
				$user->refresh();
			}
			
			UserType::where('user_id', $user->id)->delete();
			if (isset($params['types']) && is_array($params['types']) && count($params['types']) > 0) {
				foreach ($params['types'] as $type) {
					UserType::create([
						'user_id' => $user->id,
						'type'    => $type
					]);
				}
			}
			
			$role = Role::findByName($request->get('role'));
			if (isset($role)) {
				$user->syncRoles($role);
				$user->save();
			}
			
			return new UserResource($user);
		}
	}
	
	public function updateProfile(Request $request, User $user)
	{
		$rules = [
			'full_name'     => ['required', 'string', 'max:255'],
			'furigana_name' => ['required', 'string', 'max:255'],
		];
		
		$validator = Validator::make($request->all(), $rules);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		$user->update([
			'email'               => isset($params['email']) ? $params['email'] : $user->email,
			'full_name'           => $params['full_name'],
			'furigana_name'       => $params['furigana_name'],
			'first_name'          => $params['full_name'] ?? $user->first_name,
			'last_name'           => $params['full_name'] ?? $user->first_name,
			'furigana_first_name' => $params['full_name'] ?? $user->first_name,
			'furigana_last_name'  => $params['full_name'] ?? $user->first_name,
			'name'                => $params['full_name'],
			'post_code'           => isset($params['post_code']) ? $params['post_code'] : $user->post_code,
			'city'                => isset($params['address']) ? $params['address'] : $user->city,
			'district'            => isset($params['address2']) ? $params['address2'] : $user->district,
			'address'             => isset($params['address3']) ? $params['address3'] : $user->address,
			'phone_number'        => isset($params['phone_number']) ? $params['phone_number'] : $user->phone_number,
			'mobile_tel'          => isset($params['mobile_tel']) ? $params['mobile_tel'] : $user->mobile_tel,
			'updated_at'          => date('Y-m-d H:i:s'),
		]);
		
		UserType::where('user_id', $user->id)->delete();
		if (isset($params['types']) && is_array($params['types']) && count($params['types']) > 0) {
			foreach ($params['types'] as $type) {
				UserType::create([
					'user_id' => $user->id,
					'type'    => $type
				]);
			}
		}
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updateDetail(Request $request, User $user)
	{
		$rules = [
			'gender'        => ['required'],
			'date_of_birth' => ['required'],
			'height'        => ['required']
		];
		
		$validator = Validator::make($request->all(), $rules);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user->id != auth('api')->user()->id) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		$gender = 2;
		if (in_array($params['gender'], [0, 1, 2])) {
			$gender = $params['gender'];
		}
		
		$user->update([
			'gender'        => $gender,
			'date_of_birth' => $params['date_of_birth'],
			'address2'      => $params['address2'] ?? null,
			'height'        => $params['height'],
			'sleeve'        => $params['sleeve'] ?? null,
			'waist'         => $params['waist'] ?? null,
			'updated_at'    => date('Y-m-d H:i:s')
		]);
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updateEmail(Request $request, User $user)
	{
		$validator = Validator::make($request->all(), [
			'email'        => ['required', 'email', 'max:255'],
			'phone_number' => ['required', 'string', 'max:15'],
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		
		$user->update([
			'email'        => $params['email'],
			'phone_number' => $params['phone_number'],
			'mobile_tel'   => $params['mobile_tel'],
			'updated_at'   => date('Y-m-d H:i:s')
		]);
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updatePassword(Request $request, User $user)
	{
		$validator = Validator::make($request->all(), [
			'current_password' => ['required', 'string', 'min:6', 'max:30'],
			'password'         => ['required', 'string', 'min:6', 'max:30'],
			'confirm_password' => ['same:password'],
			'reminder'         => ['required'],
			'reminder_answer'  => ['required', 'string', 'max:255'],
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		if (!Hash::check($params['current_password'], $user->password)) return response()->json(['status' => 'error', 'message' => __('messages.current_password_incorrect')], 200);
		$user->fill([
			'password'          => Hash::make($params['password']),
			'reminder_question' => $params['reminder'],
			'reminder_answer'   => $params['reminder_answer'],
			'updated_at'        => date('Y-m-d H:i:s')
		])->save();
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updateCertification(Request $request, User $user)
	{
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		// Chặn cập nhật nếu đã approved
		if ($user->identity_status === 'approved') {
			return response()->json(['errors' => ['status' => ['本人確認が完了しているため、書類の変更はできません。']]], 403);
		}
		
		$params = $request->all();
		$type = isset($params['type']) ? (int)$params['type'] : null;
		
		// Validation rules based on type
		// Type 0: Driver's license (requires 2 images: driver_license + insurance_card)
		// Type 1: My Number Card (requires 1 image: number_card)
		if ($type === 0) {
			$validator = Validator::make($request->all(), [
				'type'           => ['required', 'numeric'],
				'driver_license' => ['required', 'string'],
				'insurance_card' => ['required', 'string'],
			]);
		} else if ($type === 1) {
			$validator = Validator::make($request->all(), [
				'type'        => ['required', 'numeric'],
				'number_card' => ['required', 'string'],
			]);
		} else {
			return response()->json(['errors' => ['type' => ['無効なタイプです。']]], 403);
		}
		
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		// Kiểm tra có thay đổi thực sự không (tránh submit lại cùng dữ liệu)
		$hasChanges = false;
		if ($type === 0) {
			$hasChanges = ($params['driver_license'] !== $user->driver_license) ||
				($params['insurance_card'] !== $user->insurance_card);
		} else if ($type === 1) {
			$hasChanges = ($params['number_card'] !== $user->number_card);
		}
		
		if (!$hasChanges) {
			return response()->json(['errors' => ['data' => ['変更内容がありません。新しい画像をアップロードしてください。']]], 403);
		}
		
		$updateData = [];
		if ($type === 0) {
			// Driver's license: front → driver_license, back → insurance_card
			$updateData['driver_license'] = $params['driver_license'];
			$updateData['insurance_card'] = $params['insurance_card'];
		} else if ($type === 1) {
			// My Number Card: front → number_card
			$updateData['number_card'] = $params['number_card'];
		}
		
		if (count($updateData) > 0) {
			$updateData['updated_at'] = date('Y-m-d H:i:s');
			
			// Cập nhật trạng thái xác thực: not_submitted hoặc rejected → pending
			$currentStatus = $user->identity_status;
			if ($currentStatus === 'not_submitted' || $currentStatus === 'rejected' || $currentStatus === null) {
				$updateData['identity_status'] = 'pending';
				$updateData['identity_submitted_at'] = date('Y-m-d H:i:s');
				// Reset rejection reason khi user nộp lại
				$updateData['identity_rejection_reason'] = null;
			}
			
			$user->update($updateData);
			
			return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
		}
		
		return response()->json(['status' => 'error', 'message' => __('messages.data_invalid')], 200);
	}
	
	public function updateAddress(Request $request, User $user)
	{
		$validator = Validator::make($request->all(), [
			'post_code' => ['required', 'string', 'max:255'],
			'city'      => ['required', 'string', 'max:255'],
			'district'  => ['required', 'string', 'max:255'],
			'address'   => ['required', 'string', 'max:255'],
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		$user->update([
			'post_code'  => $params['post_code'],
			'city'       => $params['city'],
			'district'   => $params['district'],
			'address'    => $params['address'],
			'address2'   => $params['address2'],
			'updated_at' => date('Y-m-d H:i:s')
		]);
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updateShippingAddress(Request $request, User $user)
	{
		$validator = Validator::make($request->all(), [
			'shipping_post_code' => ['required', 'string', 'max:255'],
			'shipping_city'      => ['required', 'string', 'max:255'],
			'shipping_district'  => ['required', 'string', 'max:255'],
			'shipping_address'   => ['required', 'string', 'max:255'],
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || ($user->id != auth('api')->user()->id)) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$params = $request->all();
		$user->update([
			'shipping_post_code'  => $params['shipping_post_code'],
			'shipping_city'       => $params['shipping_city'],
			'shipping_district'   => $params['shipping_district'],
			'shipping_address'    => $params['shipping_address'],
			'shipping_address2'   => $params['shipping_address2'],
			'shipping_updated_at' => date('Y-m-d H:i:s')
		]);
		
		return response()->json(['status' => 'success', 'message' => __('messages.updated_successfully')], 200);
	}
	
	public function updateProfileFull(Request $request, User $user)
	{
		if ($user === null) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$rules = [
			'first_name'          => ['required', 'string', 'max:255'],
			'last_name'           => ['required', 'string', 'max:255'],
			'furigana_first_name' => ['required', 'string', 'max:255'],
			'furigana_last_name'  => ['required', 'string', 'max:255'],
			'post_code'           => ['required', 'min:1', 'max:10'],
			'address'             => ['required', 'string', 'max:255'],
			'address2'            => ['required', 'string', 'max:255'],
			'phone_number'        => ['required', 'min:8', 'max:15'],
			'email'               => ['required', 'email'],
			'password'            => ['required', 'string', 'min:6', 'max:30'],
			'confirm_password'    => ['same:password'],
			'gender'              => ['required'],
			'dob_year'            => ['required'],
			'dob_month'           => ['required'],
			'dob_day'             => ['required'],
			'reminder'            => ['required', 'string', 'max:2'],
			'reminder_answer'     => ['required', 'string', 'max:255'],
			'mail_subscribe'      => ['required'],
			'mail_format'         => ['required'],
		];
		
		/*if ($request->get('password') != null && $request->get('password') != '') {
			$rules['password'] = [ 'required', 'string', 'min:6', 'max:30' ];
			$rules['confirm_password'] = ['same:password'];
		}*/
		
		$validator = Validator::make($request->all(), $rules);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$params = $request->all();
		
		$checkEmail = User::where('email', $params['email'])->where('id', '!=', $user->id)->count();
		if ($checkEmail > 0) return response()->json(['data' => ['status' => 'error', 'name' => 'email_exist', 'message' => 'メールは既に存在します。']], 200);
		
		$updateData = [
			'password'            => Hash::make($params['password']),
			'first_name'          => $params['first_name'],
			'last_name'           => $params['last_name'],
			'full_name'           => $params['first_name'] . ' ' . $params['last_name'],
			'furigana_first_name' => $params['furigana_first_name'],
			'furigana_last_name'  => $params['furigana_last_name'],
			'furigana_name'       => $params['furigana_first_name'] . ' ' . $params['furigana_last_name'],
			'post_code'           => $params['post_code'],
			'city'                => $params['address'],
			'address'             => $params['address2'],
			'address2'            => isset($params['address3']) ? $params['address3'] : '',
			'phone_number'        => $params['phone_number'],
			'fax_number'          => $params['fax_number'],
			'career'              => $params['career'],
			'mobile_tel'          => (isset($params['mobile_tel']) && !empty($params['mobile_tel'])) ? $params['mobile_tel'] : null,
			'emg_tel'             => (isset($params['emg_tel']) && !empty($params['emg_tel'])) ? $params['emg_tel'] : null,
			'gender'              => (isset($params['gender']) && $params['gender'] == 0) ? 0 : 1,
			'date_of_birth'       => $params['dob_year'] . '-' . $params['dob_month'] . '-' . $params['dob_day'],
			'reminder_question'   => $params['reminder'],
			'reminder_answer'     => $params['reminder_answer'],
			'email2'              => $params['email2'],
			'email_subscribe'     => $params['mail_subscribe'],
			'email_format'        => $params['mail_format'],
			'updated_at'          => date('Y-m-d H:i:s')
		];
		
		//if ($params['password'] != "") $user->password = Hash::make($params['password']);
		
		if (!$user->isAdmin()) {
			//return response()->json(['error' => 'Admin can not be modified'], 403);
			$updateData['email'] = $params['email'];
		}
		$user->update($updateData);
		
		return response()->json(['data' => ['status' => 'success', 'message' => __('messages.updated_successfully')]], 200);
	}
	
	public function wishlist(Request $request, User $user)
	{
		if ($user === null || $user->id !== auth('api')->user()->id) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$listIds = UserWishlist::where('user_id', auth('api')->user()->id)->pluck('product_id')->toArray();
		$list = Product::isPublished()->whereIn('id', $listIds)->orderBy('id', 'DESC');
		
		return ProductResource::collection($list->paginate($limit));
	}
	
	public function wishlistStore(Request $request, User $user)
	{
		$validator = Validator::make($request->all(), ['id' => ['required']]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		
		if ($user === null || $user->id !== auth('api')->user()->id) {
			return response()->json(['status' => 'error', 'message' => 'User not found'], 200);
		}
		
		$params = $request->all();
		$product = Product::isPublished()->where('id', $params['id'])->first();
		if (!$product) {
			return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
		}
		
		$countItem = UserWishlist::where('user_id', auth('api')->user()->id)->where('product_id', $product->id)->count();
		if ($countItem <= 0) {
			UserWishlist::create([
				'user_id'    => auth('api')->user()->id,
				'product_id' => $product->id,
				'created_at' => date('Y-m-d H:i:s'),
				'updated_at' => date('Y-m-d H:i:s')
			]);
		}
		
		return response()->json(['status' => 'success', 'message' => __('messages.add_product_to_wishlist_success')], 200);
	}
	
	public function wishlistDestroy(User $user, Product $product)
	{
		if ($user === null || $user->id !== auth('api')->user()->id) {
			return response()->json(['status' => 'error', 'message' => 'User not found'], 200);
		}
		
		if ($product === null) {
			return response()->json(['status' => 'error', 'message' => __('messages.product_not_found')], 200);
		}
		
		UserWishlist::where('user_id', auth('api')->user()->id)->where('product_id', $product->id)->delete();
		
		return response()->json(['status' => 'success', 'message' => __('messages.delete_product_from_wishlist_success')], 200);
	}
	
	/**
	 * Update the specified resource in storage.
	 *
	 * @param Request $request
	 * @param User $user
	 * @return UserResource|\Illuminate\Http\JsonResponse
	 */
	public function updatePermissions(Request $request, User $user)
	{
		if ($user === null) {
			return response()->json(['error' => __('messages.user_not_found')], 404);
		}
		
		if ($user->isAdmin()) {
			return response()->json(['error' => __('messages.admin_cannot_be_modified')], 403);
		}
		
		$permissionIds = $request->get('permissions', []);
		$rolePermissionIds = array_map(
			function ($permission) {
				return $permission['id'];
			},
			
			$user->getPermissionsViaRoles()->toArray()
		);
		
		$newPermissionIds = array_diff($permissionIds, $rolePermissionIds);
		$permissions = Permission::allowed()->whereIn('id', $newPermissionIds)->get();
		$user->syncPermissions($permissions);
		return new UserResource($user);
	}
	
	/**
	 * Remove the specified resource from storage.
	 *
	 * @param User $user
	 * @return \Illuminate\Http\Response
	 */
	public function destroy(User $user)
	{
		if ($user->isAdmin()) {
			response()->json(['error' => __('messages.cannot_delete_admin_user')], 403);
		}
		
		try {
			$user->delete();
		} catch (\Exception $ex) {
			response()->json(['error' => $ex->getMessage()], 403);
		}
		
		return response()->json(null, 204);
	}
	
	/**
	 * Get permissions from role
	 *
	 * @param User $user
	 * @return array|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
	 */
	public function permissions(User $user)
	{
		try {
			return new JsonResponse([
				'user' => PermissionResource::collection($user->getDirectPermissions()),
				'role' => PermissionResource::collection($user->getPermissionsViaRoles()),
			]);
		} catch (\Exception $ex) {
			response()->json(['error' => $ex->getMessage()], 403);
		}
	}
	
	/**
	 * @param bool $isNew
	 * @return array
	 */
	private function getValidationRules($isNew = true)
	{
		return [
			'email' => $isNew ? 'required|email|unique:users' : 'required|email',
			'roles' => [
				'required',
				'array'
			],
		];
	}
}
