can you make some changes to the relevant blocks in my code? what i need is for you to replace the function that stops the recording upon silence with the function that stops the transcription and waits for the next phrase. the only time the recording should be completely stopped is when the stop recording button is pressed. this is also the ONLY time the good morning message should appear, (not when a cell is opened and closed) responding to all phrases in between the recording starting and stopping. here is the code:

import UIKit
import AVFoundation
import Speech
import BackgroundTasks

struct SleepTalk: Codable {
    let id: UUID
    var phrase: String
    var interpretation: String?
    var audioURL: URL?
    var date: Date
}

class ViewController: UIViewController {
    
    // MARK: - Properties
    
    private var audioEngine: AVAudioEngine?
        private var audioRecorder: AVAudioRecorder?
        private var audioPlayer: AVAudioPlayer?
        private var speechRecognizer: SFSpeechRecognizer?
        private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
        private var recognitionTask: SFSpeechRecognitionTask?
        private var sleepTalks: [SleepTalk] = [] {
            didSet {
                saveSleepTalks()
            }
        }
    
    private var goodMorningLabel: UILabel?
       private var goodMorningTimer: Timer?
    
    private var nightPhrases: [String] = []
    
    private let tableView = UITableView()
    private let startButton = UIButton(type: .system)
    private let stopButton = UIButton(type: .system)
    private let testButton = UIButton(type: .system)
    private let statusLabel = UILabel()
    private let dateLabel = UILabel()
    
    private var isTestRecording = false
    private var isSleepRecording = false
    private var currentPhraseID: UUID?
    private var backgroundTask: UIBackgroundTaskIdentifier = .invalid
    private var currentSession: [SleepTalk] = []
       private var silenceTimer: Timer?
    private let silenceThreshold: TimeInterval = 5.0
    private var summaryButton: UIButton!
    private var recordingCount = 0
    private var summary: String?

    // MARK: - Lifecycle Methods
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupAudioSession()
        setupSpeechRecognizer()
        registerBackgroundTask()
        loadSleepTalks()
        
        // Additional Debugging
        print("View did load, audioEngine initialized: \(audioEngine != nil)")
    }
        
    private func saveSleepTalks() {
        do {
            let encodedData = try JSONEncoder().encode(sleepTalks)
            UserDefaults.standard.set(encodedData, forKey: "sleepTalks")
            print("Successfully saved sleep talks.")
        } catch {
            print("Error saving sleep talks: \(error)")
        }
    }

    private func loadSleepTalks() {
        if let savedData = UserDefaults.standard.data(forKey: "sleepTalks") {
            do {
                sleepTalks = try JSONDecoder().decode([SleepTalk].self, from: savedData)
                tableView.reloadData()
                print("Successfully loaded sleep talks. Count: \(sleepTalks.count)")
            } catch {
                print("Error loading sleep talks: \(error)")
            }
        } else {
            print("No saved sleep talks found.")
        }
    }

    // MARK: - Setup Methods
    
    private func setupUI() {
           view.backgroundColor = .white
           setupButtons()
           setupStatusLabel()
           setupDateLabel()
           setupTableView()
           setupSummaryButton()
           layoutUI()
       }

  
    
    private func startTestRecording() {
        print("Test recording started")
        startRecording(isTest: true)
    }

    
    
    
    @objc private func toggleTestRecording() {
        if isTestRecording {
            stopRecording()
            testButton.setTitle("Test Recording", for: .normal)
        } else {
            startTestRecording()
            testButton.setTitle("Stop Test", for: .normal)
        }
        isTestRecording.toggle()
    }

       private func updateButtonColors() {
           // Update start button color
           startButton.backgroundColor = isSleepRecording ? .systemBlue : .systemGreen
           startButton.setTitleColor(.white, for: .normal)
           // Update stop button color
           stopButton.backgroundColor = .systemRed
           stopButton.setTitleColor(.white, for: .normal)
           // Update test button color
           testButton.backgroundColor = isTestRecording ? .systemGreen : .systemBlue
           testButton.setTitleColor(.white, for: .normal)
       
        // Ensure color is reset when leaving and returning to a cell
        testButton.addTarget(self, action: #selector(toggleTestRecording), for: .touchUpInside)
        startButton.addTarget(self, action: #selector(startSleepRecording), for: .touchUpInside)
        stopButton.addTarget(self, action: #selector(stopRecording), for: .touchUpInside)
    }


    private func setupStatusLabel() {
        statusLabel.text = "Ready to start"
        statusLabel.font = UIFont.systemFont(ofSize: 16, weight: .regular) // Adjusted font size for clarity
        statusLabel.textAlignment = .center
        statusLabel.textColor = UIColor.darkGray // Subtle color for status label
        statusLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(statusLabel)
    }

    private func setupDateLabel() {
        dateLabel.text = getCurrentDate()
        dateLabel.font = UIFont.systemFont(ofSize: 16, weight: .regular) // Consistent font styling
        dateLabel.textAlignment = .center
        dateLabel.textColor = UIColor.darkGray
        dateLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(dateLabel)
    }

    private func setupTableView() {
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(SleepTalkCell.self, forCellReuseIdentifier: "SleepTalkCell")
        tableView.dataSource = self
        tableView.delegate = self
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 100
        view.addSubview(tableView)
    }

    private func setupSummaryButton() {
        summaryButton = UIButton(type: .system)
        summaryButton.setTitle("View Summary", for: .normal)
        summaryButton.backgroundColor = .systemPurple
        summaryButton.setTitleColor(.white, for: .normal)
        summaryButton.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold) // Adjusted font
        summaryButton.layer.cornerRadius = 8 // Softer corners for consistency
        summaryButton.translatesAutoresizingMaskIntoConstraints = false
        summaryButton.addTarget(self, action: #selector(showSummary), for: .touchUpInside)
        view.addSubview(summaryButton)

        NSLayoutConstraint.activate([
            summaryButton.topAnchor.constraint(equalTo: dateLabel.bottomAnchor, constant: 20),
            summaryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            summaryButton.widthAnchor.constraint(equalToConstant: 150),
            summaryButton.heightAnchor.constraint(equalToConstant: 50)
        ])
    }

    private func layoutUI() {
        NSLayoutConstraint.activate([
            // Start Button
            startButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            startButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            startButton.widthAnchor.constraint(equalTo: stopButton.widthAnchor), // Match width of stop button
            startButton.heightAnchor.constraint(equalToConstant: 50),

            // Stop Button
            stopButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            stopButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            stopButton.widthAnchor.constraint(equalToConstant: 150),
            stopButton.heightAnchor.constraint(equalToConstant: 50),

            // Test Button
            testButton.topAnchor.constraint(equalTo: startButton.bottomAnchor, constant: 20),
            testButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            testButton.widthAnchor.constraint(equalToConstant: 200),
            testButton.heightAnchor.constraint(equalToConstant: 50),

            // Status Label
            statusLabel.topAnchor.constraint(equalTo: testButton.bottomAnchor, constant: 20),
            statusLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            statusLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            statusLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            // Date Label
            dateLabel.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 10),
            dateLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            dateLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            dateLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            // Table View
            tableView.topAnchor.constraint(equalTo: summaryButton.bottomAnchor, constant: 20),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }

    
    private func setupAudioSession() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .allowBluetooth, .defaultToSpeaker])
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print("Failed to set up audio session: \(error)")
        }
    }

    private func setupSpeechRecognizer() {
        speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))
        speechRecognizer?.delegate = self

        SFSpeechRecognizer.requestAuthorization { [weak self] authStatus in
            DispatchQueue.main.async {
                self?.updateUIForSpeechStatus(authStatus)
            }
        }
    }

    private func updateUIForSpeechStatus(_ status: SFSpeechRecognizerAuthorizationStatus) {
        switch status {
        case .authorized:
            statusLabel.text = "Speech recognition authorized"
            startButton.isEnabled = true
        case .denied:
            statusLabel.text = "Speech recognition authorization denied"
            startButton.isEnabled = false
        case .restricted:
            statusLabel.text = "Speech recognition restricted on this device"
            startButton.isEnabled = false
        case .notDetermined:
            statusLabel.text = "Speech recognition not yet authorized"
            startButton.isEnabled = false
        @unknown default:
            statusLabel.text = "Unknown authorization status"
            startButton.isEnabled = false
        }
    }

    // MARK: - Background Task Management
    
    func registerBackgroundTask() {
        BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.yourapp.sleeprecording", using: nil) { task in
            self.handleAppRefresh(task: task as! BGAppRefreshTask)
        }
    }

    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.yourapp.sleeprecording")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) // Fetch no earlier than 15 minutes from now
        
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule app refresh: \(error)")
        }
    }

    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        
        // Start recording in background
        startBackgroundRecording()
        
        task.setTaskCompleted(success: true)
        
        // Add an expiration handler for when the task times out
        task.expirationHandler = {
            // Call the method to stop the background recording if the task expires
            self.stopBackgroundRecording()
            task.setTaskCompleted(success: false)
        }
    }

    private func startBackgroundRecording() {
        if audioEngine == nil {
            startRecording(isTest: false)
        }
    }
    
    

    private func stopBackgroundRecording() {
        if audioEngine != nil {
            stopRecording()
        }
    }
    
    private func handleRecognitionResult(_ result: SFSpeechRecognitionResult?, error: Error?) {
        if let result = result {
            let transcribedText = result.bestTranscription.formattedString
            print("Transcribed Text: \(transcribedText)")
            
            // Only proceed if there's new transcribed text
            if !transcribedText.isEmpty {
                updateOrCreateSleepTalk(text: transcribedText)
                resetSilenceTimer()
            } else {
                print("Received an empty transcription result.")
            }
        }
        
        if let error = error {
            print("Recognition task error: \(error.localizedDescription)")
            // Optionally update status label or handle specific errors
        }
    }

    // Set up the silence detection with a timer to manage transcription only
    private func resetSilenceTimer() {
        silenceTimer?.invalidate() // Reset any previous timers
        silenceTimer = Timer.scheduledTimer(withTimeInterval: silenceThreshold, repeats: false) { [weak self] _ in
            self?.endCurrentPhrase() // Stop transcription but NOT the recording
        }
    }

    // Handles ending the current transcription phrase when silence is detected
    private func endCurrentPhrase() {
        print("Ending current transcription phrase")
        
        // End the current recognition request and task
        recognitionRequest?.endAudio()
        recognitionTask?.cancel()
        recognitionRequest = nil
        recognitionTask = nil
        
        // Remove tap to allow starting a new transcription
        audioEngine?.inputNode.removeTap(onBus: 0)
        
        // Optionally, start a new transcription if recording is still active
        if isSleepRecording || isTestRecording {
            startTranscription()
            print("Started new transcription session after ending phrase")
        }
    }


    private func startTranscription() {
        guard let speechRecognizer = speechRecognizer, speechRecognizer.isAvailable else {
            print("Speech recognizer is unavailable")
            statusLabel.text = "Speech recognizer is unavailable"
            return
        }
        
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        
        guard let recognitionRequest = recognitionRequest else {
            print("Unable to create speech recognition request")
            statusLabel.text = "Unable to create speech recognition request"
            return
        }
        
        recognitionRequest.shouldReportPartialResults = true
        
        let inputNode = audioEngine!.inputNode
        let recordingFormat = inputNode.outputFormat(forBus: 0)
        
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [weak self] buffer, when in
            self?.recognitionRequest?.append(buffer)
        }
        
        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] result, error in
            if let result = result {
                self?.handleRecognitionResult(result, error: error)
            }
            
            if let error = error {
                print("Recognition task error: \(error.localizedDescription)")
                self?.stopRecording()
            }
        }
        
        do {
            try audioEngine!.start()
            print("Audio engine started for transcription")
        } catch {
            print("Audio engine couldn't start for transcription: \(error.localizedDescription)")
            statusLabel.text = "Audio engine start failed"
        }
    }




    private func addToTable(currentPhrase: UUID) {
        let newPhrase = SleepTalk(id: currentPhrase, phrase: "", interpretation: nil, audioURL: nil, date: Date())
        sleepTalks.append(newPhrase)
        tableView.reloadData() // Add a new entry for each phrase
    }


    private func updateUIForRecordingState(isRecording: Bool, isTest: Bool) {
        startButton.isEnabled = !isRecording
        stopButton.isEnabled = isRecording
        isTestRecording = isTest && isRecording
        isSleepRecording = !isTest && isRecording
        statusLabel.text = isRecording ? (isTest ? "Test recording..." : "Recording sleep talk...") : "Recording stopped."
        currentPhraseID = isRecording ? nil : currentPhraseID
    }
    
   
    // Function to update and wrap the good morning message with a 53-character limit
    // The 53-character limit is only enforced in the updateGoodMorningMessage function
    private func updateGoodMorningMessage(with message: String) {
        let truncatedMessage = String(message.prefix(53)) // Limit to 53 characters

        goodMorningLabel?.removeFromSuperview() // Clear previous message
        goodMorningLabel = UILabel()
        goodMorningLabel?.text = truncatedMessage
        goodMorningLabel?.numberOfLines = 0
        goodMorningLabel?.lineBreakMode = .byWordWrapping
        goodMorningLabel?.frame = CGRect(x: 20, y: 50, width: view.frame.width - 40, height: 100)
        goodMorningLabel?.textAlignment = .center
        goodMorningLabel?.backgroundColor = .clear
        goodMorningLabel?.textColor = .black
        view.addSubview(goodMorningLabel!)
    }
    

    private func setupButtons() {
        [startButton, stopButton, testButton].forEach { button in
            button.layer.removeAllAnimations() // Remove any existing animations
            button.layer.cornerRadius = 8
            button.translatesAutoresizingMaskIntoConstraints = false
            button.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
            button.titleLabel?.numberOfLines = 2
            button.titleLabel?.textAlignment = .center
            view.addSubview(button)

            // Manually set static colors
            if button == startButton {
                button.backgroundColor = .systemGreen
            } else if button == stopButton {
                button.backgroundColor = .systemRed
            } else if button == testButton {
                button.backgroundColor = .systemBlue
            }
        }

        startButton.setTitle("Start Sleep Recording", for: .normal)
        startButton.setTitleColor(.white, for: .normal)

        stopButton.setTitle("Stop Recording", for: .normal)
        stopButton.setTitleColor(.white, for: .normal)

        testButton.setTitle("Test Recording", for: .normal)
        testButton.setTitleColor(.white, for: .normal)

        // Add targets for buttons
        startButton.addTarget(self, action: #selector(startSleepRecording), for: .touchUpInside)
        stopButton.addTarget(self, action: #selector(stopRecording), for: .touchUpInside)
        testButton.addTarget(self, action: #selector(toggleTestRecording), for: .touchUpInside)
    }




 
    @objc private func stopRecording() {
        print("Stop recording triggered")
        
        // Stop silence timer
        silenceTimer?.invalidate()
        silenceTimer = nil
        
        // Stop transcription
        recognitionRequest?.endAudio()
        recognitionTask?.cancel()
        recognitionRequest = nil
        recognitionTask = nil
        
        // Stop audio engine
        audioEngine?.stop()
        audioEngine?.inputNode.removeTap(onBus: 0)
        audioEngine = nil
        
        // Stop audio recorder
        audioRecorder?.stop()
        audioRecorder = nil
        
        // Update UI to reflect the stopped state
        updateUIForRecordingState(isRecording: false, isTest: isTestRecording)
        
        // If there is an ongoing phrase, end it
        if currentPhraseID != nil {
            endCurrentPhrase()
        }
        
        // Display the Good Morning message after recording
        if !nightPhrases.isEmpty {
            generateGoodMorningMessage(for: nightPhrases)
        } else {
            // Fallback message if no phrases
            showGoodMorningMessage("Good Morning!")
        }
        
        // Clear phrases after the session
        nightPhrases.removeAll()
    }







    
    

    
    // MARK: - Recording Methods
    
    private func showGoodMorningMessage(_ message: String) {
        print("Displaying Good Morning message: \(message)")
        
        // Remove existing label if any
        goodMorningLabel?.removeFromSuperview()
        
        // Create new label
        goodMorningLabel = UILabel()
        goodMorningLabel?.text = message
        goodMorningLabel?.font = UIFont.boldSystemFont(ofSize: 24)
        goodMorningLabel?.textAlignment = .center
        goodMorningLabel?.numberOfLines = 0
        goodMorningLabel?.textColor = .black
        goodMorningLabel?.backgroundColor = .clear
        goodMorningLabel?.alpha = 0
        goodMorningLabel?.translatesAutoresizingMaskIntoConstraints = false
        
        // Add to view
        if let goodMorningLabel = goodMorningLabel {
            view.addSubview(goodMorningLabel)
            
            NSLayoutConstraint.activate([
                goodMorningLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
                goodMorningLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
                goodMorningLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)
            ])
            
            // Animate UI elements to slide down and show message
            UIView.animate(withDuration: 0.5, animations: {
                self.startButton.transform = CGAffineTransform(translationX: 0, y: 80) // Adjust y as needed
                self.stopButton.transform = CGAffineTransform(translationX: 0, y: 80)
                self.testButton.transform = CGAffineTransform(translationX: 0, y: 80)
                self.summaryButton.transform = CGAffineTransform(translationX: 0, y: 80)
                self.statusLabel.transform = CGAffineTransform(translationX: 0, y: 80)
                self.dateLabel.transform = CGAffineTransform(translationX: 0, y: 80)
                self.tableView.transform = CGAffineTransform(translationX: 0, y: 80)
                goodMorningLabel.alpha = 1.0
            }) { _ in
                // After showing the message, set a timer to hide it after 10 seconds
                Timer.scheduledTimer(withTimeInterval: 10.0, repeats: false) { _ in
                    UIView.animate(withDuration: 0.5, animations: {
                        goodMorningLabel.alpha = 0.0
                        self.startButton.transform = .identity
                        self.stopButton.transform = .identity
                        self.testButton.transform = .identity
                        self.summaryButton.transform = .identity
                        self.statusLabel.transform = .identity
                        self.dateLabel.transform = .identity
                        self.tableView.transform = .identity
                    }) { _ in
                        goodMorningLabel.removeFromSuperview()
                    }
                }
            }
        }
    }







    
    @objc private func startSleepRecording() {
        statusLabel.text = "Will start recording in 30 minutes..."
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) { // 30 minutes delay
            self.startRecording(isTest: false)
            self.scheduleAppRefresh()
        }
    }

    // MARK: - Recording Methods

    private func startRecording(isTest: Bool) {
        print("Starting recording, isTest: \(isTest)")
        
        // Update UI to reflect recording state
        updateUIForRecordingState(isRecording: true, isTest: isTest)
        
        // Initialize AVAudioEngine if not already
        if audioEngine == nil {
            audioEngine = AVAudioEngine()
        }
        
        // Initialize AVAudioRecorder
        let audioFilename = getDocumentsDirectory().appendingPathComponent("\(Date().timeIntervalSince1970).m4a")
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 44100,
            AVNumberOfChannelsKey: 2,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
        ]
        
        do {
            audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
            audioRecorder?.delegate = self
            audioRecorder?.isMeteringEnabled = true
            audioRecorder?.record()
            print("Audio recorder started recording at URL: \(audioFilename)")
        } catch {
            print("Audio recording failed: \(error.localizedDescription)")
            statusLabel.text = "Audio recording failed"
            return
        }
        
        // Start transcription
        startTranscription()
        
        // Schedule silence detection timer
        silenceTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in
            self?.checkForSilence()
        }
        
        print("Recording successfully started")
    }


    private func checkForSilence() {
        guard let audioRecorder = audioRecorder else { return }
        
        audioRecorder.updateMeters()
        let audioLevel = audioRecorder.averagePower(forChannel: 0)
        print("Current Audio Level: \(audioLevel)")
        
        if audioLevel < -40 {  // Silence threshold (adjustable)
            // If not already counting silence, start the timer
            if silenceTimer == nil {
                silenceTimer = Timer.scheduledTimer(withTimeInterval: silenceThreshold, repeats: false) { [weak self] _ in
                    self?.endCurrentPhrase()
                }
                print("Silence detected, starting timer to end phrase")
            }
        } else {
            // Audio is detected, reset silence timer
            if silenceTimer != nil {
                silenceTimer?.invalidate()
                silenceTimer = nil
                print("Audio detected, resetting silence timer")
            }
        }
    }

    
    // MARK: - LLM Integration
    
    private func updateOrCreateSleepTalk(text: String) {
        let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmedText.isEmpty else {
            print("Received empty or whitespace-only phrase. Ignoring.")
            return  // Avoid adding empty phrases
        }
        
        if let currentID = currentPhraseID, let index = sleepTalks.firstIndex(where: { $0.id == currentID }) {
            // Update existing phrase
            sleepTalks[index].phrase = trimmedText
            print("Updated existing SleepTalk with ID: \(currentID)")
        } else {
            // Create new phrase
            let newID = UUID()
            currentPhraseID = newID
            let audioURL = audioRecorder?.url // Save the audio URL
            let newSleepTalk = SleepTalk(id: newID, phrase: trimmedText, interpretation: nil, audioURL: audioURL, date: Date())
            sleepTalks.append(newSleepTalk)
            print("Added new SleepTalk with ID: \(newID) and phrase: \(trimmedText)")
            
            // Also add to nightPhrases
            nightPhrases.append(trimmedText)
        }
        
        DispatchQueue.main.async {
            self.tableView.reloadData()
            print("Table view reloaded. Total sleepTalks: \(self.sleepTalks.count)")
        }
    }
    
    func sendToLLM(text: String, id: UUID) {
        let apiUrl = URL(string: "https://openrouter.ai/api/v1/chat/completions")!
        
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer \(APIKeys.openRouterKey)", forHTTPHeaderField: "Authorization")
        request.addValue("Your-App-Name", forHTTPHeaderField: "HTTP-Referer")

        let prompt = """
        Analyze the following sleep talk phrase and provide two things:
        1. A brief interpretation of the sleep talk. This interpretation does not have to be under 53 characters.
        2. A witty 'Good Morning' message referencing the sleep talk. The message should be under 53 characters long (the brief interpretation of the singular sleep talk phrases can be any length though). When writing a good morning message, do not include anything other than the message, as if it was a text message. Do not include quotation marks either.

        Sleep talk: "\(text)"
        """

        let requestBody: [String: Any] = [
            "model": "openai/gpt-3.5-turbo",
            "messages": [
                ["role": "system", "content": "You are an AI assistant specialized in interpreting sleep talk and generating personalized good morning messages."],
                ["role": "user", "content": prompt]
            ]
        ]

        request.httpBody = try? JSONSerialization.data(withJSONObject: requestBody)

        let task = URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in
            DispatchQueue.main.async {
                if let error = error {
                    print("API request error: \(error)")
                    self?.updateInterpretation(for: id, with: "Error: Unable to analyze")
                    self?.showGoodMorningMessage("Good morning! Hope you had a restful night.")
                    return
                }

                guard let data = data else {
                    print("No data received from API")
                    self?.updateInterpretation(for: id, with: "Error: No data received")
                    self?.showGoodMorningMessage("Good morning! Hope you had a restful night.")
                    return
                }

                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                       let choices = json["choices"] as? [[String: Any]],
                       let firstChoice = choices.first,
                       let message = firstChoice["message"] as? [String: Any],
                       let content = message["content"] as? String {

                        // Split the response into analysis and good morning message
                        let parts = content.split(separator: "\n", maxSplits: 1)
                        let interpretation = parts.first?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "No interpretation available."
                        let goodMorningMessage = parts.last?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "Good morning! Hope you had a restful night."

                        // Update UI with AI-generated results
                        self?.updateInterpretation(for: id, with: interpretation)
                        
                        // Replace animateGoodMorningMessage with showGoodMorningMessage
                        self?.showGoodMorningMessage(goodMorningMessage)
                    } else {
                        self?.updateInterpretation(for: id, with: "Error: Invalid response format")
                        self?.showGoodMorningMessage("Good morning! Hope you had a restful night.")
                    }
                } catch {
                    print("JSON parsing error: \(error)")
                    self?.updateInterpretation(for: id, with: "Error: Unable to parse response")
                    self?.showGoodMorningMessage("Good morning! Hope you had a restful night.")
                }
            }
        }

        task.resume()
    }
    
    
    private func generateGoodMorningMessage(for phrases: [String]) {
        let allPhrases = phrases.joined(separator: "\n")
        let prompt = """
        Based on the following sleep talk phrases from last night, generate a witty and engaging 'Good Morning' message. The message should be under 53 characters long and reference the overall theme or a standout phrase from the night's sleep talk.

        Sleep talk phrases:
        \(allPhrases)
        """
        
        print("Generating Good Morning message with prompt: \(prompt)")
        
        let apiUrl = URL(string: "https://openrouter.ai/api/v1/chat/completions")!
        
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer \(APIKeys.openRouterKey)", forHTTPHeaderField: "Authorization")
        request.addValue("Your-App-Name", forHTTPHeaderField: "HTTP-Referer")
        
        let requestBody: [String: Any] = [
            "model": "openai/gpt-3.5-turbo",
            "messages": [
                ["role": "system", "content": "You are an AI assistant specialized in generating witty good morning messages based on sleep talk."],
                ["role": "user", "content": prompt]
            ]
        ]
        
        request.httpBody = try? JSONSerialization.data(withJSONObject: requestBody)
        
        let task = URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in
            DispatchQueue.main.async {
                if let error = error {
                    print("API request error: \(error)")
                    self?.showGoodMorningMessage("Good morning! Hope you had interesting dreams.")
                    return
                }
                
                guard let data = data else {
                    print("No data received from API")
                    self?.showGoodMorningMessage("Good morning! Your night was full of mysteries.")
                    return
                }
                
                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                       let choices = json["choices"] as? [[String: Any]],
                       let firstChoice = choices.first,
                       let message = firstChoice["message"] as? [String: Any],
                       let content = message["content"] as? String {
                        
                        let goodMorningMessage = content.trimmingCharacters(in: .whitespacesAndNewlines)
                        print("Received Good Morning message: \(goodMorningMessage)")
                        self?.showGoodMorningMessage(goodMorningMessage)
                    } else {
                        print("Invalid response format from API")
                        self?.showGoodMorningMessage("Good morning! Your night was full of untold stories.")
                    }
                } catch {
                    print("JSON parsing error: \(error)")
                    self?.showGoodMorningMessage("Good morning! Your dreams were beyond words.")
                }
            }
        }
        
        task.resume()
    }

    private func updateInterpretation(for id: UUID, with interpretation: String) {
            if let index = sleepTalks.firstIndex(where: { $0.id == id }) {
                sleepTalks[index].interpretation = interpretation
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                    // If DetailViewController is currently presented, update its interpretation label
                    if let detailVC = self.presentedViewController as? DetailViewController {
                        detailVC.updateInterpretation(id: id, interpretation: interpretation)
                    }
                }
            }
        }
    
    

    
    private func incrementRecordingCount() {
        recordingCount += 1
        if recordingCount % 15 == 0 {
            generateSummary()
        }
    }

    private func generateSummary() {
        let allPhrases = sleepTalks.map { $0.phrase }.joined(separator: "\n")
        let prompt = """
        Analyze the following sleep talk phrases and provide a summary:
        \(allPhrases)

        Please provide a summary that includes:
        1. Common themes or topics
        2. Overall emotional state or mood
        3. Any recurring patterns or unusual observations
        4. Potential insights into the speaker's subconscious thoughts
        5. Suggestions for improving sleep quality based on the sleep talk content
        """

        let apiUrl = URL(string: "https://openrouter.ai/api/v1/chat/completions")!
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer \(APIKeys.openRouterKey)", forHTTPHeaderField: "Authorization")
        request.addValue("Your-App-Name", forHTTPHeaderField: "HTTP-Referer")

        let requestBody: [String: Any] = [
            "model": "openai/gpt-3.5-turbo",
            "messages": [
                ["role": "system", "content": "You are an AI assistant specialized in analyzing sleep talk patterns."],
                ["role": "user", "content": prompt]
            ]
        ]

        request.httpBody = try? JSONSerialization.data(withJSONObject: requestBody)

        let task = URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in
            DispatchQueue.main.async {
                if let error = error {
                    print("API request error: \(error)")
                    self?.summary = "Error: Unable to generate summary"
                    return
                }

                guard let data = data else {
                    print("No data received from API")
                    self?.summary = "Error: No data received"
                    return
                }

                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                       let choices = json["choices"] as? [[String: Any]],
                       let firstChoice = choices.first,
                       let message = firstChoice["message"] as? [String: Any],
                       let summaryText = message["content"] as? String {
                        self?.summary = summaryText
                    } else {
                        self?.summary = "Error: Invalid response format"
                    }
                } catch {
                    print("JSON parsing error: \(error)")
                    self?.summary = "Error: Unable to parse response"
                }
            }
        }

        task.resume()
    }

    func deleteSleepTalk(id: UUID) {
        if let index = sleepTalks.firstIndex(where: { $0.id == id }) {
            sleepTalks.remove(at: index)
            // Reload the table view to reflect the deletion
            tableView.reloadData()
        } else {
            print("Unable to delete: No sleep talk entry found with the given ID.")
        }
    }
    
    @objc private func showSummary() {
        let summaryVC = SummaryViewController(summary: summary ?? "No summary available yet.")
        let navController = UINavigationController(rootViewController: summaryVC)
        present(navController, animated: true, completion: nil)
    }
        // MARK: - Helper Methods
        
        private func getDocumentsDirectory() -> URL {
            FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        }
        
        private func getCurrentDate() -> String {
            let dateFormatter = DateFormatter()
            dateFormatter.dateStyle = .medium
            dateFormatter.timeStyle = .short
            return dateFormatter.string(from: Date())
        }
}

    // MARK: - UITableViewDataSource & UITableViewDelegate

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Number of sleepTalks: \(sleepTalks.count)")
        return sleepTalks.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "SleepTalkCell", for: indexPath) as? SleepTalkCell else {
            print("Unable to dequeue SleepTalkCell for row \(indexPath.row)")
            fatalError("Unable to dequeue SleepTalkCell")
        }
        
        let sleepTalk = sleepTalks[indexPath.row]
        cell.configure(with: sleepTalk)
        cell.playButton.tag = indexPath.row
        cell.playButton.addTarget(self, action: #selector(playAudio), for: .touchUpInside)
        
        print("Configured cell for row \(indexPath.row) with phrase: \(sleepTalk.phrase)")
        
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let sleepTalk = sleepTalks[indexPath.row]
        let detailVC = DetailViewController(sleepTalk: sleepTalk)
        let navController = UINavigationController(rootViewController: detailVC)
        present(navController, animated: true, completion: nil)
        tableView.deselectRow(at: indexPath, animated: true)
        print("Selected row \(indexPath.row) with phrase: \(sleepTalk.phrase)")
    }
    
    @objc func playAudio(sender: UIButton) {
        let index = sender.tag
        guard index >= 0 && index < sleepTalks.count else {
            print("Invalid index \(index) for audio playback.")
            return
        }
        
        if let audioURL = sleepTalks[index].audioURL {
            print("Attempting to play audio file at URL: \(audioURL)")
            if FileManager.default.fileExists(atPath: audioURL.path) {
                do {
                    audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
                    print("Audio player initialized with file: \(audioURL.lastPathComponent)")
                    audioPlayer?.play()
                    if let audioPlayer = audioPlayer, audioPlayer.isPlaying {
                        print("Audio playback started successfully for file: \(audioURL.lastPathComponent)")
                    } else {
                        print("Audio playback failed to start for file: \(audioURL.lastPathComponent)")
                    }
                } catch {
                    print("Failed to play audio: \(error.localizedDescription)")
                }
            } else {
                print("Audio file does not exist at path: \(audioURL.path)")
            }
        } else {
            print("No audio file URL available for row \(index)")
        }
    }
}

    // MARK: - SFSpeechRecognizerDelegate



extension ViewController: SFSpeechRecognizerDelegate {
    func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
        startButton.isEnabled = available
        statusLabel.text = available ? "Speech recognizer is available" : "Speech recognizer is not available"
        if !available {
            print("Speech recognizer is currently unavailable.")
        }
    }

    func startSpeechRecognition(audioURL: URL) {
        if FileManager.default.fileExists(atPath: audioURL.path) {
            let recognitionRequest = SFSpeechURLRecognitionRequest(url: audioURL)
            speechRecognizer?.recognitionTask(with: recognitionRequest) { result, error in
                if let error = error {
                    print("Speech recognition failed: \(error.localizedDescription)")
                } else if let result = result {
                    print("Speech recognition result: \(result.bestTranscription.formattedString)")
                }
            }
        } else {
            print("Audio file does not exist at path: \(audioURL.path)")
        }
    }
}

    // MARK: - AVAudioRecorderDelegate

    extension ViewController: AVAudioRecorderDelegate {
        func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
            if !flag {
                stopRecording()
            }
        }
    }

    // MARK: - SleepTalkCell

class SleepTalkCell: UITableViewCell {
    private let phraseLabel = UILabel()
    private let dateLabel = UILabel()
    let playButton = UIButton(type: .system)
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupUI()
        print("SleepTalkCell initialized")
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // Inside SleepTalkCell class
    private func setupUI() {
        [phraseLabel, dateLabel, playButton].forEach {
            contentView.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
        }
        
        phraseLabel.numberOfLines = 0
        phraseLabel.font = UIFont.systemFont(ofSize: 16)
        
        dateLabel.font = UIFont.systemFont(ofSize: 12)
        dateLabel.textColor = .gray
        
        playButton.setTitle("Play", for: .normal)
        playButton.setTitleColor(.white, for: .normal)
        playButton.backgroundColor = .systemBlue
        playButton.layer.cornerRadius = 8
        playButton.clipsToBounds = true
        
        NSLayoutConstraint.activate([
            phraseLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
            phraseLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            phraseLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            
            dateLabel.topAnchor.constraint(equalTo: phraseLabel.bottomAnchor, constant: 8),
            dateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            dateLabel.trailingAnchor.constraint(equalTo: playButton.leadingAnchor, constant: -8),
            dateLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
            
            playButton.centerYAnchor.constraint(equalTo: dateLabel.centerYAnchor),
            playButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            playButton.widthAnchor.constraint(equalToConstant: 60),
            playButton.heightAnchor.constraint(equalToConstant: 30)
        ])
    }

    func configure(with sleepTalk: SleepTalk) {
        phraseLabel.text = sleepTalk.phrase
        dateLabel.text = DateFormatter.localizedString(from: sleepTalk.date, dateStyle: .medium, timeStyle: .short)
        
        if let audioURL = sleepTalk.audioURL {
            if FileManager.default.fileExists(atPath: audioURL.path) {
                print("Audio file exists for SleepTalk ID: \(sleepTalk.id)")
            } else {
                print("Audio file is missing for SleepTalk ID: \(sleepTalk.id) at path: \(audioURL.path)")
            }
        } else {
            print("No audioURL for SleepTalk ID: \(sleepTalk.id)")
        }
    }
}
    
    private func startButtonColorFluctuation(for button: UIButton, baseColor: UIColor) {
        let animation = CAKeyframeAnimation(keyPath: "backgroundColor")
        animation.values = [
            baseColor.cgColor,
            baseColor.withAlphaComponent(0.8).cgColor,
            baseColor.withAlphaComponent(0.6).cgColor,
            baseColor.withAlphaComponent(0.8).cgColor,
            baseColor.cgColor
        ]
        animation.keyTimes = [0, 0.25, 0.5, 0.75, 1]
        animation.duration = 2.0
        animation.repeatCount = .infinity
        button.layer.add(animation, forKey: "backgroundColorAnimation")
    }

    // MARK: - DetailViewController

// MARK: - DetailViewController

class DetailViewController: UIViewController {
    var sleepTalk: SleepTalk
    
    private let phraseLabel = UILabel()
    private let interpretationLabel = UILabel()
    private let dateLabel = UILabel()
    private let playButton = UIButton(type: .system)
    private let deleteButton = UIButton(type: .system)
    private var audioPlayer: AVAudioPlayer?

    init(sleepTalk: SleepTalk) {
        self.sleepTalk = sleepTalk
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupUI()
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(dismissVC))
    }
    
    private func startHueFluctuation(for button: UIButton, baseColor: UIColor, hueColors: [UIColor]) {
        let smoothHueColors = hueColors + [hueColors.first!] // Ensure a complete cycle back to the start color

        // Create a CAKeyframeAnimation for the background color
        let animation = CAKeyframeAnimation(keyPath: "backgroundColor")
        animation.values = smoothHueColors.map { $0.cgColor }
        animation.keyTimes = Array(0..<smoothHueColors.count).map { NSNumber(value: Double($0) / Double(smoothHueColors.count - 1)) }
        
        animation.duration = 3.0 // Adjust for smoothness
        animation.repeatCount = .infinity
        button.layer.add(animation, forKey: "hueFluctuation")
    }

   

    
    // Inside DetailViewController class
    private func setupUI() {
        [phraseLabel, interpretationLabel, dateLabel, playButton, deleteButton].forEach {
            view.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
        }
        
        phraseLabel.text = "Phrase: \(sleepTalk.phrase)"
        phraseLabel.numberOfLines = 0

        updateInterpretationLabel()
        
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .short
        dateLabel.text = dateFormatter.string(from: sleepTalk.date)
        
        playButton.setTitle("Play Audio", for: .normal)
        playButton.setTitleColor(.white, for: .normal)
        playButton.backgroundColor = .systemBlue
        playButton.layer.cornerRadius = 10
        playButton.clipsToBounds = true
        playButton.addTarget(self, action: #selector(playButtonTapped), for: .touchUpInside)
        
        deleteButton.setTitle("Delete", for: .normal)
        deleteButton.setTitleColor(.white, for: .normal)
        deleteButton.backgroundColor = .systemRed
        deleteButton.layer.cornerRadius = 10
        deleteButton.clipsToBounds = true
        deleteButton.addTarget(self, action: #selector(deleteButtonTapped), for: .touchUpInside)
        
        NSLayoutConstraint.activate([
            phraseLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            phraseLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            phraseLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),

            interpretationLabel.topAnchor.constraint(equalTo: phraseLabel.bottomAnchor, constant: 20),
            interpretationLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            interpretationLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),

            dateLabel.topAnchor.constraint(equalTo: interpretationLabel.bottomAnchor, constant: 20),
            dateLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            dateLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),

            playButton.topAnchor.constraint(equalTo: dateLabel.bottomAnchor, constant: 20),
            playButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            playButton.widthAnchor.constraint(equalToConstant: 100),
            playButton.heightAnchor.constraint(equalToConstant: 50),

            deleteButton.topAnchor.constraint(equalTo: playButton.bottomAnchor, constant: 20),
            deleteButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            deleteButton.widthAnchor.constraint(equalToConstant: 100),
            deleteButton.heightAnchor.constraint(equalToConstant: 50)
        ])
        
        startHueFluctuation(for: playButton, baseColor: .systemBlue, hueColors: [.systemBlue, .systemCyan, .systemTeal, .systemBlue])
        startHueFluctuation(for: deleteButton, baseColor: .systemRed, hueColors: [.systemRed, .systemPink, .systemOrange, .systemRed])
    }
    
    
    private func updateInterpretationLabel() {
        interpretationLabel.text = "Interpretation: \(sleepTalk.interpretation ?? "Analyzing...")"
        interpretationLabel.numberOfLines = 0
        
        if sleepTalk.interpretation == nil {
            if let viewController = presentingViewController as? ViewController {
                viewController.sendToLLM(text: sleepTalk.phrase, id: sleepTalk.id)
            }
        }
    }
    
    func updateInterpretation(id: UUID, interpretation: String) {
        if id == sleepTalk.id {
            sleepTalk.interpretation = interpretation
            updateInterpretationLabel()
        }
    }
    
    @objc private func dismissVC() {
        dismiss(animated: true, completion: nil)
    }
    
    @objc func playButtonTapped() {
        if let audioURL = sleepTalk.audioURL {
            print("Attempting to play audio from URL: \(audioURL)")
            
            if FileManager.default.fileExists(atPath: audioURL.path) {
                do {
                    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
                    try AVAudioSession.sharedInstance().setActive(true)
                    
                    audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
                    audioPlayer?.prepareToPlay()
                    audioPlayer?.play()
                    print("Audio playback started")
                } catch {
                    print("Failed to play audio: \(error.localizedDescription)")
                }
            } else {
                print("Audio file does not exist at path: \(audioURL.path)")
            }
        } else {
            print("No audio file available for this entry.")
        }
    }

    @objc func deleteButtonTapped() {
        let alert = UIAlertController(title: "Delete Phrase", message: "Are you sure you want to delete this phrase?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { [weak self] _ in
            self?.deleteSleepTalk()
        }))
        present(alert, animated: true, completion: nil)
    }

    private func deleteSleepTalk() {
        if let viewController = presentingViewController as? ViewController {
            viewController.deleteSleepTalk(id: sleepTalk.id)
            dismiss(animated: true, completion: nil)
        }
    }

    private func startButtonColorFluctuation(for button: UIButton, baseColor: UIColor) {
        let animation = CAKeyframeAnimation(keyPath: "backgroundColor")
        animation.values = [
            baseColor.cgColor,
            baseColor.withAlphaComponent(0.8).cgColor,
            baseColor.withAlphaComponent(0.6).cgColor,
            baseColor.withAlphaComponent(0.8).cgColor,
            baseColor.cgColor
        ]
        animation.keyTimes = [0, 0.25, 0.5, 0.75, 1]
        animation.duration = 2.0
        animation.repeatCount = .infinity
        button.layer.add(animation, forKey: "backgroundColorAnimation")
    }
}
// MARK: - SummaryViewController

class SummaryViewController: UIViewController {
    private let summaryTextView = UITextView()
    private let summary: String

    init(summary: String) {
        self.summary = summary
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupUI()

        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(dismissVC))
    }

    private func setupUI() {
        view.addSubview(summaryTextView)
        summaryTextView.translatesAutoresizingMaskIntoConstraints = false
        summaryTextView.isEditable = false
        summaryTextView.font = UIFont.systemFont(ofSize: 16)
        summaryTextView.text = summary

        NSLayoutConstraint.activate([
            summaryTextView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            summaryTextView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            summaryTextView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            summaryTextView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20)
        ])
    }

    @objc private func dismissVC() {
        dismiss(animated: true, completion: nil)
    }
}