import { NextRequest, NextResponse } from 'next/server';

import { adminApiDisabledResponse, isAdminApiEnabled } from '@/lib/runtime/adminApi';
import type { FunnelDefinition, ScreenDefinition, TypographyVariant } from '@/lib/funnel/types';

/**
 * Нормализует TypographyVariant - удаляет объект если text пустой
 */
function normalizeTypography(typography: TypographyVariant | undefined): TypographyVariant | undefined {
  if (!typography) return undefined;
  
  // Если text пустой или только пробелы, удаляем весь объект
  if (!typography.text || typography.text.trim() === '') {
    return undefined;
  }
  
  return typography;
}

/**
 * Нормализует данные воронки перед сохранением в MongoDB
 * Удаляет пустые текстовые поля которые не пройдут валидацию
 */
function normalizeFunnelData(funnelData: FunnelDefinition): FunnelDefinition {
  return {
    ...funnelData,
    screens: funnelData.screens.map((screen): ScreenDefinition => {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const normalizedScreen: any = { ...screen };
      
      // Нормализуем subtitle (опциональное поле)
      if ('subtitle' in normalizedScreen) {
        const normalized = normalizeTypography(normalizedScreen.subtitle);
        if (normalized === undefined) {
          delete normalizedScreen.subtitle;
        } else {
          normalizedScreen.subtitle = normalized;
        }
      }
      
      // Нормализуем description (для info и soulmate экранов)
      if ('description' in normalizedScreen) {
        const normalized = normalizeTypography(normalizedScreen.description);
        if (normalized === undefined) {
          delete normalizedScreen.description;
        } else {
          normalizedScreen.description = normalized;
        }
      }
      
      return normalizedScreen as ScreenDefinition;
    }),
  };
}

// GET /api/funnels - получить список всех воронок
export async function GET(request: NextRequest) {
  if (!isAdminApiEnabled()) {
    return adminApiDisabledResponse();
  }

  try {
    const [{ default: connectMongoDB }, { default: FunnelModel }] = await Promise.all([
      import('@/lib/mongodb'),
      import('@/lib/models/Funnel'),
    ]);

    await connectMongoDB();

    const { searchParams } = new URL(request.url);
    const status = searchParams.get('status');
    const search = searchParams.get('search');
    const limit = parseInt(searchParams.get('limit') || '20');
    const page = parseInt(searchParams.get('page') || '1');
    const sortBy = searchParams.get('sortBy') || 'updatedAt';
    const sortOrder = searchParams.get('sortOrder') || 'desc';

    // Строим фильтр
    const filter: Record<string, unknown> = {};
    
    if (status && ['draft', 'published', 'archived'].includes(status)) {
      filter.status = status;
    }
    
    if (search) {
      filter.$or = [
        { name: { $regex: search, $options: 'i' } },
        { description: { $regex: search, $options: 'i' } },
        { 'funnelData.meta.title': { $regex: search, $options: 'i' } },
        { 'funnelData.meta.description': { $regex: search, $options: 'i' } }
      ];
    }

    // Строим сортировку
    const sort: Record<string, 1 | -1> = {};
    sort[sortBy] = sortOrder === 'desc' ? -1 : 1;

    // Выполняем запрос с пагинацией
    const skip = (page - 1) * limit;
    
    const [funnels, total] = await Promise.all([
      FunnelModel
        .find(filter)
        .select('-funnelData.screens -funnelData.defaultTexts') // Исключаем тяжелые данные, но оставляем meta
        .sort(sort)
        .skip(skip)
        .limit(limit)
        .lean(),
      FunnelModel.countDocuments(filter)
    ]);

    return NextResponse.json({
      funnels,
      pagination: {
        current: page,
        total: Math.ceil(total / limit),
        count: funnels.length,
        totalItems: total
      }
    });

  } catch (error) {
    console.error('GET /api/funnels error:', error);
    return NextResponse.json(
      { error: 'Failed to fetch funnels' },
      { status: 500 }
    );
  }
}

// POST /api/funnels - создать новую воронку
export async function POST(request: NextRequest) {
  if (!isAdminApiEnabled()) {
    return adminApiDisabledResponse();
  }

  try {
    const [
      { default: connectMongoDB },
      { default: FunnelModel },
      { default: FunnelHistoryModel },
    ] = await Promise.all([
      import('@/lib/mongodb'),
      import('@/lib/models/Funnel'),
      import('@/lib/models/FunnelHistory'),
    ]);

    await connectMongoDB();

    const body = await request.json();
    const { name, description, funnelData, status = 'draft' } = body;

    // Валидация
    if (!name || !funnelData) {
      return NextResponse.json(
        { error: 'Name and funnel data are required' },
        { status: 400 }
      );
    }

    if (!funnelData.meta || !funnelData.meta.id || !Array.isArray(funnelData.screens)) {
      return NextResponse.json(
        { error: 'Invalid funnel data structure' },
        { status: 400 }
      );
    }

    // Проверяем уникальность funnelData.meta.id
    const existingFunnel = await FunnelModel.findOne({ 
      'funnelData.meta.id': funnelData.meta.id 
    });
    
    if (existingFunnel) {
      return NextResponse.json(
        { error: 'Funnel with this ID already exists' },
        { status: 409 }
      );
    }

    // Нормализуем данные перед сохранением (удаляем пустые текстовые поля)
    const normalizedData = normalizeFunnelData(funnelData as FunnelDefinition);
    
    // Создаем воронку
    const funnel = new FunnelModel({
      name,
      description,
      funnelData: normalizedData,
      status,
      version: 1,
      usage: {
        totalViews: 0,
        totalCompletions: 0
      }
    });

    const savedFunnel = await funnel.save();

    // Создаем базовую точку в истории
    const sessionId = `create-${Date.now()}`;
    await FunnelHistoryModel.create({
      funnelId: String(savedFunnel._id),
      sessionId,
      funnelSnapshot: normalizedData,
      actionType: 'create',
      sequenceNumber: 0,
      description: 'Воронка создана',
      isBaseline: true
    });

    return NextResponse.json({
      _id: savedFunnel._id,
      name: savedFunnel.name,
      description: savedFunnel.description,
      status: savedFunnel.status,
      version: savedFunnel.version,
      createdAt: savedFunnel.createdAt,
      updatedAt: savedFunnel.updatedAt,
      usage: savedFunnel.usage,
      funnelData: savedFunnel.funnelData
    }, { status: 201 });

  } catch (error) {
    console.error('POST /api/funnels error:', error);
    
    // Обработка ошибок валидации Mongoose
    if (error instanceof Error && error.name === 'ValidationError') {
      const validationError = error as Error & { errors: Record<string, { message: string }> };
      const details = [];
      
      // Собираем все ошибки валидации
      for (const field in validationError.errors) {
        const fieldError = validationError.errors[field];
        details.push(`${field}: ${fieldError.message}`);
      }
      
      return NextResponse.json(
        { 
          error: 'Ошибка валидации данных воронки',
          details: details.join('; ')
        },
        { status: 400 }
      );
    }
    
    if (error instanceof Error && error.message.includes('duplicate key')) {
      return NextResponse.json(
        { error: 'Funnel with this name already exists' },
        { status: 409 }
      );
    }
    
    return NextResponse.json(
      { error: 'Failed to create funnel' },
      { status: 500 }
    );
  }
}
