<?php
/**
 * ============================================================================
 * classes/User.php
 * user management class
 * ============================================================================
 */

class User {
    private $db;
    private $table = 'users';
    
    public $id;
    public $phone_number;
    public $password_hash;
    public $full_name;
    public $email;
    public $district;
    public $subcounty;
    public $parish;
    public $village;
    public $language_preference;
    public $profile_picture;
    public $user_type;
    public $is_verified;
    public $is_active;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Register new user
     */
    public function register($data) {
        try {
            // Validate phone number
            $phone = validatePhone($data['phone_number']);
            if (!$phone) {
                return ['success' => false, 'message' => 'Invalid phone number format'];
            }
            
            // Check if phone already exists
            if ($this->phoneExists($phone)) {
                return ['success' => false, 'message' => 'Phone number already registered'];
            }
            
            // Hash password
            $passwordHash = hashPassword($data['password']);
            
            // Insert user
            $sql = "INSERT INTO {$this->table} 
                    (phone_number, password_hash, full_name, district, subcounty, 
                     parish, village, language_preference, user_type) 
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            $stmt = $this->db->prepare($sql);
            $result = $stmt->execute([
                $phone,
                $passwordHash,
                sanitize($data['full_name']),
                sanitize($data['district'] ?? 'Luuka'),
                sanitize($data['subcounty'] ?? ''),
                sanitize($data['parish'] ?? ''),
                sanitize($data['village'] ?? ''),
                $data['language'] ?? 'en',
                $data['user_type'] ?? 'farmer'
            ]);
            
            if ($result) {
                $userId = $this->db->lastInsertId();
                
                // Generate OTP
                $otp = $this->generateOTP($phone);
                
                return [
                    'success' => true, 
                    'message' => 'Registration successful. OTP sent to your phone.',
                    'user_id' => $userId,
                    'otp' => $otp // Remove in production
                ];
            }
            
            return ['success' => false, 'message' => 'Registration failed'];
            
        } catch (PDOException $e) {
            error_log("Registration error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Database error occurred'];
        }
    }
    
    /**
     * Login user
     */
    public function login($phone, $password) {
        try {
            $phone = validatePhone($phone);
            if (!$phone) {
                return ['success' => false, 'message' => 'Invalid phone number'];
            }
            
            $sql = "SELECT * FROM {$this->table} WHERE phone_number = ? AND is_active = 1";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$phone]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$user) {
                return ['success' => false, 'message' => 'Phone number not found'];
            }
            
            if (!verifyPassword($password, $user['password_hash'])) {
                return ['success' => false, 'message' => 'Incorrect password'];
            }
            
            if (!$user['is_verified']) {
                return [
                    'success' => false, 
                    'message' => 'Account not verified. Please verify your phone number.',
                    'requires_verification' => true,
                    'phone' => $phone
                ];
            }
            
            // Update last login
            $this->updateLastLogin($user['id']);
            
            // Set session
            setUserSession($user);
            
            // Log activity
            $this->logActivity($user['id'], 'login', 'User logged in successfully');
            
            return [
                'success' => true, 
                'message' => 'Login successful',
                'user' => $user
            ];
            
        } catch (PDOException $e) {
            error_log("Login error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Login failed'];
        }
    }
    
    /**
     * Generate OTP
     */
    private function generateOTP($phone) {
        $otp = generateOTP(6);
        $expiresAt = date('Y-m-d H:i:s', strtotime('+10 minutes'));
        
        $sql = "INSERT INTO otp_verifications (phone_number, otp_code, expires_at) 
                VALUES (?, ?, ?)";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$phone, $otp, $expiresAt]);
        
        return $otp;
    }
    
    /**
     * Verify OTP
     */
    public function verifyOTP($phone, $otp) {
        try {
            $phone = validatePhone($phone);
            
            $sql = "SELECT * FROM otp_verifications 
                    WHERE phone_number = ? AND otp_code = ? 
                    AND is_verified = 0 AND expires_at > NOW() 
                    ORDER BY created_at DESC LIMIT 1";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$phone, $otp]);
            $otpRecord = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$otpRecord) {
                return ['success' => false, 'message' => 'Invalid or expired OTP'];
            }
            
            // Mark OTP as verified
            $sql = "UPDATE otp_verifications SET is_verified = 1 WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$otpRecord['id']]);
            
            // Mark user as verified
            $sql = "UPDATE {$this->table} SET is_verified = 1 WHERE phone_number = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$phone]);
            
            // Auto login after verification
            $sql = "SELECT * FROM {$this->table} WHERE phone_number = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$phone]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($user) {
                setUserSession($user);
            }
            
            return [
                'success' => true, 
                'message' => 'Phone number verified successfully'
            ];
            
        } catch (PDOException $e) {
            error_log("OTP verification error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Verification failed'];
        }
    }
    
    /**
     * Resend OTP
     */
    public function resendOTP($phone) {
        $phone = validatePhone($phone);
        if (!$phone) {
            return ['success' => false, 'message' => 'Invalid phone number'];
        }
        
        $otp = $this->generateOTP($phone);
        
        return [
            'success' => true, 
            'message' => 'OTP resent successfully',
            'otp' => $otp // Remove in production
        ];
    }
    
    /**
     * Check if phone exists
     */
    private function phoneExists($phone) {
        $sql = "SELECT id FROM {$this->table} WHERE phone_number = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$phone]);
        return $stmt->fetch() !== false;
    }
    
    /**
     * Get user by ID
     */
    public function getUserById($id) {
        $sql = "SELECT * FROM {$this->table} WHERE id = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    /**
     * Update user profile
     */
    public function updateProfile($userId, $data) {
        try {
            $sql = "UPDATE {$this->table} SET 
                    full_name = ?,
                    district = ?,
                    subcounty = ?,
                    parish = ?,
                    village = ?,
                    language_preference = ?,
                    updated_at = CURRENT_TIMESTAMP
                    WHERE id = ?";
            
            $stmt = $this->db->prepare($sql);
            $result = $stmt->execute([
                sanitize($data['full_name']),
                sanitize($data['district']),
                sanitize($data['subcounty']),
                sanitize($data['parish']),
                sanitize($data['village']),
                $data['language_preference'],
                $userId
            ]);
            
            if ($result) {
                return ['success' => true, 'message' => 'Profile updated successfully'];
            }
            
            return ['success' => false, 'message' => 'Update failed'];
            
        } catch (PDOException $e) {
            error_log("Profile update error: " . $e->getMessage());
            return ['success' => false, 'message' => 'Update failed'];
        }
    }
    
    /**
     * Update last login
     */
    private function updateLastLogin($userId) {
        $sql = "UPDATE {$this->table} SET last_login = CURRENT_TIMESTAMP WHERE id = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
    }
    
    /**
     * Log user activity
     */
    public function logActivity($userId, $action, $description = '') {
        $sql = "INSERT INTO activity_log (user_id, action, description, ip_address, user_agent) 
                VALUES (?, ?, ?, ?, ?)";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $userId,
            $action,
            $description,
            $_SERVER['REMOTE_ADDR'] ?? '',
            $_SERVER['HTTP_USER_AGENT'] ?? ''
        ]);
    }
}
?>