import UIKit

/// Debug-only stress test: generates fake messages with real images to test performance.
@MainActor
enum StressTestGenerator {

    static func generateMessages(count: Int, dialogKey: String) {
        let myKey = SessionManager.shared.currentPublicKey
        guard !myKey.isEmpty else { return }

        // Generate and cache a few real images so MessageImageView shows actual content
        let imageIds = prepareTestImages()

        let now = Int64(Date().timeIntervalSince1970 * 1000)
        let texts = [
            "Привет, как дела?", "Всё отлично 😊", "👍",
            "Посмотри это обновление, новые фичи огонь. Шифрование улучшили и UI переделали полностью.",
            "Отправлю файл", "Окей", "Short", "🎉🎊🥳",
            "Встреча в 3 завтра?", "Давай 👌", "Ну чё как?",
            "Это очень длинное сообщение которое тестирует как приложение обрабатывает большие объёмы текста в одном бабле. Должно переноситься корректно и не вызывать проблем с layout. Производительность должна оставаться плавной даже при нескольких строках текста.",
            "**Bold** и обычный текст", "Лол 😂😂😂", "Сейчас скину",
            "Чё делаешь?", "Работаю", "Пойдём гулять?", "Не могу сегодня",
            "Завтра тогда", "Ладно", "Спокойной ночи 🌙", "Утро ☀️",
            "Кофе?", "Да, давай", "Где?", "Как обычно", "Ок буду через 10",
            "Уже тут", "Иду", "Заказал тебе латте"
        ]

        for i in 0..<count {
            let isOutgoing = i % 3 != 0
            let timestamp = now - Int64((count - i) * 15_000) // 15s apart
            let messageId = "stress_\(UUID().uuidString.prefix(8))"
            let text = texts[i % texts.count]

            var attachments: [MessageAttachment] = []

            // Every 5th message has a photo (20% have images — realistic ratio)
            if i % 5 == 0, !imageIds.isEmpty {
                let imgId = imageIds[i % imageIds.count]
                attachments.append(MessageAttachment(
                    id: imgId,
                    preview: "cached::LKO2:N%2Syay-;jtR*.7oe{$jbIU",
                    blob: "",
                    type: .image
                ))
            }

            // Every 15th message has a file
            if i % 15 == 0 {
                attachments.append(MessageAttachment(
                    id: "file_\(messageId)",
                    preview: "fake_tag::12345::document.pdf",
                    blob: "",
                    type: .file
                ))
            }

            // Some messages with 2-3 photos (collage)
            if i % 20 == 0, imageIds.count >= 3 {
                attachments = (0..<3).map { j in
                    MessageAttachment(
                        id: imageIds[(i + j) % imageIds.count],
                        preview: "cached::LKO2:N%2Syay-;jtR*.7oe{$jbIU",
                        blob: "",
                        type: .image
                    )
                }
            }

            let message = ChatMessage(
                id: messageId,
                fromPublicKey: isOutgoing ? myKey : dialogKey,
                toPublicKey: isOutgoing ? dialogKey : myKey,
                text: attachments.isEmpty ? text : (i % 2 == 0 ? text : ""),
                timestamp: timestamp,
                deliveryStatus: .delivered,
                isRead: true,
                attachments: attachments,
                attachmentPassword: nil
            )

            MessageRepository.shared.insertStressTestMessage(message, dialogKey: dialogKey)
        }

        DialogRepository.shared.ensureDialog(
            opponentKey: dialogKey,
            title: "Stress Test (\(count))",
            username: "stress_test",
            verified: 0,
            myPublicKey: myKey
        )

        print("🧪 StressTest: generated \(count) messages (\(imageIds.count) cached images)")
    }

    // MARK: - Generate real test images and cache them

    /// Creates colored gradient images and saves to AttachmentCache.
    /// Returns array of attachment IDs that have cached images.
    private static func prepareTestImages() -> [String] {
        let colors: [(UIColor, UIColor)] = [
            (.systemBlue, .systemPurple),
            (.systemOrange, .systemRed),
            (.systemGreen, .systemTeal),
            (.systemPink, .systemIndigo),
            (.systemYellow, .systemOrange),
            (.systemCyan, .systemBlue),
        ]

        var ids: [String] = []
        let size = CGSize(width: 400, height: 300)

        for (i, (c1, c2)) in colors.enumerated() {
            let id = "stress_img_\(i)"

            // Check if already cached
            if AttachmentCache.shared.loadImage(forAttachmentId: id) != nil {
                ids.append(id)
                continue
            }

            // Generate gradient image
            let renderer = UIGraphicsImageRenderer(size: size)
            let image = renderer.image { ctx in
                let gradient = CGGradient(
                    colorsSpace: CGColorSpaceCreateDeviceRGB(),
                    colors: [c1.cgColor, c2.cgColor] as CFArray,
                    locations: [0, 1]
                )!
                ctx.cgContext.drawLinearGradient(
                    gradient,
                    start: .zero,
                    end: CGPoint(x: size.width, y: size.height),
                    options: []
                )
                // Draw text label
                let text = "Test \(i + 1)" as NSString
                let attrs: [NSAttributedString.Key: Any] = [
                    .font: UIFont.boldSystemFont(ofSize: 32),
                    .foregroundColor: UIColor.white
                ]
                let textSize = text.size(withAttributes: attrs)
                text.draw(
                    at: CGPoint(
                        x: (size.width - textSize.width) / 2,
                        y: (size.height - textSize.height) / 2
                    ),
                    withAttributes: attrs
                )
            }

            AttachmentCache.shared.saveImage(image, forAttachmentId: id)
            ids.append(id)
        }

        return ids
    }
}
