<?php
/**
 * UserService
 * Handles profile update, 30-day username cooldown, password change, and avatar uploads
 */

require_once __DIR__ . '/../Models/User.php';
require_once __DIR__ . '/../Models/ActivityLog.php';
require_once __DIR__ . '/../Helpers/Validator.php';
require_once __DIR__ . '/../Helpers/Upload.php';
require_once __DIR__ . '/../Helpers/Auth.php';
require_once __DIR__ . '/../Helpers/Language.php';

class UserService {
    private User $userModel;
    private ActivityLog $activityLog;

    public function __construct() {
        $this->userModel = new User();
        $this->activityLog = new ActivityLog();
    }

    /**
     * Update User Profile (Name, Username, Email, Phone)
     */
    public function updateProfile(int $userId, array $data): array {
        $currentUser = $this->userModel->findById($userId);
        if (!$currentUser) {
            return ['success' => false, 'message' => __('error_occurred')];
        }

        $rules = [
            'first_name' => 'required|max:100',
            'last_name' => 'max:100',
        ];

        $updateData = [
            'first_name' => trim($data['first_name']),
            'last_name' => trim($data['last_name'] ?? ''),
        ];

        $newUsername = trim($data['username'] ?? '');
        $newEmail = trim(strtolower($data['email'] ?? ''));
        $newPhone = preg_replace('/[^0-9]/', '', (string)($data['phone'] ?? ''));
        $currentPassword = $data['current_password'] ?? '';

        // Check if username changed
        if ($newUsername !== '' && $newUsername !== $currentUser['username']) {
            // Check 30-day interval rule
            if (!empty($currentUser['username_changed_at'])) {
                $lastChanged = strtotime($currentUser['username_changed_at']);
                $cooldownEnds = $lastChanged + (30 * 86400);
                if (time() < $cooldownEnds) {
                    $nextDate = date('d/m/Y H:i', $cooldownEnds);
                    return [
                        'success' => false,
                        'message' => __('username_cooldown_left', ['date' => $nextDate])
                    ];
                }
            }

            $rules['username'] = "required|username|unique:users,username,{$userId},id";
            $updateData['username'] = $newUsername;
            $updateData['username_changed_at'] = date('Y-m-d H:i:s');
        }

        // Check if Email or Phone changed (Requires current password verification)
        $isSensitiveChange = false;
        if ($newEmail !== '' && $newEmail !== $currentUser['email']) {
            $rules['email'] = "required|email|unique:users,email,{$userId},id";
            $updateData['email'] = $newEmail;
            $isSensitiveChange = true;
        }

        if ($newPhone !== '' && $newPhone !== $currentUser['phone']) {
            $rules['phone'] = "required|phone|unique:users,phone,{$userId},id";
            $updateData['phone'] = $newPhone;
            $isSensitiveChange = true;
        }

        if ($isSensitiveChange) {
            if (empty($currentPassword) || !password_verify($currentPassword, $currentUser['password'])) {
                return ['success' => false, 'message' => __('current_password_incorrect')];
            }
        }

        $validator = Validator::make(array_merge($data, ['phone' => $newPhone]), $rules);
        if (!$validator->validate()) {
            return ['success' => false, 'errors' => $validator->errors()];
        }

        $updateData['updated_at'] = date('Y-m-d H:i:s');
        $this->userModel->update($userId, $updateData);

        Auth::clearCache();
        $this->activityLog->record($userId, 'profile_updated', 'user', $userId, 'User updated profile details');

        return ['success' => true, 'message' => __('profile_updated_success')];
    }

    /**
     * Update User Avatar
     */
    public function updateAvatar(int $userId, array $file): array {
        $currentUser = $this->userModel->findById($userId);
        if (!$currentUser) {
            return ['success' => false, 'message' => __('error_occurred')];
        }

        [$uploaded, $result] = Upload::processAvatar($file, $userId);
        if (!$uploaded) {
            return ['success' => false, 'message' => $result];
        }

        $newFilename = $result;

        // Delete old avatar if existing
        Upload::deleteOldAvatar($currentUser['profile_image']);

        // Update database
        $this->userModel->update($userId, [
            'profile_image' => $newFilename,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        Auth::clearCache();
        $this->activityLog->record($userId, 'avatar_updated', 'user', $userId, 'User updated profile avatar');

        return [
            'success' => true,
            'message' => __('avatar_updated_success'),
            'avatar_url' => Url::asset('/uploads/profiles/' . $newFilename)
        ];
    }

    /**
     * Change User Password
     */
    public function changePassword(int $userId, string $currentPassword, string $newPassword, string $confirmPassword): array {
        $currentUser = $this->userModel->findById($userId);
        if (!$currentUser) {
            return ['success' => false, 'message' => __('error_occurred')];
        }

        $validator = Validator::make([
            'current_password' => $currentPassword,
            'new_password' => $newPassword,
            'confirm_new_password' => $confirmPassword
        ], [
            'current_password' => 'required',
            'new_password' => 'required|min:8',
            'confirm_new_password' => 'required|matches:new_password'
        ]);

        if (!$validator->validate()) {
            return ['success' => false, 'errors' => $validator->errors()];
        }

        if (!password_verify($currentPassword, $currentUser['password'])) {
            return ['success' => false, 'message' => __('current_password_incorrect')];
        }

        $newHash = password_hash($newPassword, PASSWORD_BCRYPT, ['cost' => 12]);

        $this->userModel->update($userId, [
            'password' => $newHash,
            'is_temp_password' => 0,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $this->activityLog->record($userId, 'password_changed', 'user', $userId, 'User changed account password');

        return ['success' => true, 'message' => __('password_changed_success')];
    }
}
