import SwiftUI

/**
 * Survey Modal — SwiftUI component for displaying and completing surveys.
 * Part of ByteLystPlatformSDK.
 */
@available(iOS 15.0, *)
public struct BLSurveyModal: View {
    @ObservedObject var client: BLSurveyClient
    @State private var survey: BLActiveSurvey?
    @State private var currentQuestionIndex = 0
    @State private var answers: [String: BLSurveyAnswer] = [:]
    @State private var isComplete = false
    @State private var showCompletion = false
    @State private var isPresented = false
    
    // Local state for question answers
    @State private var selectedOption: String?
    @State private var selectedOptions: Set<String> = []
    @State private var ratingValue: Int = 0
    @State private var textAnswer: String = ""
    @State private var rankingOrder: [String] = []
    
    public init(client: BLSurveyClient) {
        self.client = client
    }
    
    public var body: some View {
        EmptyView()
            .sheet(isPresented: $isPresented) {
                surveyContent
            }
            .task {
                await checkForSurvey()
                startPolling()
            }
    }
    
    @ViewBuilder
    private var surveyContent: some View {
        if showCompletion {
            CompletionView(
                survey: survey,
                onDismiss: { dismissSurvey() }
            )
        } else if let survey = survey, currentQuestionIndex < survey.questions.count {
            let question = survey.questions[currentQuestionIndex]
            QuestionView(
                survey: survey,
                question: question,
                questionIndex: currentQuestionIndex,
                totalQuestions: survey.questions.count,
                selectedOption: $selectedOption,
                selectedOptions: $selectedOptions,
                ratingValue: $ratingValue,
                textAnswer: $textAnswer,
                rankingOrder: $rankingOrder,
                onSubmit: { await submitAnswer(question) },
                onSkip: { await skipQuestion() },
                onDismiss: { dismissSurvey() }
            )
        }
    }
    
    private func checkForSurvey() async {
        do {
            if let activeSurvey = try await client.getActiveSurvey() {
                survey = activeSurvey
                if !isPresented {
                    isPresented = true
                }
            }
        } catch {
            // Silently ignore
        }
    }
    
    private func startPolling() {
        client.startPolling(interval: 60) { newSurvey in
            if let newSurvey = newSurvey, self.survey == nil {
                self.survey = newSurvey
                self.isPresented = true
            }
        }
    }
    
    private func submitAnswer(_ question: BLSurveyQuestion) async {
        let answer: BLSurveyAnswer
        
        switch question.type {
        case .singleChoice, .dropdown:
            guard let value = selectedOption else { return }
            answer = .singleChoice(optionId: value)
        case .multipleChoice:
            let values = Array(selectedOptions)
            answer = .multipleChoice(optionIds: values)
        case .rating, .scale:
            answer = .rating(value: ratingValue)
        case .nps:
            answer = .nps(value: ratingValue)
        case .textShort, .textLong:
            answer = .text(value: textAnswer)
        case .ranking:
            answer = .ranking(rankedOptionIds: rankingOrder)
        }
        
        do {
            let response = try await client.submitAnswer(surveyId: survey!.id, questionId: question.id, answer: answer)
            currentQuestionIndex = response.currentQuestionIndex
            answers = response.answers
            resetQuestionState()
            
            if currentQuestionIndex >= survey!.questions.count {
                await completeSurvey()
            }
        } catch {
            // Silently ignore submit errors
        }
    }
    
    private func skipQuestion() async {
        let question = survey!.questions[currentQuestionIndex]
        if !question.required {
            // Skip by advancing without submitting
            currentQuestionIndex += 1
            resetQuestionState()
            
            if currentQuestionIndex >= survey!.questions.count {
                await completeSurvey()
            }
        }
    }
    
    private func completeSurvey() async {
        do {
            let completion = try await client.completeSurvey(surveyId: survey!.id)
            if completion.success {
                isComplete = true
                showCompletion = true
            }
        } catch {
            // Silently ignore
        }
    }
    
    private func dismissSurvey() {
        if let survey = survey {
            Task {
                try? await client.dismissSurvey(surveyId: survey.id)
            }
        }
        isPresented = false
        resetSurvey()
    }
    
    private func resetSurvey() {
        survey = nil
        currentQuestionIndex = 0
        answers = [:]
        isComplete = false
        showCompletion = false
        resetQuestionState()
    }
    
    private func resetQuestionState() {
        selectedOption = nil
        selectedOptions = []
        ratingValue = 0
        textAnswer = ""
        rankingOrder = []
    }
}

@available(iOS 15.0, *)
struct QuestionView: View {
    let survey: BLActiveSurvey
    let question: BLSurveyQuestion
    let questionIndex: Int
    let totalQuestions: Int
    
    @Binding var selectedOption: String?
    @Binding var selectedOptions: Set<String>
    @Binding var ratingValue: Int
    @Binding var textAnswer: String
    @Binding var rankingOrder: [String]
    
    let onSubmit: () async -> Void
    let onSkip: () async -> Void
    let onDismiss: () -> Void
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 24) {
                    // Progress bar
                    ProgressView(value: Double(questionIndex + 1), total: Double(totalQuestions))
                        .padding(.horizontal)
                    
                    Text("Question \(questionIndex + 1) of \(totalQuestions)")
                        .font(.caption)
                        .foregroundColor(.secondary)
                    
                    // Question text
                    VStack(alignment: .leading, spacing: 8) {
                        Text(question.text)
                            .font(.title3.bold())
                        
                        if let description = question.description {
                            Text(description)
                                .font(.subheadline)
                                .foregroundColor(.secondary)
                        }
                        
                        if question.required {
                            Text("Required")
                                .font(.caption)
                                .foregroundColor(.red)
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.horizontal)
                    
                    // Question input based on type
                    questionInput
                    
                    Spacer()
                    
                    // Action buttons
                    VStack(spacing: 12) {
                        Button(action: { Task { await onSubmit() } }) {
                            Text(isLast ? "Complete" : "Next")
                                .font(.headline)
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding()
                                .background(canSubmit ? Color.blue : Color.gray)
                                .cornerRadius(12)
                        }
                        .disabled(!canSubmit)
                        
                        if !question.required {
                            Button(action: { Task { await onSkip() } }) {
                                Text("Skip")
                                    .font(.subheadline)
                                    .foregroundColor(.secondary)
                            }
                        }
                    }
                    .padding(.horizontal)
                }
                .padding(.vertical)
            }
            .navigationTitle(survey.title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Dismiss") {
                        onDismiss()
                    }
                }
            }
        }
    }
    
    private var isLast: Bool {
        questionIndex == totalQuestions - 1
    }
    
    private var canSubmit: Bool {
        if !question.required { return true }
        
        switch question.type {
        case .singleChoice, .dropdown:
            return selectedOption != nil
        case .multipleChoice:
            return !selectedOptions.isEmpty
        case .rating, .scale, .nps:
            return ratingValue > 0
        case .textShort, .textLong:
            return !textAnswer.isEmpty
        case .ranking:
            return rankingOrder.count == (question.options?.count ?? 0)
        }
    }
    
    @ViewBuilder
    private var questionInput: some View {
        switch question.type {
        case .singleChoice, .dropdown:
            SingleChoiceView(
                options: question.options ?? [],
                selected: $selectedOption
            )
        case .multipleChoice:
            MultipleChoiceView(
                options: question.options ?? [],
                selected: $selectedOptions
            )
        case .rating, .scale, .nps:
            RatingView(
                minValue: question.minValue ?? (question.type == .nps ? 0 : 1),
                maxValue: question.maxValue ?? (question.type == .nps ? 10 : 5),
                rating: $ratingValue
            )
        case .textShort, .textLong:
            TextAnswerView(
                text: $textAnswer,
                isLong: question.type == .textLong,
                minLength: question.minLength,
                maxLength: question.maxLength
            )
        case .ranking:
            RankingView(
                options: question.options ?? [],
                order: $rankingOrder
            )
        }
    }
}

// MARK: - Question Type Views

@available(iOS 15.0, *)
struct SingleChoiceView: View {
    let options: [BLSurveyOption]
    @Binding var selected: String?
    
    var body: some View {
        VStack(spacing: 8) {
            ForEach(options) { option in
                Button(action: { selected = option.id }) {
                    HStack {
                        Text(option.emoji ?? "")
                        Text(option.text)
                            .foregroundColor(.primary)
                        Spacer()
                        if selected == option.id {
                            Image(systemName: "checkmark.circle.fill")
                                .foregroundColor(.blue)
                        } else {
                            Image(systemName: "circle")
                                .foregroundColor(.secondary)
                        }
                    }
                    .padding()
                    .background(
                        RoundedRectangle(cornerRadius: 8)
                            .fill(selected == option.id ? Color.blue.opacity(0.1) : Color(.systemGray6))
                    )
                }
            }
        }
        .padding(.horizontal)
    }
}

@available(iOS 15.0, *)
struct MultipleChoiceView: View {
    let options: [BLSurveyOption]
    @Binding var selected: Set<String>
    
    var body: some View {
        VStack(spacing: 8) {
            ForEach(options) { option in
                Button(action: { toggleOption(option.id) }) {
                    HStack {
                        Text(option.emoji ?? "")
                        Text(option.text)
                            .foregroundColor(.primary)
                        Spacer()
                        if selected.contains(option.id) {
                            Image(systemName: "checkmark.square.fill")
                                .foregroundColor(.blue)
                        } else {
                            Image(systemName: "square")
                                .foregroundColor(.secondary)
                        }
                    }
                    .padding()
                    .background(
                        RoundedRectangle(cornerRadius: 8)
                            .fill(selected.contains(option.id) ? Color.blue.opacity(0.1) : Color(.systemGray6))
                    )
                }
            }
        }
        .padding(.horizontal)
    }
    
    private func toggleOption(_ id: String) {
        if selected.contains(id) {
            selected.remove(id)
        } else {
            selected.insert(id)
        }
    }
}

@available(iOS 15.0, *)
struct RatingView: View {
    let minValue: Int
    let maxValue: Int
    @Binding var rating: Int
    
    var body: some View {
        VStack(spacing: 16) {
            HStack(spacing: 8) {
                ForEach(minValue...maxValue, id: \.self) { value in
                    Button(action: { rating = value }) {
                        Text("\(value)")
                            .font(.headline)
                            .frame(width: 44, height: 44)
                            .background(
                                Circle()
                                    .fill(rating == value ? Color.blue : Color(.systemGray5))
                            )
                            .foregroundColor(rating == value ? .white : .primary)
                    }
                }
            }
            
            HStack {
                Text("Low")
                    .font(.caption)
                    .foregroundColor(.secondary)
                Spacer()
                Text("High")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
            .padding(.horizontal, 32)
        }
    }
}

@available(iOS 15.0, *)
struct TextAnswerView: View {
    @Binding var text: String
    let isLong: Bool
    let minLength: Int?
    let maxLength: Int?
    
    var body: some View {
        VStack {
            if isLong {
                TextEditor(text: $text)
                    .frame(minHeight: 120)
                    .padding(8)
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
            } else {
                TextField("Your answer", text: $text)
                    .padding()
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
            }
            
            if let max = maxLength {
                Text("\(text.count)/\(max)")
                    .font(.caption)
                    .foregroundColor(text.count > max ? .red : .secondary)
            }
        }
        .padding(.horizontal)
    }
}

@available(iOS 15.0, *)
struct RankingView: View {
    let options: [BLSurveyOption]
    @Binding var order: [String]
    
    var body: some View {
        VStack(spacing: 8) {
            ForEach(options) { option in
                HStack {
                    Text("\(order.firstIndex(of: option.id).map { "\($0 + 1)" } ?? "-")")
                        .font(.caption)
                        .frame(width: 24, height: 24)
                        .background(
                            Circle()
                                .fill(order.contains(option.id) ? Color.blue : Color(.systemGray5))
                        )
                        .foregroundColor(order.contains(option.id) ? .white : .secondary)
                    
                    Text(option.text)
                    
                    Spacer()
                    
                    HStack(spacing: 4) {
                        Button(action: { moveUp(option.id) }) {
                            Image(systemName: "arrow.up")
                        }
                        .disabled(!canMoveUp(option.id))
                        
                        Button(action: { moveDown(option.id) }) {
                            Image(systemName: "arrow.down")
                        }
                        .disabled(!canMoveDown(option.id))
                        
                        Button(action: { addToRanking(option.id) }) {
                            Image(systemName: "plus")
                        }
                        .disabled(order.contains(option.id))
                    }
                }
                .padding()
                .background(Color(.systemGray6))
                .cornerRadius(8)
            }
        }
        .padding(.horizontal)
    }
    
    private func canMoveUp(_ id: String) -> Bool {
        guard let index = order.firstIndex(of: id), index > 0 else { return false }
        return true
    }
    
    private func canMoveDown(_ id: String) -> Bool {
        guard let index = order.firstIndex(of: id), index < order.count - 1 else { return false }
        return true
    }
    
    private func moveUp(_ id: String) {
        guard let index = order.firstIndex(of: id), index > 0 else { return }
        order.swapAt(index, index - 1)
    }
    
    private func moveDown(_ id: String) {
        guard let index = order.firstIndex(of: id), index < order.count - 1 else { return }
        order.swapAt(index, index + 1)
    }
    
    private func addToRanking(_ id: String) {
        if !order.contains(id) {
            order.append(id)
        }
    }
}

@available(iOS 15.0, *)
struct CompletionView: View {
    let survey: BLActiveSurvey?
    let onDismiss: () -> Void
    
    var body: some View {
        NavigationView {
            VStack(spacing: 24) {
                Image(systemName: "checkmark.circle.fill")
                    .font(.system(size: 64))
                    .foregroundColor(.green)
                
                Text("Thank You!")
                    .font(.title.bold())
                
                Text("Your feedback helps us improve.")
                    .font(.body)
                    .foregroundColor(.secondary)
                    .multilineTextAlignment(.center)
                
                if let incentive = survey?.incentive {
                    HStack {
                        Image(systemName: "gift.fill")
                            .foregroundColor(.green)
                        Text("You've earned \(incentive.amount) \(incentive.type == "pro_days" ? "Pro Days" : "Credits")!")
                            .font(.headline)
                            .foregroundColor(.green)
                    }
                    .padding()
                    .background(Color.green.opacity(0.1))
                    .cornerRadius(12)
                }
                
                Spacer()
                
                Button(action: onDismiss) {
                    Text("Close")
                        .font(.headline)
                        .foregroundColor(.white)
                        .frame(maxWidth: .infinity)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(12)
                }
                .padding(.horizontal)
            }
            .padding()
            .navigationBarHidden(true)
        }
    }
}
