// File: src/services/API/TenantService.js

import ApiClient from "./ApiClient";

/**
 * TenantService - Handles Tenant Management API requests
 *
 * Backend API:
 * - POST /api/v1/tenants (Create Tenant)
 * - GET /api/v1/tenants/{id} (Get Tenant by ID)
 * - GET /api/v1/tenants/slug/{slug} (Get Tenant by Slug)
 *
 * Documentation: cloud/maplepress-backend/docs/API.md (lines 416-558)
 *
 * Purpose: Manage tenants (organizations) in the multi-tenant system.
 * Each tenant represents an organization with its own users and resources.
 */

/**
 * Create a new tenant (organization)
 *
 * @param {Object} tenantData - Tenant creation data
 * @param {string} tenantData.name - Tenant/organization name
 * @param {string} tenantData.slug - URL-friendly tenant identifier (lowercase, hyphens only)
 * @returns {Promise<Object>} Created tenant data
 * @throws {Error} If creation fails or validation errors occur
 *
 * Response format (transformed to camelCase):
 * {
 *   id: string,          // Tenant ID (UUID)
 *   name: string,        // Tenant name
 *   slug: string,        // Tenant slug
 *   status: string,      // Tenant status (e.g., "active")
 *   createdAt: Date      // Creation timestamp
 * }
 */
async function createTenant(tenantData) {
  // Validate required fields
  if (!tenantData || typeof tenantData !== "object") {
    throw new Error("Tenant data is required");
  }

  if (!tenantData.name || typeof tenantData.name !== "string") {
    throw new Error("Tenant name is required");
  }

  if (!tenantData.slug || typeof tenantData.slug !== "string") {
    throw new Error("Tenant slug is required");
  }

  // Validate slug format (lowercase, numbers, hyphens only)
  const slugPattern = /^[a-z0-9-]+$/;
  if (!slugPattern.test(tenantData.slug)) {
    throw new Error(
      "Tenant slug must contain only lowercase letters, numbers, and hyphens"
    );
  }

  // Prepare request body (snake_case for backend)
  const requestBody = {
    name: tenantData.name.trim(),
    slug: tenantData.slug.trim().toLowerCase(),
  };

  try {
    // Make authenticated API request
    const response = await ApiClient.post("/api/v1/tenants", requestBody);

    // Transform response to camelCase for frontend
    return {
      id: response.id,
      name: response.name,
      slug: response.slug,
      status: response.status,
      createdAt: new Date(response.created_at),
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Authentication required. Please log in to continue."
      );
    }

    if (message.includes("conflict") || message.includes("409") || message.includes("already exists")) {
      throw new Error(
        "Tenant slug already exists. Please choose a different slug."
      );
    }

    if (message.includes("slug")) {
      throw new Error(
        "Invalid tenant slug. Must contain only lowercase letters, numbers, and hyphens."
      );
    }

    if (message.includes("name")) {
      throw new Error("Invalid tenant name provided.");
    }

    // Generic error
    throw new Error(
      error.message || "Failed to create tenant. Please try again."
    );
  }
}

/**
 * Get tenant by ID
 *
 * @param {string} tenantId - Tenant ID (UUID)
 * @returns {Promise<Object>} Tenant data
 * @throws {Error} If retrieval fails or tenant not found
 *
 * Response format (transformed to camelCase):
 * {
 *   id: string,          // Tenant ID (UUID)
 *   name: string,        // Tenant name
 *   slug: string,        // Tenant slug
 *   status: string,      // Tenant status
 *   createdAt: Date,     // Creation timestamp
 *   updatedAt: Date      // Last update timestamp
 * }
 */
async function getTenantById(tenantId) {
  // Validate input
  if (!tenantId || typeof tenantId !== "string") {
    throw new Error("Tenant ID is required");
  }

  // Basic UUID validation
  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
  if (!uuidPattern.test(tenantId)) {
    throw new Error("Invalid tenant ID format");
  }

  try {
    // Make authenticated GET request
    const response = await ApiClient.get(`/api/v1/tenants/${tenantId}`);

    // Transform response to camelCase for frontend
    return {
      id: response.id,
      name: response.name,
      slug: response.slug,
      status: response.status,
      createdAt: new Date(response.created_at),
      updatedAt: new Date(response.updated_at),
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Authentication required. Please log in to continue."
      );
    }

    if (message.includes("not found") || message.includes("404")) {
      throw new Error("Tenant not found.");
    }

    // Generic error
    throw new Error(
      error.message || "Failed to retrieve tenant. Please try again."
    );
  }
}

/**
 * Get tenant by slug
 *
 * @param {string} slug - Tenant slug (URL-friendly identifier)
 * @returns {Promise<Object>} Tenant data
 * @throws {Error} If retrieval fails or tenant not found
 *
 * Response format (transformed to camelCase):
 * {
 *   id: string,          // Tenant ID (UUID)
 *   name: string,        // Tenant name
 *   slug: string,        // Tenant slug
 *   status: string,      // Tenant status
 *   createdAt: Date,     // Creation timestamp
 *   updatedAt: Date      // Last update timestamp
 * }
 */
async function getTenantBySlug(slug) {
  // Validate input
  if (!slug || typeof slug !== "string") {
    throw new Error("Tenant slug is required");
  }

  const normalizedSlug = slug.trim().toLowerCase();

  if (normalizedSlug.length === 0) {
    throw new Error("Tenant slug cannot be empty");
  }

  try {
    // Make authenticated GET request
    const response = await ApiClient.get(`/api/v1/tenants/slug/${normalizedSlug}`);

    // Transform response to camelCase for frontend
    return {
      id: response.id,
      name: response.name,
      slug: response.slug,
      status: response.status,
      createdAt: new Date(response.created_at),
      updatedAt: new Date(response.updated_at),
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Authentication required. Please log in to continue."
      );
    }

    if (message.includes("not found") || message.includes("404")) {
      throw new Error("Tenant not found.");
    }

    // Generic error
    throw new Error(
      error.message || "Failed to retrieve tenant. Please try again."
    );
  }
}

/**
 * Generate a URL-friendly slug from a tenant name
 * Converts to lowercase, replaces spaces with hyphens, removes special characters
 *
 * @param {string} name - Tenant name
 * @returns {string} Generated slug
 */
function generateSlug(name) {
  if (!name || typeof name !== "string") {
    return "";
  }

  return name
    .trim()
    .toLowerCase()
    .replace(/\s+/g, "-")           // Replace spaces with hyphens
    .replace(/[^a-z0-9-]/g, "")     // Remove non-alphanumeric except hyphens
    .replace(/-+/g, "-")            // Replace multiple hyphens with single
    .replace(/^-|-$/g, "");         // Remove leading/trailing hyphens
}

/**
 * Validate a tenant slug format
 *
 * @param {string} slug - Slug to validate
 * @returns {Object} { valid: boolean, error: string|null }
 */
function validateSlug(slug) {
  if (!slug || typeof slug !== "string") {
    return { valid: false, error: "Slug is required" };
  }

  const trimmedSlug = slug.trim();

  if (trimmedSlug.length === 0) {
    return { valid: false, error: "Slug cannot be empty" };
  }

  if (trimmedSlug.length < 2) {
    return { valid: false, error: "Slug must be at least 2 characters" };
  }

  if (trimmedSlug.length > 50) {
    return { valid: false, error: "Slug must be 50 characters or less" };
  }

  // Check format (lowercase, numbers, hyphens only)
  const slugPattern = /^[a-z0-9-]+$/;
  if (!slugPattern.test(trimmedSlug)) {
    return {
      valid: false,
      error: "Slug must contain only lowercase letters, numbers, and hyphens",
    };
  }

  // Check for leading/trailing hyphens
  if (trimmedSlug.startsWith("-") || trimmedSlug.endsWith("-")) {
    return { valid: false, error: "Slug cannot start or end with a hyphen" };
  }

  // Check for consecutive hyphens
  if (trimmedSlug.includes("--")) {
    return { valid: false, error: "Slug cannot contain consecutive hyphens" };
  }

  return { valid: true, error: null };
}

/**
 * Validate tenant name
 *
 * @param {string} name - Name to validate
 * @returns {Object} { valid: boolean, error: string|null }
 */
function validateName(name) {
  if (!name || typeof name !== "string") {
    return { valid: false, error: "Name is required" };
  }

  const trimmedName = name.trim();

  if (trimmedName.length === 0) {
    return { valid: false, error: "Name cannot be empty" };
  }

  if (trimmedName.length < 2) {
    return { valid: false, error: "Name must be at least 2 characters" };
  }

  if (trimmedName.length > 100) {
    return { valid: false, error: "Name must be 100 characters or less" };
  }

  return { valid: true, error: null };
}

// Export service
const TenantService = {
  createTenant,
  getTenantById,
  getTenantBySlug,
  generateSlug,
  validateSlug,
  validateName,
};

export default TenantService;
