import { GenerationResponse, ApiError as ApiErrorType, GeneratedImage, PendingTask, GenerationResult } from '../types/api';
import { baseWorkflow } from '../constants/baseWorkflow';
import { prompts } from '../assets/prompts';
import translateService from './translateService';
import { getCurrentUserId, isTelegramWebAppAvailable } from '../constants/user';

const API_BASE_URL = 'https://stickerserver.gymnasticstuff.uk';

/**
 * Нормализует URL изображения, заменяя IP-адрес на домен, если необходимо.
 * Если URL уже содержит домен, оставляет его без изменений.
 * @param url URL изображения
 * @returns Нормализованный URL
 */
export const normalizeImageUrl = (url: string): string => {
  if (!url) return url;
  
  // Если URL уже содержит домен, оставляем его без изменений
  if (url.includes('stickerserver.gymnasticstuff.uk')) {
    return url;
  }
  
  // Проверяем, содержит ли URL IP-адрес (простая проверка на наличие цифр и точек)
  const ipRegex = /\d+\.\d+\.\d+\.\d+/;
  if (ipRegex.test(url)) {
    // Заменяем IP-адрес на домен
    // Извлекаем путь из URL (все, что после IP-адреса и порта, если есть)
    const pathMatch = url.match(/https?:\/\/\d+\.\d+\.\d+\.\d+(:\d+)?(\/.*)/);
    if (pathMatch && pathMatch[2]) {
      return `${API_BASE_URL}${pathMatch[2]}`;
    }
  }
  
  return url;
};

// Маппинг стилей к тегам для определения, какой тег использовать для каждого стиля
const styleToTagMap: Record<string, string> = {
  'chibi': 'image_generation',
  'emotions': 'chibi', // Пока используем chibi для всех стилей
  'realism': 'chibi'
};

class GenerationError extends Error {
  constructor(public details: ApiErrorType['detail']) {
    super('API Error');
    this.name = 'GenerationError';
  }
}

const apiService = {
  // Получение списка задач пользователя в статусе PENDING
  async getUserPendingTasks(userId = getCurrentUserId()): Promise<PendingTask[]> {
    try {
      const response = await fetch(`${API_BASE_URL}/user_pending_tasks/${userId}`, {
        method: 'GET',
        headers: {
          'accept': 'application/json',
        }
      });

      if (!response.ok) {
        throw new Error('Failed to fetch pending tasks');
      }

      return await response.json();
    } catch (error) {
      console.error('Error fetching pending tasks:', error);
      return [];
    }
  },

  // Получение текущей позиции задачи в очереди
  async getTaskPosition(taskId: string): Promise<{task_id: number, status: string, queue_position: number | null}> {
    try {
      const response = await fetch(`${API_BASE_URL}/task_position/${taskId}`, {
        method: 'GET',
        headers: {
          'accept': 'application/json',
        }
      });

      if (!response.ok) {
        throw new Error('Failed to fetch task position');
      }

      return await response.json();
    } catch (error) {
      console.error('Error fetching task position:', error);
      throw error;
    }
  },

  // Расчет примерного времени ожидания в секундах
  calculateEstimatedWaitTime(queuePosition: number): number {
    // Среднее время генерации 13-15 секунд
    const averageGenerationTime = 14; 
    return queuePosition * averageGenerationTime;
  },

  async getGeneratedImages(userId = getCurrentUserId()): Promise<GeneratedImage[]> {
    try {
      const response = await fetch(`${API_BASE_URL}/images_links/${userId}`, {
        method: 'GET',
        headers: {
          'accept': 'application/json',
        }
      });

      if (!response.ok) {
        throw new Error('Failed to fetch images');
      }

      // Получаем массив строк с file_id
      const fileIds = await response.json() as string[];
      
      // Преобразуем массив строк в массив объектов GeneratedImage
      const images = fileIds.map((fileId, index) => ({
        id: index + 1,
        link: fileId,
        prompt_id: '',
        status: 'COMPLETED',
        created_at: new Date().toISOString(),
        sticker_set_id: null,
        url: `${API_BASE_URL}/stickers/proxy/sticker/${encodeURIComponent(fileId)}`
      }));
      
      // Сортируем изображения от новых к старым (по id в обратном порядке)
      return images.sort((a, b) => b.id - a.id);
    } catch (error) {
      console.error('Error fetching images:', error);
      throw new Error('Failed to fetch images');
    }
  },
  
async generateImage(imageData: string, style?: string, promptId?: string, userPrompt?: string): Promise<GenerationResult> {
  try {
    // Создаем копию базового воркфлоу
    const workflow = JSON.parse(JSON.stringify(baseWorkflow));
    
    // Вставляем изображение в base64 формате в узел 563
    workflow['563'].inputs.image = imageData;
    
    // Переменная для хранения использованного промпта
    let usedPrompt = '';
    let translationFailed = false;
    
    // Если указан пользовательский промпт и выбрана кнопка "Свой промпт"
    if (userPrompt && promptId === 'customPrompt') {
      console.log('Переводим пользовательский промпт:', userPrompt);
      
      // Используем новый метод перевода через LLM
      const translationResult = await translateService.translateWithLLM(userPrompt);
      
      if (translationResult.success) {
        // Успешный перевод
        console.log('Переведенный промпт:', translationResult.text);
        workflow['316'].inputs.prompt_1 = translationResult.text;
        usedPrompt = translationResult.text;
      } else {
        // Перевод не удался после всех попыток
        console.error('Не удалось перевести промпт:', translationResult.text);
        translationFailed = true;
        
        // Не продолжаем генерацию, возвращаем ошибку с сообщением
        return {
          translationFailed: true,
          usedPrompt: 'Недопустимый промпт', // Сообщение для пользователя
          errorDetails: translationResult.text // Детали ошибки для отладки
        };
      }
    } 
    // Иначе используем предустановленный промпт (они уже переведены)
    else if (promptId && prompts[promptId]) {
      workflow['316'].inputs.prompt_1 = prompts[promptId];
      usedPrompt = prompts[promptId];
      console.log('Используем предустановленный промпт:', prompts[promptId]);
    }
    
    // Если был сбой перевода, не продолжаем генерацию
    if (translationFailed) {
      return { translationFailed: true };
    }
    
    // Создаем строку JSON для workflow ПОСЛЕ того, как все изменения внесены
    const workflowJson = JSON.stringify(workflow);
    
    // Определяем тег на основе выбранного стиля
    const tag = styleToTagMap[style || 'chibi'] || 'chibi';
    console.log(`Используем тег "${tag}" для стиля "${style || 'chibi'}"`);
    
    // Создаем тело запроса как строку JSON вручную
    const requestBodyJson = `{"tag":"${tag}","user_id":${getCurrentUserId()},"workflow":${workflowJson}}`;
    
    // Сохраняем JSON для отладки только при локальной разработке
    if (!isTelegramWebAppAvailable()) {
      const blob = new Blob([requestBodyJson], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'generation_request.json';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
    
    // Отправляем запрос
    const response = await fetch(`${API_BASE_URL}/generate_image`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: requestBodyJson
    });

    if (!response.ok) {
      const errorData: ApiErrorType = await response.json();
      throw new GenerationError(errorData.detail);
    }

    const result = await response.json() as GenerationResponse;
    
    // Возвращаем результат и использованный промпт
    return {
      result,
      usedPrompt,
      translationFailed: false
    };
    } catch (error) {
      if (error instanceof GenerationError) {
        throw error;
      }
      throw new Error('Failed to generate image');
    }
  }
};

export default apiService;
