<?php

namespace App\Http\Controllers\Api\Auth;

use Exception;
use Throwable;
use App\Models\User;
use App\Models\Setting;
use App\Enums\ImageNames;
use App\Services\ImageService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Auth\Events\Registered;
use App\Http\Requests\Auth\UserSaveRequest;
use App\Mail\UserRegistered;
use App\Mail\UserUpdated;

class RegisteredUserController extends Controller
{
    protected $imageService;

    public function __construct(ImageService $imageService)
    {
        $this->imageService = $imageService;
    }

    /**
     * Handle an incoming registration request.
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function save(UserSaveRequest $request): JsonResponse
    {
        $loginUserId = auth()->id();
        try {
            DB::beginTransaction();

            $user = User::updateOrCreate(
                ['id' => $loginUserId],
                [
                    'name' => $request->first_name . ' ' . $request->last_name,
                    'email' => $request->email,
                    'password' => Hash::make($request->password),
                ]
            );
            $user->profile()->updateOrCreate(
                ['id' => $loginUserId],
                [
                    'first_name' => $request->first_name,
                    'last_name' => $request->last_name,
                    'gender' => $request->gender,
                    'phone' => $request->phone,
                    'country' => $request->country,
                    'state' => $request->state,
                    'city' => $request->city,
                    'address' => $request->address,
                    'zip' => $request->zip,
                ]
            );

            if ($request->hasFile('profile_image')) {
                $oldProfileImage = $user->images()->profile()->first();
                if ($oldProfileImage) {
                    $this->imageService->delete($oldProfileImage->id, User::class);
                }
                $profileImage = $this->imageService->upload($request->file('profile_image'), User::class, $user->id, ImageNames::PROFILE->value);
                $user->images()->profile()->save($profileImage);
            }

            if ($request->hasFile('cover_image')) {
                $oldCoverImage = $user->images()->cover()->first();
                if ($oldCoverImage) {
                    $this->imageService->delete($oldCoverImage->id, User::class);
                }
                $coverImage = $this->imageService->upload($request->file('cover_image'), User::class, $user->id, ImageNames::COVER->value);
                $user->images()->cover()->save($coverImage);
            }

            if (!$loginUserId) {
                $settings = Setting::all();
                foreach ($settings as $setting) {
                    $setting->users()->save($user, ['value' => $setting->default_value]);
                }
                Mail::to($user->email)->send(new UserRegistered($user));
            } else {
                Mail::to($user->email)->send(new UserUpdated($user));
            }

            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();

            Log::error(__CLASS__ . '::' . __FUNCTION__ . '[line: ' . __LINE__ . ']Message: ' . $e->getMessage());

            throw new Exception('User saved failed.');
        }

        if (!$loginUserId) {
            event(new Registered($user));

            auth()->login($user);
        }

        return response()->json(['user' => $user]);
    }
}
