import SwiftUI
import SharedModels
import SwiftData
import Translation

struct LyricsConfirmationView: View {
    let result: LyricsSearchResult
    let onSave: () -> Void

    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @Environment(\.dismiss) private var dismiss

    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

    @State private var translatedEN = ""
    @State private var isTranslating = true
    @State private var translationError = false
    @State private var translationConfig: TranslationSession.Configuration?

    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                headerSection
                lyricsPreview
                actionButtons
            }
            .padding()
            .adaptiveContainer()
        }
        .navigationTitle("Confirm Lyrics")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear {
            translationConfig = .init(
                source: Locale.Language(identifier: "es"),
                target: Locale.Language(identifier: "en")
            )
        }
        .translationTask(translationConfig) { session in
            await translateLyrics(session: session)
        }
    }

    // MARK: - Sections

    private var headerSection: some View {
        VStack(spacing: 12) {
            if let artURL = result.albumArtURL, let url = URL(string: artURL) {
                AsyncImage(url: url) { image in
                    image.resizable().scaledToFill()
                } placeholder: {
                    RoundedRectangle(cornerRadius: 12)
                        .fill(.fill.quaternary)
                        .overlay {
                            ProgressView()
                        }
                }
                .frame(width: 200, height: 200)
                .clipShape(RoundedRectangle(cornerRadius: 12))
            }

            Text(result.title)
                .font(.title2.weight(.bold))
                .multilineTextAlignment(.center)

            Text(result.artist)
                .font(.subheadline)
                .foregroundStyle(.secondary)
        }
    }

    private var lyricsPreview: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Spanish Lyrics")
                .font(.headline)

            Text(result.lyricsES.prefix(500) + (result.lyricsES.count > 500 ? "\n..." : ""))
                .font(.body)
                .foregroundStyle(.primary)

            Divider()

            HStack {
                Text("English Translation")
                    .font(.headline)
                if isTranslating {
                    ProgressView()
                        .controlSize(.small)
                }
            }

            if translationError {
                Label("Translation unavailable. You can still save with Spanish only.",
                      systemImage: "exclamationmark.triangle")
                    .font(.caption)
                    .foregroundStyle(.orange)
            } else if translatedEN.isEmpty && isTranslating {
                Text("Translating...")
                    .font(.body)
                    .foregroundStyle(.secondary)
            } else {
                Text(translatedEN.prefix(500) + (translatedEN.count > 500 ? "\n..." : ""))
                    .font(.body)
                    .foregroundStyle(.secondary)
            }
        }
        .padding()
        .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))
    }

    private var actionButtons: some View {
        HStack(spacing: 16) {
            Button(role: .cancel) {
                dismiss()
            } label: {
                Text("Cancel")
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 12)
            }
            .buttonStyle(.bordered)

            Button {
                saveSong()
            } label: {
                Text("Save")
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 12)
            }
            .buttonStyle(.borderedProminent)
            .tint(.orange)
            .disabled(isTranslating && translatedEN.isEmpty && !translationError)
        }
    }

    // MARK: - Logic

    private func translateLyrics(session: sending TranslationSession) async {
        await MainActor.run { isTranslating = true }
        let text = result.lyricsES
        let esLines = text.components(separatedBy: "\n")
        print("[LyricsTranslation] Spanish line count: \(esLines.count)")
        print("[LyricsTranslation] Spanish blank lines: \(esLines.filter { $0.trimmingCharacters(in: .whitespaces).isEmpty }.count)")
        print("[LyricsTranslation] First 10 ES lines:")
        for (i, line) in esLines.prefix(10).enumerated() {
            print("  ES[\(i)]: \(line.isEmpty ? "(blank)" : line)")
        }

        do {
            let response = try await session.translate(text)
            let enLines = response.targetText.components(separatedBy: "\n")
            print("[LyricsTranslation] English line count: \(enLines.count)")
            print("[LyricsTranslation] English blank lines: \(enLines.filter { $0.trimmingCharacters(in: .whitespaces).isEmpty }.count)")
            print("[LyricsTranslation] First 10 EN lines:")
            for (i, line) in enLines.prefix(10).enumerated() {
                print("  EN[\(i)]: \(line.isEmpty ? "(blank)" : line)")
            }
            // The Translation framework often inserts a blank line after every
            // translated line. Collapse consecutive blank lines into single blanks,
            // then trim leading/trailing blanks so the EN structure matches the ES.
            let normalized = Self.normalizeTranslationLineBreaks(
                translated: response.targetText,
                originalES: text
            )
            let normalizedLines = normalized.components(separatedBy: "\n")
            print("[LyricsTranslation] After normalization: EN lines \(enLines.count) → \(normalizedLines.count) (target: \(esLines.count))")

            await MainActor.run { translatedEN = normalized }
        } catch {
            print("[LyricsTranslation] Translation error: \(error)")
            await MainActor.run { translationError = true }
        }
        await MainActor.run { isTranslating = false }
    }

    /// Re-align translated line breaks to match the original Spanish structure.
    /// The Translation framework often inserts a blank line after every translated
    /// line. We strip all blanks from the EN output, then re-insert them at the
    /// same positions where the original ES text has blank lines.
    /// Re-align translated line breaks to match the original Spanish structure.
    private static func normalizeTranslationLineBreaks(translated: String, originalES: String) -> String {
        let esLines = originalES.components(separatedBy: "\n")
        let enContentLines = translated.components(separatedBy: "\n")
            .filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty }

        // Walk ES lines. For each blank ES line, insert a blank in the result.
        // For each content ES line, consume the next EN content line.
        var result: [String] = []
        var enIndex = 0
        for esLine in esLines {
            if esLine.trimmingCharacters(in: .whitespaces).isEmpty {
                result.append("")
            } else if enIndex < enContentLines.count {
                result.append(enContentLines[enIndex])
                enIndex += 1
            } else {
                result.append("")
            }
        }

        print("[LyricsNormalize] ES lines: \(esLines.count), EN content: \(enContentLines.count), result: \(result.count), EN consumed: \(enIndex)")
        return result.joined(separator: "\n")
    }

    private func saveSong() {
        let song = SavedSong(
            title: result.title,
            artist: result.artist,
            lyricsES: result.lyricsES,
            lyricsEN: translatedEN,
            albumArtURL: result.albumArtURL ?? "",
            appleMusicURL: result.appleMusicURL ?? ""
        )
        cloudModelContext.insert(song)
        try? cloudModelContext.save()
        onSave()
    }
}
