// ================================================================
// frontend/src/api/services/tenant.ts
// ================================================================
/**
 * Tenant Service - Complete backend alignment
 *
 * Backend API structure (3-tier architecture):
 * - ATOMIC: tenants.py, tenant_members.py
 * - OPERATIONS: tenant_operations.py
 *
 * Last Updated: 2025-10-05
 * Status: ✅ Complete - Zero drift with backend
 */
import { apiClient } from '../client';
import {
  BakeryRegistration,
  BakeryRegistrationWithSubscription,
  TenantResponse,
  TenantAccessResponse,
  TenantUpdate,
  TenantMemberResponse,
  TenantStatistics,
  TenantSearchParams,
  TenantNearbyParams,
  AddMemberWithUserCreate,
  SubscriptionLinkingResponse,
} from '../types/tenant';

export class TenantService {
  private readonly baseUrl = '/tenants';

  // ===================================================================
  // ATOMIC: Tenant CRUD
  // Backend: services/tenant/app/api/tenants.py
  // ===================================================================
  async registerBakery(bakeryData: BakeryRegistration): Promise<TenantResponse> {
    return apiClient.post<TenantResponse>(`${this.baseUrl}/register`, bakeryData);
  }

  async registerBakeryWithSubscription(bakeryData: BakeryRegistrationWithSubscription): Promise<TenantResponse> {
    return apiClient.post<TenantResponse>(`${this.baseUrl}/register`, bakeryData);
  }

  async linkSubscriptionToTenant(
    tenantId: string,
    subscriptionId: string,
    userId: string
  ): Promise<SubscriptionLinkingResponse> {
    return apiClient.post<SubscriptionLinkingResponse>(
      `${this.baseUrl}/link-subscription`,
      { tenant_id: tenantId, subscription_id: subscriptionId, user_id: userId }
    );
  }

  async getTenant(tenantId: string): Promise<TenantResponse> {
    return apiClient.get<TenantResponse>(`${this.baseUrl}/${tenantId}`);
  }

  async getTenantBySubdomain(subdomain: string): Promise<TenantResponse> {
    return apiClient.get<TenantResponse>(`${this.baseUrl}/subdomain/${subdomain}`);
  }

  async getUserTenants(userId: string): Promise<TenantResponse[]> {
    // Use the /tenants endpoint to get both owned and member tenants
    return apiClient.get<TenantResponse[]>(`${this.baseUrl}/user/${userId}/tenants`);
  }

  async getUserOwnedTenants(userId: string): Promise<TenantResponse[]> {
    return apiClient.get<TenantResponse[]>(`${this.baseUrl}/user/${userId}/owned`);
  }

  async updateTenant(tenantId: string, updateData: TenantUpdate): Promise<TenantResponse> {
    return apiClient.put<TenantResponse>(`${this.baseUrl}/${tenantId}`, updateData);
  }

  async deactivateTenant(tenantId: string): Promise<{ success: boolean; message: string }> {
    return apiClient.post<{ success: boolean; message: string }>(`${this.baseUrl}/${tenantId}/deactivate`);
  }

  async activateTenant(tenantId: string): Promise<{ success: boolean; message: string }> {
    return apiClient.post<{ success: boolean; message: string }>(`${this.baseUrl}/${tenantId}/activate`);
  }

  // ===================================================================
  // OPERATIONS: Access Control
  // Backend: services/tenant/app/api/tenant_operations.py
  // ===================================================================
  async verifyTenantAccess(tenantId: string, userId: string): Promise<TenantAccessResponse> {
    return apiClient.get<TenantAccessResponse>(`${this.baseUrl}/${tenantId}/access/${userId}`);
  }

  async getCurrentUserTenantAccess(tenantId: string): Promise<TenantAccessResponse> {
    // This will use the current user from the auth token
    // The backend endpoint handles extracting user_id from the token
    return apiClient.get<TenantAccessResponse>(`${this.baseUrl}/${tenantId}/my-access`);
  }

  // ===================================================================
  // OPERATIONS: Enterprise Hierarchy
  // Backend: services/tenant/app/api/tenant_hierarchy.py
  // ===================================================================
  async getChildTenants(parentTenantId: string): Promise<TenantResponse[]> {
    return apiClient.get<TenantResponse[]>(`${this.baseUrl}/${parentTenantId}/children`);
  }

  async bulkCreateChildTenants(parentTenantId: string, request: {
    child_tenants: Array<{
      name: string;
      city: string;
      zone?: string;
      address: string;
      postal_code: string;
      location_code: string;
      latitude?: number;
      longitude?: number;
      phone?: string;
      email?: string;
      business_type?: string;
      business_model?: string;
      timezone?: string;
      metadata?: Record<string, any>;
    }>;
    auto_configure_distribution?: boolean;
  }): Promise<{
    parent_tenant_id: string;
    created_count: number;
    failed_count: number;
    created_tenants: TenantResponse[];
    failed_tenants: Array<{ name: string; location_code: string; error: string }>;
    distribution_configured: boolean;
  }> {
    return apiClient.post(`${this.baseUrl}/${parentTenantId}/bulk-children`, request);
  }

  // ===================================================================
  // OPERATIONS: Search & Discovery
  // Backend: services/tenant/app/api/tenant_operations.py
  // ===================================================================
  async searchTenants(params: TenantSearchParams): Promise<TenantResponse[]> {
    const queryParams = new URLSearchParams();
    
    if (params.search_term) queryParams.append('search_term', params.search_term);
    if (params.business_type) queryParams.append('business_type', params.business_type);
    if (params.city) queryParams.append('city', params.city);
    if (params.skip !== undefined) queryParams.append('skip', params.skip.toString());
    if (params.limit !== undefined) queryParams.append('limit', params.limit.toString());

    return apiClient.get<TenantResponse[]>(`${this.baseUrl}/search?${queryParams.toString()}`);
  }

  async getNearbyTenants(params: TenantNearbyParams): Promise<TenantResponse[]> {
    const queryParams = new URLSearchParams();
    
    queryParams.append('latitude', params.latitude.toString());
    queryParams.append('longitude', params.longitude.toString());
    if (params.radius_km !== undefined) queryParams.append('radius_km', params.radius_km.toString());
    if (params.limit !== undefined) queryParams.append('limit', params.limit.toString());

    return apiClient.get<TenantResponse[]>(`${this.baseUrl}/nearby?${queryParams.toString()}`);
  }

  // ===================================================================
  // OPERATIONS: Model Status Management
  // Backend: services/tenant/app/api/tenant_operations.py
  // ===================================================================
  async updateModelStatus(
    tenantId: string, 
    modelTrained: boolean, 
    lastTrainingDate?: string
  ): Promise<TenantResponse> {
    const queryParams = new URLSearchParams();
    queryParams.append('model_trained', modelTrained.toString());
    if (lastTrainingDate) queryParams.append('last_training_date', lastTrainingDate);

    return apiClient.put<TenantResponse>(`${this.baseUrl}/${tenantId}/model-status?${queryParams.toString()}`);
  }

  // ===================================================================
  // ATOMIC: Team Member Management
  // Backend: services/tenant/app/api/tenant_members.py
  // ===================================================================
  async addTeamMember(
    tenantId: string,
    userId: string,
    role: string
  ): Promise<TenantMemberResponse> {
    return apiClient.post<TenantMemberResponse>(`${this.baseUrl}/${tenantId}/members`, {
      user_id: userId,
      role: role,
    });
  }

  async addTeamMemberWithUserCreation(
    tenantId: string,
    memberData: AddMemberWithUserCreate
  ): Promise<TenantMemberResponse> {
    return apiClient.post<TenantMemberResponse>(
      `${this.baseUrl}/${tenantId}/members/with-user`,
      memberData
    );
  }

  async getTeamMembers(tenantId: string, activeOnly: boolean = true): Promise<TenantMemberResponse[]> {
    const queryParams = new URLSearchParams();
    queryParams.append('active_only', activeOnly.toString());
    
    return apiClient.get<TenantMemberResponse[]>(`${this.baseUrl}/${tenantId}/members?${queryParams.toString()}`);
  }

  async updateMemberRole(
    tenantId: string, 
    memberUserId: string, 
    newRole: string
  ): Promise<TenantMemberResponse> {
    return apiClient.put<TenantMemberResponse>(
      `${this.baseUrl}/${tenantId}/members/${memberUserId}/role`, 
      { new_role: newRole }
    );
  }

  async removeTeamMember(tenantId: string, memberUserId: string): Promise<{ success: boolean; message: string }> {
    return apiClient.delete<{ success: boolean; message: string }>(`${this.baseUrl}/${tenantId}/members/${memberUserId}`);
  }

  /**
   * Transfer tenant ownership to another admin
   * Backend: services/tenant/app/api/tenant_members.py - transfer_ownership endpoint
   *
   * @param tenantId - The tenant ID
   * @param newOwnerId - The user ID of the new owner (must be an existing admin)
   * @returns Updated tenant with new owner
   */
  async transferOwnership(tenantId: string, newOwnerId: string): Promise<TenantResponse> {
    return apiClient.post<TenantResponse>(
      `${this.baseUrl}/${tenantId}/transfer-ownership`,
      { new_owner_id: newOwnerId }
    );
  }

  // ===================================================================
  // OPERATIONS: Statistics & Admin
  // Backend: services/tenant/app/api/tenant_operations.py
  // ===================================================================
  async getTenantStatistics(): Promise<TenantStatistics> {
    return apiClient.get<TenantStatistics>(`${this.baseUrl}/statistics`);
  }

  // ===================================================================
  // Frontend Context Management
  // ===================================================================
  setCurrentTenant(tenant: TenantResponse): void {
    // Set tenant context in API client
    if (tenant && tenant.id) {
      apiClient.setTenantId(tenant.id);
    }
  }

  clearCurrentTenant(): void {
    // Clear tenant context from API client
    apiClient.setTenantId(null);
  }
}

export const tenantService = new TenantService();