// contacts_interface.h - Contacts interface for Lua sandbox
// Milestone 17: Contact access with granular read/write permissions
#pragma once

#include <string>
#include <vector>
#include <optional>
#include <functional>
#include <mutex>
#include <unordered_map>

struct lua_State;

namespace mosis {

struct Contact {
    int id = 0;                  // Internal ID
    std::string name;            // Display name
    std::string phone;           // Primary phone number
    std::string email;           // Primary email
};

struct QueryOptions {
    std::string search;          // Search string (matches name, phone, email)
    int limit = 50;              // Max results (capped at 100)
    int offset = 0;              // Pagination offset
};

enum class ContactsError {
    None,
    PermissionDenied,
    NotFound,
    InvalidData,
    LimitExceeded
};

class ContactsInterface {
public:
    ContactsInterface(const std::string& app_id);
    ~ContactsInterface();

    // Permission checks
    bool HasReadPermission() const { return m_has_read_permission; }
    void SetReadPermission(bool granted) { m_has_read_permission = granted; }

    bool HasWritePermission() const { return m_has_write_permission; }
    void SetWritePermission(bool granted) { m_has_write_permission = granted; }

    // Query contacts (requires read permission)
    std::vector<Contact> Query(const QueryOptions& options, std::string& error);

    // Get single contact by ID (requires read permission)
    std::optional<Contact> GetById(int id, std::string& error);

    // Add contact (requires write permission)
    int Add(const Contact& contact, std::string& error);

    // Update contact (requires write permission)
    bool Update(const Contact& contact, std::string& error);

    // Delete contact (requires write permission)
    bool Delete(int id, std::string& error);

    // Get total contact count (requires read permission)
    int GetCount(std::string& error);

    // For testing
    void SetMockMode(bool enabled) { m_mock_mode = enabled; }
    bool IsMockMode() const { return m_mock_mode; }

    // Mock mode: set contacts directly
    void SetMockContacts(const std::vector<Contact>& contacts);

    // Clear all mock contacts
    void ClearMockContacts();

private:
    std::string m_app_id;
    bool m_mock_mode = true;
    bool m_has_read_permission = false;
    bool m_has_write_permission = false;
    std::vector<Contact> m_mock_contacts;
    int m_next_id = 1;
    mutable std::mutex m_mutex;

    static constexpr int MAX_RESULTS = 100;

    bool MatchesSearch(const Contact& contact, const std::string& search) const;
};

// Register contacts.* APIs as globals
void RegisterContactsAPI(lua_State* L, ContactsInterface* contacts);

} // namespace mosis
