<?php

namespace App\Libs\Services;

use App\Models\User;
use App\Notifications\ApproveUser;
use App\Notifications\InactiveUser;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;

class UserService
{
    public function createUser($data)
    {
        // if (!empty($data['profileImage'])) {
        //     $tempFileName = $data['profileImage'];
        //     $tempPath = 'temp_image/' . $tempFileName;
        //     $finalPath = 'profile_images/' . $tempFileName;

        //     if (!Storage::disk('public')->exists(dirname($finalPath))) {
        //         Storage::disk('public')->makeDirectory(dirname($finalPath));
        //     }

        //     if (Storage::disk('public')->exists($tempPath)) {
        //         Storage::disk('public')->move($tempPath, $finalPath);
        //     }
        // }

        $user = User::create([
            'first_name'    => $data['firstName'],
            'last_name'     => $data['lastName'],
            'email'         => $data['email'],
            'password'      => Hash::make($data['password']),
            'role'          => $data['role'],
            'company_name'  => $data['companyName'],
            'state'         => $data['state'],
            // 'profile_image' => $tempFileName ?? $tempFileName,
            'phone'         => $data['phone'],
            'fax'           => $data['fax'],
            'address'       => $data['address'],
            'house_no'      => $data['houseNo'],
            'zip'           => $data['zip'],
            'city'          => $data['city'],
            'country'       => $data['country']
        ]);

        return $user;
    }

    public function findById($userId)
    {
        $user = User::find($userId);
        return $user;
    }

    public function updateUserPersonalInfo($data)
    {
        $user = User::find($data['id']);

        if (empty($user)) {
            abort(404);
        }

        $user->first_name = $data['firstName'];
        $user->last_name = $data['lastName'];
        $user->phone = $data['phone'];
        $user->fax = $data['fax'];
        $user->save();

        return $user;
    }

    public function updateUserAddress($data)
    {
        $user = User::find($data['id']);

        if (empty($user)) {
            abort(404);
        }

        $user->address = $data['address'];
        $user->house_no = $data['houseNo'];
        $user->zip = $data['zip'];
        $user->city = $data['city'];
        $user->country = $data['country'];
        $user->save();

        return $user;
    }

    public function updateUserCompany($data)
    {
        $user = User::find($data['id']);

        if (empty($user)) {
            abort(404);
        }

        $user->company_name = $data['companyName'];
        $user->save();

        return $user;
    }

    public function deleteUser($userId)
    {
        $authUser = Auth::user();

        /* if ($authUser->role === "user") {
            return [
                'message' => 'not allowed',
            ];
        } */

        $user = User::find($userId);
        if ($user) {
            $user->delete();
        }

        return [
            'message' => 'success',
        ];
    }

    public function list($data)
    {
        $userId = Auth::id();
        $query = User::where('id', '!=', $userId)
                     ->where('role', '!=', 'super');

        if (!empty($data['filterByState'])) {
            $states = explode(',', $data['filterByState']);
            $states = array_map('trim', $states);
            $query->whereIn('state', $states);
        }

        $orderDir = $data['orderDir'] ? $data['orderDir'] : 'asc';

        switch ($data['orderBy']) {
            case 'company':
                $query->orderBy('company_name', $orderDir);
                break;
            case 'firstName':
                $query->orderBy('first_name', $orderDir);
                break;
            case 'lastName':
                $query->orderBy('last_name', $orderDir);
                break;
            case 'email':
                $query->orderBy('email', $orderDir);
                break;
            default:
                # creation
                $query->orderBy('created_at', $orderDir);
                break;
        }

        if (!empty($data['countOnly'])) {
            $count = $query->count();

            return [
                'count' => $count,
            ];
        } else {
            $perPage = $data['perPage'] ?? 12;
            $page = $data['page'] ?? 1;

            $users = $query->paginate($perPage, ['*'], 'page', $page);

            $paginationData = [
                'currentPage' =>  intval($users->currentPage()),
                'lastPage' => intval($users->lastPage()),
                'perPage' =>  intval($users->perPage()),
                'total' =>  intval($users->total()),
                'count' =>  intval($users->count()),
                'hasMorePages' => $users->hasMorePages(),
                'nextPageUrl' => $users->nextPageUrl(),
                'prevPageUrl' => $users->previousPageUrl(),
            ];

            return [
                'users' => $users,
                'pagination' => $paginationData,
            ];
        }
    }

    public function updateUserState($data)
    {
        $user = User::find($data['id']);

        if (empty($user) && $user->state === 'pendingEmailValidation') {
            return [
                'message' => 'not allowed',
            ];
        }

        if ($data['state'] === 'active') {
            $user->notify(new ApproveUser());
        }

        if ($data['state'] === 'inactive') {
            $user->notify(new InactiveUser());
        }

        $user->state = $data['state'];
        $user->save();
        return $user;
    }

    public function changePassword ($data, $userData)
    {
        if (!Hash::check($data['oldPassword'], $userData->password)) {
            return response()->json(['message' => 'The previous password is incorrect.'], 422);
        }

        $userData->password = Hash::make($data['password']);
        $userData->save();

        return response()->json(['message' => 'Password updated successfully.']);
    }

    public function storeProfileImage ($data, $userData)
    {
        $uniqueName = md5(pathinfo($data['file']->getClientOriginalName(), PATHINFO_FILENAME) . microtime(true));
        $fileName = $uniqueName . '.' . $data['file']->getClientOriginalExtension();
        $data['file']->storeAs('profile_images', $fileName, 'public');

        $fileNameThumb = $uniqueName . '_100x100' . '.' . $data['file']->getClientOriginalExtension();
        $targetFilePath = config("path.internal.media")."/{$fileNameThumb}";
        $originalFilePath = config("path.internal.media")."/{$fileName}";
        $img = Image::make(Storage::path($originalFilePath));
        $width = 100;
        $height = 100;
        $img->fit($width, $height);
        $img->save(Storage::path($targetFilePath), 90);

        $user = User::find($userData->id);
        $user->profile_image = $fileName;
        $user->save();

        return $fileName;
    }

    public function search ($data)
    {
        $userId = Auth::id();
        $query = User::where('id', '!=', $userId)
                     ->where('role', '!=', 'super');

        if (!empty($data['filterByState'])) {
            $states = explode(',', $data['filterByState']);
            $states = array_map('trim', $states);
            $query->whereIn('state', $states);
        }

        if (!empty($data['search'])) {
            $search = $data['search'];
            $query->where(function ($query) use ($search) {
                $query->where('first_name', 'like', "%{$search}%")
                      ->orWhere('last_name', 'like', "%{$search}%")
                      ->orWhere('email', 'like', "%{$search}%")
                      ->orWhere('company_name', 'like', "%{$search}%");
            });
        }

        $orderDir = $data['orderDir'] ? $data['orderDir'] : 'asc';

        switch ($data['orderBy']) {
            case 'company':
                $query->orderBy('company_name', $orderDir);
                break;
            case 'firstName':
                $query->orderBy('first_name', $orderDir);
                break;
            case 'lastName':
                $query->orderBy('last_name', $orderDir);
                break;
            case 'email':
                $query->orderBy('email', $orderDir);
                break;
            default:
                # creation
                $query->orderBy('created_at', $orderDir);
                break;
        }

        $perPage = $data['perPage'] ?? 12;
        $page = $data['page'] ?? 1;

        $users = $query->paginate($perPage, ['*'], 'page', $page);

        $paginationData = [
            'currentPage' =>  intval($users->currentPage()),
            'lastPage' => intval($users->lastPage()),
            'perPage' =>  intval($users->perPage()),
            'total' =>  intval($users->total()),
            'count' =>  intval($users->count()),
            'hasMorePages' => $users->hasMorePages(),
            'nextPageUrl' => $users->nextPageUrl(),
            'prevPageUrl' => $users->previousPageUrl(),
        ];

        return [
            'users' => $users,
            'pagination' => $paginationData,
        ];
    }
}
