//
//  See LICENSE folder for this template’s licensing information.
//
//  Abstract:
//   playground ライブビューとコード間のメッセージハンドリング
//   playground BluetoothによるconnectionViewの表示

import UIKit
import SpriteKit
import Foundation
import Network
import PlaygroundSupport
import AVFoundation

public class DropViewController: UIViewController,PlaygroundLiveViewSafeAreaContainer, SetNameViewDelegate  {

    private var mySKView = SKView()
    private var vstring = String()
    private var jewelType = Int() //宝石番号
    private var myScene = DropScene()
    public var usernameLabel = UILabel()
    public var clrButton = UIButton()
    public var setUserButton = UIButton()
    private var addedLayers = [CAShapeLayer]()  //描画したシェイプを保持
    private var dropCounter = [0,0,0,0,0,0,0,0,0,0]  //各列のカウンター
    private var userName: String? = nil
    private var userNumber: String? = nil
    //private let tcpClient = TCPClient()
    private let url = URL(string: "https://feedm.net/playgroundSupport/jewelDrop/session.php")!
    private var schoolId: String? = nil
    private var webMode: String? = nil
    private var currentSetNameView: SetNameView? = nil
    
    public required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override public func viewDidLoad() {
        super.viewDidLoad()
        
        // PlaygroundKeyValueStoreからSchoolIdを取得
        if let keyValue = PlaygroundKeyValueStore.current["schoolId"],
           case .string(let storedSchoolId) = keyValue {
            schoolId = storedSchoolId
        } else {
            schoolId = nil
        }
        
        // PlaygroundKeyValueStoreからWebModeを取得
        if let keyValue = PlaygroundKeyValueStore.current["webMode"],
           case .string(let storedWebMode) = keyValue {
            webMode = storedWebMode
        } else {
            webMode = nil
        }

        // PlaygroundKeyValueStoreからユーザー名を取得
        if let keyValue = PlaygroundKeyValueStore.current["userName"],
            case .string(let storedUserName) = keyValue {
            userName = storedUserName
        } else {
            userName = nil
        }
        
        // PlaygroundKeyValueStoreから番号を取得
        if let keyValue = PlaygroundKeyValueStore.current["userNumber"],
            case .string(let storedNumber) = keyValue {
            userNumber = storedNumber
        } else {
            userNumber = nil
        }
        
        //クライアントの開始
        //tcpClient.start()
        
        jewelType = 1
        view.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
        // disable auto layout
        view.translatesAutoresizingMaskIntoConstraints = false
        
       //ビューを配置
        mySKView.isUserInteractionEnabled = true
        mySKView.clipsToBounds = true //はみ出さない様にする。

        mySKView.layer.cornerRadius = 0
        //mySKView.showsFPS = true
        //mySKView.showsNodeCount = true
        mySKView.translatesAutoresizingMaskIntoConstraints  = false
        mySKView.frame.size = CGSize(width:200.0, height:205.0)
        myScene = DropScene(size: mySKView.frame.size)
        myScene.scaleMode = .aspectFit
        mySKView.allowsTransparency = true
        mySKView.presentScene(myScene)
        view.addSubview(mySKView)
        
         // ボタンの位置とサイズを設定
        clrButton.frame = CGRect(x:20, y:80,
                        width:120, height:30)
         // ボタンのタイトルを設定
        clrButton.setTitle("画面クリア", for:UIControl.State.normal)
         // タイトルの色
        clrButton.setTitleColor(UIColor.blue, for: .normal)
         // ボタンのフォントサイズ
        clrButton.titleLabel?.font =  UIFont.systemFont(ofSize: 16)
         // 背景色
        clrButton.backgroundColor = UIColor.init(
            red:0.9, green: 0.9, blue: 0.9, alpha: 0.5)
        clrButton.layer.cornerRadius = 5
         // タップされたときのaction
        clrButton.addTarget(self,
                            action: #selector(self.buttonTapped(sender:)),
                for: .touchUpInside)
         // Viewにボタンを追加
         self.view.addSubview(clrButton)
        
        // ボタンの位置とサイズを設定
        setUserButton.frame = CGRect(x:160, y:80,
                       width:120, height:30)
        // ボタンのタイトルを設定
        setUserButton.setTitle("ユーザー設定", for:UIControl.State.normal)
        // タイトルの色
        setUserButton.setTitleColor(UIColor.blue, for: .normal)
        // ボタンのフォントサイズ
        setUserButton.titleLabel?.font =  UIFont.systemFont(ofSize: 16)
        // 背景色
        setUserButton.backgroundColor = UIColor.init(
           red:0.9, green: 0.9, blue: 0.9, alpha: 0.5)
        setUserButton.layer.cornerRadius = 5
        // タップされたときのaction
        setUserButton.addTarget(self,
                           action: #selector(self.showSetNameView),
               for: .touchUpInside)
        // Viewにボタンを追加
        self.view.addSubview(setUserButton)
        
        //ユーザー名ラベルの位置とサイズを設定
        usernameLabel.frame = CGRect(x:150, y:80, width:400, height:30)
        usernameLabel.font = UIFont.systemFont(ofSize: 20)
        usernameLabel.text = [userNumber, userName].compactMap { $0 }.joined(separator: ":")
        self.view.addSubview(usernameLabel)
        
        clrButton.translatesAutoresizingMaskIntoConstraints  = false
        setUserButton.translatesAutoresizingMaskIntoConstraints  = false
        usernameLabel.translatesAutoresizingMaskIntoConstraints  = false
        
        NSLayoutConstraint.activate([
            setUserButton.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor,constant: 20.0),
            setUserButton.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor,constant: 10.0),
            setUserButton.heightAnchor.constraint(equalToConstant: 30.0),
            setUserButton.widthAnchor.constraint(equalToConstant: 100.0),
            
            clrButton.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor,constant: -20.0),
            clrButton.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor,constant: 10.0),
            clrButton.heightAnchor.constraint(equalToConstant: 30.0),
            clrButton.widthAnchor.constraint(equalToConstant: 100.0),
            
            usernameLabel.leadingAnchor.constraint(equalTo: setUserButton.trailingAnchor,constant: 20.0),
            usernameLabel.trailingAnchor.constraint(equalTo: clrButton.leadingAnchor, constant: -20),
            usernameLabel.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor,constant: 10.0),
            usernameLabel.heightAnchor.constraint(equalToConstant: 30.0),
            

            
            
            mySKView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor,constant: 20.0),
            mySKView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20.0),
            mySKView.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 50.0),
            mySKView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: -50)
            ])
        
        
    }
    
    override public func viewWillAppear(_ animated: Bool) {
    }
    
    @objc func showSetNameView() {
        // すでに SetNameView が表示されているかどうかを確認
        if currentSetNameView != nil {
            return
        }
        
        let setNameView = SetNameView()
        setNameView.delegate = self // デリゲートを設定
        setNameView.translatesAutoresizingMaskIntoConstraints = false
        // SetNameView を現在のプロパティに保持
        currentSetNameView = setNameView
        
        self.view.addSubview(setNameView)
        
        NSLayoutConstraint.activate([
            setNameView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor,constant: 40.0),
            setNameView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -40.0),
            setNameView.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 70.0),
            setNameView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: -70)
        ])
    }
    
    func didSaveSettings(userName: String?, userNumber: String?) {
        self.userName = userName
        self.userNumber = userNumber
        usernameLabel.text = [userNumber, userName].compactMap { $0 }.joined(separator: ":")
        currentSetNameView?.removeFromSuperview()
        currentSetNameView = nil
    }
    
    func didCloseSetNameView() {
        // `SetNameView` を削除
        currentSetNameView?.removeFromSuperview()
        currentSetNameView = nil
    }
    
    @objc func buttonTapped(sender : Any) {
           myScene.clear()
    }
    
}

extension DropViewController: PlaygroundLiveViewMessageHandler {
    //Playgroundページからメッセージを受け取る際の処理。
    public func receive(_ message: PlaygroundValue) {
        clrButton.isEnabled = false
        if case let .string(text) = message {
            if(text == "clear") { //クリア命令
                //全消し
                myScene.clear()
                dropCounter = [0,0,0,0,0,0,0,0,0,0]
                return
            }
            
            let arr:[String] = text.components(separatedBy: " ")
            
            var codetext = ""
            if(arr[0] == "message") {
                let codeText = PlaygroundPage.current.text
                // 取得した文字列から、ユーザー編集したものだけを取り出して出力
                let pattern = #"//#-editable-code\n([\s\S]*?)\n//#-end-editable-code"#
                do {
                    let regex = try NSRegularExpression(pattern: pattern, options: [])
                    let nsRange = NSRange(codeText.startIndex..<codeText.endIndex, in: codeText)
                    let matches = regex.matches(in: codeText, options: [], range: nsRange)
                    // マッチした内容を取り出す
                    for match in matches {
                        if let range = Range(match.range(at: 1), in: codeText) {
                            codetext += String(codeText[range]) + "\n"
                        }
                    }
                } catch {
                    codetext = "\n"
                }
                let message = (userNumber ?? "-") + "," + (userName ?? "未設定") + "," + text.suffix(text.count - 8)
                
                if (webMode == "Off") { //Bonjour送信の場合
                    let tcpClient = TCPClient()
                    // サービスの開始
                    tcpClient.start()
                    // 接続が確立された後にメッセージを送信するようにコールバックを設定
                    tcpClient.onConnectionReady = {
                        let messagedict: [String: String] = [
                            "message": message,
                            "code": codetext
                        ]
                        tcpClient.send(messageDict: messagedict)
                    }
                } else if (webMode == "On") { //Web送信の場合
                    //web送信の場合
                    let httpSend = HTTPSend(url: url)
                    httpSend.sendMessage(messageText: message, codeText:codetext, schoolId: schoolId ?? "") { result in
                        switch result {
                        case .success:
                            print("Message sent successfully")
                        case .failure(let error):
                            print("Failed to send message: \(error.localizedDescription)")
                        }
                    }
                    return
                }
            }
            
            if(arr.count == 2) {
                if(arr[0] == "drop") {
                    if(Int(arr[1])! < 1 || Int(arr[1])! > 10) {
                        return
                    }
                    if(dropCounter[Int(arr[1])!-1] < 10) {
                        dropCounter[Int(arr[1])!-1] += 1
                        if (jewelType == 0) {
                            myScene.dropZero(Int(arr[1])!)
                        } else if (jewelType == 1) {
                            myScene.dropRed(Int(arr[1])!)
                        } else if (jewelType == 2) {
                            myScene.dropGreen(Int(arr[1])!)
                        } else if (jewelType == 3) {
                            myScene.dropBlue(Int(arr[1])!)
                        }
                    }
                }
                
                if(arr[0] == "color") {
                    if(Int(arr[1])! < 4 && Int(arr[1])! >= 0) {
                        jewelType = Int(arr[1])!
                    } else {
                        jewelType = 1
                    }
                }
                return
            }
            
            if(arr.count == 4) {
                return
            }
        }
    }
    
    public func liveViewMessageConnectionOpened() {
        clrButton.isEnabled = false
        mySKView.isUserInteractionEnabled = false
        // Implement this method to be notified when the live view message connection is opened.
        // The connection will be opened when the process running Contents.swift starts running and listening for messages.
    }
    
    public func liveViewMessageConnectionClosed() {
        clrButton.isEnabled = true
        mySKView.isUserInteractionEnabled = true
        // Implement this method to be notified when the live view message connection is closed.
        // The connection will be closed when the process running Contents.swift exits and is no longer listening for messages.
        // This happens when the user's code naturally finishes running, if the user presses Stop, or if there is a crash.
    }
}


