can you edit my following code to fix this issue:

while the app is recording, it successfully initiates and finalises the first phrase, but not any of the next ones. make it so it new cells are created upon new speech being detected. also, can you edit the prompts for the ai to let it know that only the good morning message needs to be under 53 characters, but all the other pieces of text can be any length. also, make sure it knows that it is now allowed to include words at the start of the passages that are not part of the actual analyses or messages, stuff like "Interpretation:" or "Summary:" i dont want included. just the raw passages.

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 stopTranscription() {
        print("Stopping transcription only, not the recording.")
        
        // End the current recognition request and task
        recognitionRequest?.endAudio()
        recognitionTask?.cancel()
        recognitionRequest = nil
        recognitionTask = nil
        
        // Remove tap to stop receiving audio buffers for transcription
        audioEngine?.inputNode.removeTap(onBus: 0)
        
        // Stop the audio engine if it's running
        if audioEngine?.isRunning == true {
            audioEngine?.stop()
        }
        
        print("Transcription stopped. Recording continues.")
    }

    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 due to silence.")
        
        // Stop only the transcription
        stopTranscription()
        
        // Optionally, allow restarting transcription after a brief pause
        if isSleepRecording || isTestRecording {
            // Wait for a moment before restarting transcription to avoid rapid toggling
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
                self?.startTranscription()
                print("Resumed transcription after silence.")
            }
        }
    }

    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)")
                // Optionally, handle specific errors or update UI
                // Do not stop the recording here
            }
        }
        
        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 if it's active
        if recognitionTask != nil {
            stopTranscription()
        }
        
        // Stop audio engine
        if audioEngine?.isRunning == true {
            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)
        
        // 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")
                    // Removed Good Morning message
                    return
                }

                guard let data = data else {
                    print("No data received from API")
                    self?.updateInterpretation(for: id, with: "Error: No data received")
                    // Removed Good Morning message
                    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 _ = 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)
                        
                        // Removed Good Morning message
                    } else {
                        self?.updateInterpretation(for: id, with: "Error: Invalid response format")
                        // Removed Good Morning message
                    }
                } catch {
                    print("JSON parsing error: \(error)")
                    self?.updateInterpretation(for: id, with: "Error: Unable to parse response")
                    // Removed Good Morning message
                }
            }
        }

        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)
    }
}