<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

class ProfileController extends Controller
{
    public function show()
    {
        $user = Auth::user();
        return view('user.profile.show', compact('user'));
    }

    public function edit()
    {
        $user = Auth::user();
        return view('user.profile.edit', compact('user'));
    }

    public function editPassword()
    {
        $user = Auth::user();
        return view('user.profile.edit-password', compact('user'));
    }

    private function uploadToPublic($file, string $folder): string
    {
        $dir = public_path('uploads/' . trim($folder, '/'));

        if (!file_exists($dir)) {
            mkdir($dir, 0755, true);
        }

        $filename = Auth::id() . '_' . time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
        $file->move($dir, $filename);

        return 'uploads/' . trim($folder, '/') . '/' . $filename;
    }

    private function saveBase64ToPublic(string $base64, string $folder): ?string
    {
        if (!preg_match('/^data:image\/(\w+);base64,/', $base64, $type)) {
            return null;
        }

        $ext = strtolower($type[1]);

        if (!in_array($ext, ['jpg', 'jpeg', 'png', 'webp'])) {
            return null;
        }

        $data = substr($base64, strpos($base64, ',') + 1);
        $data = base64_decode($data);

        if ($data === false) {
            return null;
        }

        $dir = public_path('uploads/' . trim($folder, '/'));

        if (!file_exists($dir)) {
            mkdir($dir, 0755, true);
        }

        $filename = Auth::id() . '_' . time() . '_' . uniqid() . '.' . $ext;
        file_put_contents($dir . '/' . $filename, $data);

        return 'uploads/' . trim($folder, '/') . '/' . $filename;
    }

    private function deleteFromPublic(?string $path): void
    {
        if (!$path) {
            return;
        }

        $fullPath = public_path(ltrim($path, '/'));

        if (file_exists($fullPath) && is_file($fullPath)) {
            @unlink($fullPath);
        }
    }

    public function update(Request $request)
    {
        $user = Auth::user();

        $request->validate([
            'name'         => ['required','string','max:255'],
            'phone'        => ['required','string','max:30','unique:users,phone,' . $user->id],
            'email'        => ['required','email','max:255','unique:users,email,' . $user->id],
            'photo'        => ['nullable','image','mimes:jpg,jpeg,png,webp','max:4096'],
            'photo_base64' => ['nullable','string'],
        ]);

        $user->name  = $request->name;
        $user->phone = $request->phone;
        $user->email = $request->email;

        if ($request->filled('photo_base64')) {
            $newPath = $this->saveBase64ToPublic($request->photo_base64, 'user_photos');

            if ($newPath) {
                $this->deleteFromPublic($user->photo);
                $user->photo = $newPath;
            }
        } elseif ($request->hasFile('photo')) {
            $newPath = $this->uploadToPublic($request->file('photo'), 'user_photos');
            $this->deleteFromPublic($user->photo);
            $user->photo = $newPath;
        }

        $user->save();

        return redirect()
            ->route('user.profile.show')
            ->with('ok', 'Profile updated successfully.');
    }

    public function updatePassword(Request $request)
    {
        $request->validate([
            'current_password' => ['required'],
            'password'         => ['required','string','min:6','confirmed'],
        ]);

        $user = Auth::user();

        if (!Hash::check($request->current_password, $user->password)) {
            return back()->with('err', 'Current password incorrect.');
        }

        $user->update([
            'password' => Hash::make($request->password),
        ]);

        return redirect()
            ->route('user.profile.password.edit')
            ->with('ok', 'Password updated successfully.');
    }
}