// Chat API Service with configurable endpoints
import { mockChatData } from './mockChatData';

export interface User {
  id: string;
  name: string;
  email: string;
  avatar: string;
  online: boolean;
  lastSeen?: string;
}

export interface Message {
  id: string;
  chatId: string;
  senderId: string;
  senderName: string;
  senderAvatar: string;
  content: string;
  timestamp: string;
  isOwn: boolean;
  status: 'sent' | 'delivered' | 'read';
}

export interface Chat {
  id: string;
  name: string;
  type: 'direct' | 'group';
  participants: User[];
  lastMessage?: Message;
  unreadCount: number;
  avatar?: string;
  online?: boolean;
  lastActivity: string;
}

class ChatApiService {
  private baseUrl: string;
  private apiKey: string;
  private useMockData: boolean;

  constructor() {
    // In a real environment, these would come from environment variables
    this.baseUrl = import.meta.env.VITE_CHAT_API_URL || 'http://localhost:3001/api';
    this.apiKey = import.meta.env.VITE_CHAT_API_KEY || '';
    this.useMockData = !this.apiKey || import.meta.env.DEV;
  }

  private async apiCall<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
    if (this.useMockData) {
      // Return mock data
      return this.getMockData(endpoint) as T;
    }

    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
        ...options.headers,
      },
    });

    if (!response.ok) {
      throw new Error(`API call failed: ${response.statusText}`);
    }

    return response.json();
  }

  private getMockData(endpoint: string): any {
    // Simulate API responses with mock data
    const delay = () => new Promise(resolve => setTimeout(resolve, 100 + Math.random() * 500));
    
    return new Promise(async (resolve) => {
      await delay();
      
      if (endpoint.includes('/chats')) {
        resolve(mockChatData.chats);
      } else if (endpoint.includes('/users')) {
        resolve(mockChatData.users);
      } else if (endpoint.includes('/messages')) {
        const chatId = endpoint.split('/')[2];
        resolve(mockChatData.messages.filter(m => m.chatId === chatId));
      } else if (endpoint.includes('/search')) {
        resolve(mockChatData.users);
      } else {
        resolve([]);
      }
    });
  }

  // Get all chats for current user
  async getChats(): Promise<Chat[]> {
    return this.apiCall<Chat[]>('/chats');
  }

  // Get messages for a specific chat
  async getMessages(chatId: string): Promise<Message[]> {
    return this.apiCall<Message[]>(`/chats/${chatId}/messages`);
  }

  // Send a message
  async sendMessage(chatId: string, content: string): Promise<Message> {
    if (this.useMockData) {
      const newMessage: Message = {
        id: Date.now().toString(),
        chatId,
        senderId: 'current-user',
        senderName: 'You',
        senderAvatar: '/api/placeholder/40/40',
        content,
        timestamp: new Date().toLocaleTimeString(),
        isOwn: true,
        status: 'sent'
      };
      mockChatData.messages.push(newMessage);
      return newMessage;
    }

    return this.apiCall<Message>(`/chats/${chatId}/messages`, {
      method: 'POST',
      body: JSON.stringify({ content }),
    });
  }

  // Search users
  async searchUsers(query: string): Promise<User[]> {
    if (this.useMockData) {
      await new Promise(resolve => setTimeout(resolve, 300));
      return mockChatData.users.filter(user => 
        user.name.toLowerCase().includes(query.toLowerCase()) ||
        user.email.toLowerCase().includes(query.toLowerCase())
      );
    }

    return this.apiCall<User[]>(`/users/search?q=${encodeURIComponent(query)}`);
  }

  // Create a new chat
  async createChat(participantIds: string[]): Promise<Chat> {
    if (this.useMockData) {
      const participants = mockChatData.users.filter(user => 
        participantIds.includes(user.id)
      );
      
      const newChat: Chat = {
        id: Date.now().toString(),
        name: participants.length === 1 ? participants[0].name : `Group Chat`,
        type: participants.length === 1 ? 'direct' : 'group',
        participants,
        unreadCount: 0,
        lastActivity: new Date().toISOString(),
        avatar: participants[0]?.avatar,
        online: participants[0]?.online
      };

      mockChatData.chats.push(newChat);
      return newChat;
    }

    return this.apiCall<Chat>('/chats', {
      method: 'POST',
      body: JSON.stringify({ participantIds }),
    });
  }

  // Get online users
  async getOnlineUsers(): Promise<User[]> {
    const users = await this.apiCall<User[]>('/users/online');
    return users.filter(user => user.online);
  }

  // Mark messages as read
  async markAsRead(chatId: string): Promise<void> {
    if (this.useMockData) {
      // Update mock data
      const chat = mockChatData.chats.find(c => c.id === chatId);
      if (chat) {
        chat.unreadCount = 0;
      }
      return;
    }

    await this.apiCall(`/chats/${chatId}/read`, { method: 'POST' });
  }
}

export const chatApi = new ChatApiService();