//
//  ChatGptVC.swift
//  WoWonder
//
//  Created by iMac on 25/04/25.
//  Copyright © 2025 ScriptSun. All rights reserved.
//

import UIKit
import IQKeyboardManagerSwift
import Async
import Toast_Swift
import WowonderMessengerSDK

class ChatGptVC: BaseVC {
    
    // MARK: - IBOutlets
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var emojiButton: UIButton!
    @IBOutlet weak var messagesViewBottom: NSLayoutConstraint!
    @IBOutlet weak var messageTextView: EmojiTextView!
    
    // MARK: - Properties
        
    var messageArray: [MessageModel] = []
    
    // MARK: - View Life Cycles
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        
        self.initialConfig()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        self.removeObserver()
        IQKeyboardManager.shared.isEnabled = true
    }
    
    // MARK: - Selectors
    
    // Back Button Action
    @IBAction func backButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.navigationController?.popViewController(animated: true)
    }
    
    // Emoji Button Action
    @IBAction func emojiButtonAction(_ sender: UIButton) {
        self.messageTextView.isEmojiKeyboard = !(self.messageTextView.isEmojiKeyboard)
        self.messageTextView.becomeFirstResponder()
        self.messageTextView.reloadInputViews()
        self.emojiButton.setImage(self.messageTextView.isEmojiKeyboard ? R.image.icon_keyboard_vector() : R.image.icon_emoji_vector(), for: .normal)
    }
    
    // Send Button Action
    @IBAction func sendButtonAction(_ sender: UIButton) {
        if messageTextView.text != "" {
            self.addMessageToListAndSend()
        }
    }
    
    // MARK: - Helper Functions
    
    // Initial Config
    func initialConfig() {
        self.setUpMessageTextView()
        self.registerCell()
        self.addStartmessageToList()
        self.setObserver()
        IQKeyboardManager.shared.isEnabled = false
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
        self.view.addGestureRecognizer(tapGesture)
        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressed))
        self.tableView.addGestureRecognizer(longPressRecognizer)
    }
    
    // SetUp Message TextView
    func setUpMessageTextView() {
        self.messageTextView.delegate = self
        self.messageTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        self.messageTextView.addPlaceholder("Write your message", with: UIColor.text_color_in_between)
    }
    
    // Set Observer
    func setObserver() {
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    // Remove Observer
    func removeObserver() {
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    // Keyboard Will Show
    @objc func keyboardWillShow(_ notification: NSNotification) {
        let userInfo = notification.userInfo!
        let bottom = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
        self.messagesViewBottom.constant = bottom - self.view.safeAreaBottom
        let duration: TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
        UIView.animate(withDuration: duration) {
            if self.messageArray.count != 0 {
                self.tableView.scrollToLastRow(animated: false)
            }
            self.view.layoutIfNeeded()
        }
    }
    
    // Keyboard Will Hide
    @objc func keyboardWillHide(_ notification: NSNotification) {
        let userInfo = notification.userInfo!
        self.messagesViewBottom.constant = 0
        let duration: TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
        UIView.animate(withDuration: duration) { self.view.layoutIfNeeded() }
    }
    
    func registerCell() {
        self.tableView.delegate = self
        self.tableView.dataSource = self
        if #available(iOS 15.0, *) {
            UITableView.appearance().isPrefetchingEnabled = false
        }
        
        self.tableView.register(UINib(resource: R.nib.leftTextTableViewCell), forCellReuseIdentifier: R.reuseIdentifier.leftTextTableViewCell.identifier)
        self.tableView.register(UINib(resource: R.nib.rightTextTableViewCell), forCellReuseIdentifier: R.reuseIdentifier.rightTextTableViewCell.identifier)
    }
    
    func addStartmessageToList() {
        let dateFormatter = DateFormatter()
        dateFormatter.timeStyle = .short
        let timeNow = dateFormatter.string(from: Date())
        
        let unixTimestamp = Int(Date().timeIntervalSince1970)
        let time2 = String(unixTimestamp)
        let message = MessageModel(id: time2, from_id: "0", to_id: AppInstance.instance._userId, media: "", seen: "-1", time: time2, position: "left", time_text: timeNow, type: "left_text", message_hash_id: time2, user_data: AppInstance.instance.userProfile, text: "Hi! I&apos;m AI Chat Bot, and I&apos;m here to answer your all questions.", messageUser: AppInstance.instance.userProfile)
        self.messageArray.append(message)
        self.tableView.reloadData()
        self.tableView.scrollToLastRow(animated: false)
    }
    
    func addMessageToListAndSend() {
        let timeNow = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .short)
        let unixTimestamp = Int(Date().timeIntervalSince1970)
        let timeString = String(unixTimestamp)
        
        // Create user's outgoing message
        var outgoingMessage = MessageModel(
            id: timeString,
            from_id: AppInstance.instance._userId,
            to_id: "0",
            media: "",
            seen: "-1",
            time: timeString,
            position: "right",
            time_text: timeNow,
            type: "right_text",
            message_hash_id: timeString,
            user_data: AppInstance.instance.userProfile,
            text: self.messageTextView.text,
            messageUser: AppInstance.instance.userProfile
        )
        
        self.messageArray.insert(outgoingMessage, at: self.messageArray.count)
        self.tableView.reloadData()
        self.tableView.scrollToLastRow(animated: false)
        
        self.generateText(userMessage: self.messageTextView.text)
    }
    
    @objc func handleTap(_ gesture: UITapGestureRecognizer) {
        self.view.endEditing(true)
    }
    
    // TableView longPressed Click
    @objc func longPressed(sender: UILongPressGestureRecognizer) {
        let objSender = sender.location(in: self.tableView)
        let indexPath = self.tableView.indexPathForRow(at: objSender)
        if indexPath != nil {
            let objCopyMessageArray = self.messageArray[indexPath?.row ?? 0]
            if let newVC = R.storyboard.chat.messageOptionViewController() {
                newVC.modalPresentationStyle = .custom
                newVC.transitioningDelegate = self
                newVC.delegate = self
                newVC.indexPath = indexPath ?? IndexPath()
                if objCopyMessageArray.type == "right_text" || objCopyMessageArray.type == "left_text" {
                    if (Double(objCopyMessageArray.lat ?? "0.0") ?? 0.0) > 0.0 || Double(objCopyMessageArray.lng ?? "0.0") ?? 0.0 > 0.0 {
                        newVC.isCopy = false
                    } else {
                        newVC.isCopy = true
                    }
                } else {
                    newVC.isCopy = false
                }
                self.present(newVC, animated: true)
            }
        }
    }
    
}

// MARK: - Extensions

// MARK: Api Call
extension ChatGptVC {
    
    private func generateText(userMessage: String) {
        if Connectivity.isConnectedToNetwork() {
            let token = AppInstance.instance.decryptAESInECBModeToString(text: AppInstance.instance.siteSetting?.openai_token ?? "", key: API.ENCRYPTION_KEY.Encryption_Key) ?? ""
            print(token)
            Async.background {
                ChatGptManager.instance.generateText(token: token, userMessage: userMessage, completionBlock: { success, authError, error in
                    Async.main {
                        if success != nil {
                            print(success as Any)
                            
                            self.view.resignFirstResponder()
                            self.messageTextView.text = ""
                            
                            let timeNow = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .short)
                            let responseTime = String(Int(Date().timeIntervalSince1970))
                            let responseText = success?.choices?.first?.message?.content
                            let botMessage = MessageModel(
                                id: responseTime,
                                from_id: "0",
                                to_id: AppInstance.instance.userId,
                                media: "",
                                seen: "-1",
                                time: responseTime,
                                position: "left",
                                time_text: timeNow,
                                type: "left_text",
                                message_hash_id: responseTime,
                                user_data: AppInstance.instance.userProfile,
                                text: responseText,
                                messageUser: AppInstance.instance.userProfile
                            )
                            
                            self.messageArray.append(botMessage)
                            
                            self.tableView.reloadData()
                            self.tableView.scrollToLastRow(animated: false)
                        } else if authError != nil {
                            print(authError?.message ?? "")
                            //self.view.makeToast(authError?.message)
                        } else if error != nil {
                            self.view.makeToast(error?.localizedDescription ?? "")
                        }
                    }
                })
            }
        } else {
            self.view.makeToast(InterNetError)
        }
    }
    
}

// MARK: TableView Setup
extension ChatGptVC: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messageArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let objChatList = messageArray[indexPath.row]
        guard let type = objChatList.type else { return UITableViewCell() }
        switch type {
        case "left_text":
                let cell = self.tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.leftTextTableViewCell.identifier, for: indexPath) as! LeftTextTableViewCell
                self.setLeftTextData(cell: cell, indexPathForCell: indexPath)
                return cell
        case "right_text":
                let cell = self.tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.rightTextTableViewCell.identifier, for: indexPath) as! RightTextTableViewCell
                self.setRightTextData(cell: cell, indexPathForCell: indexPath)
                return cell
        default:
            return UITableViewCell()
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    // Set Left Text Data
    private func setLeftTextData(cell: LeftTextTableViewCell, indexPathForCell: IndexPath) {
        cell.swipeRecognizer.isEnabled = false
        let objChatList = self.messageArray[indexPathForCell.row]
        cell.forwardedView.isHidden = true
        cell.userStackView.isHidden = true
        cell.replyMessageView.isHidden = true
        cell.replyStoryView.isHidden = true
        cell.masageTextLabel.text = objChatList.text ?? ""
        cell.messageTimeLabel.text = objChatList.time?.timeStampStringToTime()
        cell.reactionImageView.isHidden = true
        cell.starImageView.isHidden = true
        // cell.messageView.backgroundColor = UIColor(hex: "#F2F2F2")
    }
    
    // Set Right Text Data
    private func setRightTextData(cell: RightTextTableViewCell, indexPathForCell: IndexPath) {
        cell.swipeRecognizer.isEnabled = false
        let objChatList = self.messageArray[indexPathForCell.row]
        cell.forwardedView.isHidden = true
        cell.replyMessageView.isHidden = true
        cell.replyStoryView.isHidden = true
        cell.messaageTextLabel.text = objChatList.text ?? ""
        cell.messageTimeLabel.text = objChatList.time?.timeStampStringToTime()
        cell.reactionImageView.isHidden = true
        cell.starImageVIew.isHidden = true
        cell.messageView.backgroundColor = UIColor(hex: "#C83747")
        if objChatList.seen == "0" {
            cell.lastSeenImage.image = UIImage(named: "ic_seenCheck")?.withRenderingMode(.alwaysTemplate)
            cell.lastSeenImage.tintColor = UIColor(hex: "C83747")
        } else {
            cell.lastSeenImage.image = UIImage(named: "ic_seen")?.withRenderingMode(.alwaysTemplate)
            cell.lastSeenImage.tintColor = UIColor(hex: "C83747")
        }
    }
    
}

// MARK: UITextViewDelegate Methods
extension ChatGptVC: UITextViewDelegate {
    
    func textViewDidEndEditing(_ textView: UITextView) {
        self.messageTextView.isEmojiKeyboard = false
        self.emojiButton.setImage(self.messageTextView.isEmojiKeyboard ? R.image.icon_keyboard_vector() : R.image.icon_emoji_vector(), for: .normal)
    }
    
}

// MARK: MessageOptionDelegate Methods
extension ChatGptVC: MessageOptionDelegate {
    
    func handleMessageOptionTap(index: Int, optionName: String, indexPath: IndexPath) {
        let object = self.messageArray[indexPath.row]
        if index == 0 {
            let messageString = "\(self.decryptionAESModeECB(messageData: object.text ?? "", key: object.time ?? "") ?? object.text ?? "")"
            UIPasteboard.general.string = messageString
        }
    }
    
}

// MARK: UIViewControllerTransitioningDelegate Methods
extension ChatGptVC: UIViewControllerTransitioningDelegate {
    
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        BottomSheetPresentationController(presentedViewController: presented, presenting: presenting)
    }
    
}
