//
//  See LICENSE folder for this template’s licensing information.
//
//  Abstract:
//   playground 学習状況の把握
//   playground BluetoothによるconnectionViewの表示

import UIKit
import PlaygroundSupport
import AVFoundation
import AudioToolbox
import Accounts

// データモデルの定義
struct Item: Codable {
    let number: String
    let name: String
    let page: Int
    let status: Int
    let message: String
    let codetext: String
    let date: Date
}

// ページ状態をまとめた表のためのデータモデルの定義
struct GroupedItem {
    let number: String
    let name: String
    var statuses: [Int: Int] // page: status
}

// カスタムセルクラスの定義
class CustomTableViewCell: UITableViewCell {
    let numberLabel = UILabel()
    let nameLabel = UILabel()
    let pageLabel = UILabel()
    let statusLabel = UILabel()
    let messageLabel = UILabel()
    let codetextLabel = UILabel()
    let dateLabel = UILabel()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        // messageLabelにタップジェスチャーを追加
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleMessageTap))
        messageLabel.isUserInteractionEnabled = true
        messageLabel.addGestureRecognizer(tapGesture)
        
        let stackView = UIStackView(arrangedSubviews: [
            numberLabel, verticalSeparator(),
            nameLabel, verticalSeparator(),
            pageLabel, verticalSeparator(),
            statusLabel, verticalSeparator(),
            messageLabel, verticalSeparator(),
            dateLabel
        ])
        
        stackView.axis = .horizontal
        stackView.distribution = .fill
        stackView.spacing = 5
        contentView.addSubview(stackView)
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
            stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5)
        ])
        
        // ラベルの横幅調整
        numberLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
        nameLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        pageLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
        statusLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
        messageLabel.widthAnchor.constraint(equalToConstant: 120).isActive = true
        dateLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        
        // ラベルのテキストアライメント
        numberLabel.textAlignment = .right
        pageLabel.textAlignment = .right
        statusLabel.textAlignment = .center
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func verticalSeparator() -> UIView {
        let separator = UIView()
        separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
        separator.backgroundColor = .lightGray
        return separator
    }
    // messageLabelがタップされた時のアクション
    @objc private func handleMessageTap() {
        // messageLabelのフルテキストをポップアップで表示
        if let parentViewController = self.window?.rootViewController {
            showPopupMessage(in: parentViewController, message: codetextLabel.text ?? "")
        }
    }
    
    private func showPopupMessage(in viewController: UIViewController, message: String) {
        let textView = UITextView()
        textView.text = message
        textView.isEditable = false
        textView.font = UIFont.systemFont(ofSize: 16)
        
        let popupViewController = UIViewController()
        popupViewController.view.addSubview(textView)
        
        textView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            textView.leadingAnchor.constraint(equalTo: popupViewController.view.leadingAnchor, constant: 10),
            textView.trailingAnchor.constraint(equalTo: popupViewController.view.trailingAnchor, constant: -10),
            textView.topAnchor.constraint(equalTo: popupViewController.view.topAnchor, constant: 10),
            textView.bottomAnchor.constraint(equalTo: popupViewController.view.bottomAnchor, constant: -10)
        ])
        
        popupViewController.modalPresentationStyle = .popover
        popupViewController.preferredContentSize = CGSize(width: 300, height: 200)
        
        if let popoverPresentationController = popupViewController.popoverPresentationController {
            popoverPresentationController.sourceView = messageLabel
            popoverPresentationController.sourceRect = messageLabel.bounds
            popoverPresentationController.permittedArrowDirections = .any
        }
        
        viewController.present(popupViewController, animated: true, completion: nil)
    }
}

// ページ状態をまとめた表のためのカスタムセルクラスの定義
class SummaryTableViewCell: UITableViewCell {
    let numberLabel = UILabel()
    var statusLabels: [UILabel] = []

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let stackView = UIStackView(arrangedSubviews: [
            numberLabel
        ])
        for _ in 1...17 {
            let statusLabel = UILabel()
            statusLabel.textAlignment = .center
            statusLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
            statusLabels.append(statusLabel)
            stackView.addArrangedSubview(verticalSeparator())
            stackView.addArrangedSubview(statusLabel)
        }

        stackView.axis = .horizontal
        stackView.distribution = .equalCentering
        stackView.spacing = 5
        contentView.addSubview(stackView)
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
            stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5)
        ])
        
        // ラベルの横幅調整
        numberLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
        numberLabel.textAlignment = .right
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func verticalSeparator() -> UIView {
        let separator = UIView()
        separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
        separator.backgroundColor = .lightGray
        return separator
    }
}

public class SituationViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, PlaygroundLiveViewSafeAreaContainer, TCPServerDelegate, HTTPPollingDelegate, HTTPAuthDelegate {

    var items: [Item] = []
    var groupedItems: [GroupedItem] = []
    let tableView = UITableView(frame: .zero, style: .plain)
    let summaryTableView = UITableView()
    let messageView = UITextView()
    let titleLabel = UILabel()
    let exportButton = UIButton(type: .system)
    let tcpServer = TCPServer(port: 12345)
    var sortKey: String = "number"
    private let url = URL(string: "https://isliceme01.stars.ne.jp/jewelDrop/session.php")!
    private let auth_url = URL(string: "https://isliceme01.stars.ne.jp/jewelDrop/authenticate.php")!

    private var httpPolling: HTTPPolling?
    private var httpAuth: HTTPAuth?
    private var schoolId: String? = nil
    private var webMode: String? = nil
    private var teacherMode: String? = nil
    
    var audioPlayer: AVAudioPlayer?
    
    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)
    }
    
    public override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

    }

    public override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }
    
    public override 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からteacherModeを取得
        if let keyValue = PlaygroundKeyValueStore.current["teacherMode"],
           case .string(let storedTeacherMode) = keyValue {
            teacherMode = storedTeacherMode
        } else {
            teacherMode = nil
        }
        setupView()
    }
    
    public func didWebAuthenticateSuccess() {
        DispatchQueue.main.async {
            //self.messageView.insertText("認証成功: schoolID=\(self.schoolId ?? "")")
            self.messageView.insertText("認証成功\n")
            if(self.webMode == "Off") {
                //Bonjourサービスの場合
                self.tcpServer.delegate = self
                self.tcpServer.start()
                self.messageView.insertText("Wi-Fiモードで受信を開始しました。\n")
            } else if(self.webMode == "On") {
                //webPollingサービスの場合
                self.httpPolling = HTTPPolling(url: self.url, schoolId: self.schoolId ?? "")
                self.httpPolling?.delegate = self
                self.httpPolling?.startPolling()
                self.messageView.insertText("Webモードで受信を開始しました。\n")
            }
        }
    }
    
    public func didWebAuthenticateFailWithError(_ error: Error) {
        DispatchQueue.main.async {
            // 認証失敗時の処理を記述
            self.messageView.insertText("認証失敗: schoolID=\(self.schoolId ?? ""):\(error.localizedDescription)")
            self.messageView.insertText("\n認証に失敗した為、受信処理ができません。")
            self.tcpServer.stop()
            self.httpPolling?.stopPolling()
        }
    }
    
    
    func setupView() {
        if (teacherMode == "On") {
            // Register custom cell
            tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "customCell")
            summaryTableView.register(SummaryTableViewCell.self, forCellReuseIdentifier: "summaryCell")
            
            //タイトルラベルの設定
            titleLabel.backgroundColor = .systemFill
            titleLabel.text = "  schoolId: " + (schoolId ?? "未設定") + "      webモード: " + (webMode ?? "未設定")
            //エクスポートボタンの設定
            let exportIcon = UIImage(systemName: "doc.on.doc") // SF Symbolsのアイコン名
            exportButton.setImage(exportIcon, for: .normal)
            // アイコンの色を設定する場合
            exportButton.tintColor = .systemBlue // 必要に応じて色を変更
            exportButton.backgroundColor = .systemFill
            // ボタンのサイズと位置設定（例としてframeを設定）
            exportButton.frame = CGRect(x: 100, y: 100, width: 50, height: 50) // 必要に応じてサイズや位置を調整
            
            exportButton.addTarget(self, action: #selector(exportButtonTapped), for: .touchUpInside)
            view.addSubview(exportButton)
            
            // テーブルビューの設定
            tableView.dataSource = self
            tableView.delegate = self
            summaryTableView.dataSource = self
            summaryTableView.delegate = self
            titleLabel.frame.size.height = 20.0
            titleLabel.frame = view.bounds
            tableView.frame = view.bounds
            summaryTableView.frame = view.bounds
            
            view.addSubview(titleLabel)
            view.addSubview(exportButton)
            view.addSubview(tableView)
            view.addSubview(summaryTableView)
            
            // メッセージビューの設定
            messageView.frame = view.bounds
            messageView.layer.borderWidth = 1.0
            messageView.backgroundColor = .systemFill
            messageView.isEditable = false
            view.addSubview(messageView)
            
            // レイアウト調整
            titleLabel.translatesAutoresizingMaskIntoConstraints = false
            exportButton.translatesAutoresizingMaskIntoConstraints = false
            tableView.translatesAutoresizingMaskIntoConstraints = false
            summaryTableView.translatesAutoresizingMaskIntoConstraints = false
            messageView.translatesAutoresizingMaskIntoConstraints = false
            
            NSLayoutConstraint.activate([
                titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                titleLabel.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor),
                titleLabel.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -80),
                titleLabel.heightAnchor.constraint(equalToConstant: 40),
                
                exportButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                exportButton.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
                exportButton.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor),
                exportButton.heightAnchor.constraint(equalToConstant: 40),

                tableView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor),
                tableView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor),
                tableView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor),
                tableView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4),
                
                summaryTableView.topAnchor.constraint(equalTo: tableView.bottomAnchor),
                summaryTableView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor),
                summaryTableView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor),
                summaryTableView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4),
                
                messageView.topAnchor.constraint(equalTo: summaryTableView.bottomAnchor),
                messageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                messageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                messageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
            ])
            
            loadItems()
            //messageView.insertText("認証開始\n")
            httpAuth = HTTPAuth(url: auth_url, schoolId: schoolId ?? "")
            httpAuth?.delegate = self
            httpAuth?.authenticate()
            
        } else {
            let label = UILabel()
            label.text = "teacherモードが設定されていません。"
            label.textAlignment = .center
            view.addSubview(label)
            label.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                label.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor),
                label.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor),
                label.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor),
                label.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor)
            ])
        }
    }
    
    func setupFailView() {
        let label = UILabel()
        label.text = "スクールIDの認証がされませんでした。"
        label.textAlignment = .center
        view.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor),
            label.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor),
            label.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor)
        ])
    }

    
    // UITableViewDataSource メソッド
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.tableView {
            return items.count
        } else {
            return groupedItems.count
        }
    }
    
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if tableView == self.tableView {
            let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
            let item = items[indexPath.row]
            
            // Configure custom cell labels
            cell.numberLabel.text = "\(item.number)"
            cell.nameLabel.text = "\(item.name)"
            cell.pageLabel.text = "\(item.page)"
            cell.messageLabel.text = "\(item.message)"
            cell.codetextLabel.text = "\(item.codetext)"
            
            // 日付ラベルの設定（時間のみ表示）
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "HH:mm:ss"
            cell.dateLabel.text = dateFormatter.string(from: item.date)
            
            // Status label configuration
            switch item.status {
            case 1:
                cell.statusLabel.text = "✅"
            case 2:
                cell.statusLabel.text = "❌"
            default:
                cell.statusLabel.text = "\(item.status)"
            }
            
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "summaryCell", for: indexPath) as! SummaryTableViewCell
            let item = groupedItems[indexPath.row]
            
            // Configure summary cell labels
            cell.numberLabel.text = "\(item.number)"
            
            // Configure status labels
            for (page, status) in item.statuses {
                if page <= cell.statusLabels.count {
                    let statusLabel = cell.statusLabels[page - 1]
                    switch status {
                    case 1:
                        statusLabel.text = "✅"
                    case 2:
                        statusLabel.text = "❌"
                    default:
                        statusLabel.text = "　"
                    }
                }
            }
            return cell
        }
    }
    
    // UITableViewDelegate メソッド - セクションヘッダーの設定
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if tableView == self.tableView {
        let headerView = UIView()
            headerView.frame = CGRect(x: 0, y: 0, width: 1000, height: 44) // 幅を大きく設定

        headerView.backgroundColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
            if traitCollection.userInterfaceStyle == .dark {
                return UIColor(red: 0.18, green: 0.57, blue: 0.85, alpha: 1.0) // ダークモード用の水色
            } else {
                return UIColor(red: 0.239, green: 0.675, blue: 0.969, alpha: 1.0) // ライトモード用の水色
            }
        }
        
        let numberLabel = UILabel()
        numberLabel.text = "番号"
        let nameLabel = UILabel()
        nameLabel.text = "名前"
        let pageLabel = UILabel()
        pageLabel.text = "ページ"
        let statusLabel = UILabel()
        statusLabel.text = "状態"
        let messageLabel = UILabel()
        messageLabel.text = "メッセージ"
        let dateLabel = UILabel()
        dateLabel.text = "時間"
        
        let verticalSeparator1 = UIView()
        let verticalSeparator2 = UIView()
        let verticalSeparator3 = UIView()
        let verticalSeparator4 = UIView()
        let verticalSeparator5 = UIView()
        
        let stackView = UIStackView(arrangedSubviews: [
            numberLabel, verticalSeparator1,
            nameLabel, verticalSeparator2,
            pageLabel, verticalSeparator3,
            statusLabel, verticalSeparator4,
            messageLabel, verticalSeparator5,
            dateLabel
        ])
        stackView.axis = .horizontal
        stackView.distribution = .fill
        stackView.spacing = 5
        headerView.addSubview(stackView)
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 10),
            stackView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor, constant: -10),
            stackView.topAnchor.constraint(equalTo: headerView.topAnchor, constant: 5),
            stackView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor, constant: -5)
        ])
        
        // ラベルの横幅調整
        numberLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
        nameLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        pageLabel.widthAnchor.constraint(equalToConstant: 50).isActive = true
        statusLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
        messageLabel.widthAnchor.constraint(equalToConstant: 120).isActive = true
        dateLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
        
        // 縦棒の設定
        let separators = [verticalSeparator1, verticalSeparator2, verticalSeparator3, verticalSeparator4, verticalSeparator5]
        separators.forEach { separator in
            separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
            separator.backgroundColor = .darkGray
        }
        
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(sortItems(_:)))
        headerView.addGestureRecognizer(tapGestureRecognizer)
            return headerView
        } else {
            let headerView = UIView()
            headerView.backgroundColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
                if traitCollection.userInterfaceStyle == .dark {
                    return UIColor(red: 0.18, green: 0.57, blue: 0.85, alpha: 1.0) // ダークモード用の水色
                } else {
                    return UIColor(red: 0.239, green: 0.675, blue: 0.969, alpha: 1.0) // ライトモード用の水色
                }
            }
            
            let numberLabel = UILabel()
            numberLabel.text = "番号"
            
           // Create labels for pages 1 to 17
            var statusLabels: [UILabel] = []
            for i in 1...17 {
                let statusLabel = UILabel()
                statusLabel.text = "\(i)"
                statusLabel.textAlignment = .center // 中央揃え
                statusLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
                statusLabels.append(statusLabel)
            }
            
            // セパレーターを含むラベルの配列を作成
            var arrangedSubviews: [UIView] = []
            let labels = [numberLabel] + statusLabels
            for (index, label) in labels.enumerated() {
                arrangedSubviews.append(label)
                if index < labels.count - 1 { // 最後のラベルの次にセパレーターを追加しない
                    let separator = verticalSeparator()
                    arrangedSubviews.append(separator)
                }
            }
            
            let stackView = UIStackView(arrangedSubviews: arrangedSubviews)
            stackView.axis = .horizontal
            stackView.distribution = .equalCentering
            stackView.spacing = 5
            headerView.addSubview(stackView)
            
            stackView.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                stackView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 10),
                stackView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor, constant: -10),
                stackView.topAnchor.constraint(equalTo: headerView.topAnchor, constant: 5),
                stackView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor, constant: -5)
            ])
            // ラベルの横幅調整
            numberLabel.widthAnchor.constraint(equalToConstant: 40).isActive = true
            numberLabel.textAlignment = .right
            return headerView
        }
    }
    
    private func verticalSeparator() -> UIView {
        let separator = UIView()
        separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
        separator.backgroundColor = .darkGray
        return separator
    }

    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40
    }
    
    // 行の削除をサポート
    public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if tableView == self.tableView {
            if editingStyle == .delete {
                // データソースから項目を削除
                items.remove(at: indexPath.row)
                // PlaygroundKeyValueStoreにデータを保存して永続化
                saveItems()
                // テーブルビューから行を削除
                tableView.deleteRows(at: [indexPath], with: .fade)
                // グループ化されたデータを更新
                updateGroupedItems()
                summaryTableView.reloadData()
            }
        }
    }

    // 行の編集を許可するメソッド
    public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        if tableView == self.tableView {
            return true
        } else {
            return false
        }
    }
    
    // ソートボタンのアクション
    @objc func sortItems(_ sender: UITapGestureRecognizer) {
        guard let headerView = sender.view else { return }
        let tapLocation = sender.location(in: headerView)
        let stackView = headerView.subviews.first as! UIStackView
        
        for (index, view) in stackView.arrangedSubviews.enumerated() {
            if view.frame.contains(tapLocation) {
                switch index {
                case 0:
                    items.sort {
                        let number1 = Int($0.number) ?? Int.max
                        let number2 = Int($1.number) ?? Int.max
                        return number1 < number2
                    }
                    sortKey = "number"
                case 2:
                    items.sort { $0.name.localizedStandardCompare($1.name) == .orderedAscending }
                    sortKey = "name"
                case 4:
                    items.sort { $0.page < $1.page }
                    sortKey = "page"
                case 6:
                    items.sort { $0.status < $1.status }
                    sortKey = "status"
                case 8:
                    items.sort { $0.message.localizedStandardCompare($1.message) == .orderedAscending }
                    sortKey = "message"
                case 10:
                    items.sort { $0.date < $1.date }
                    sortKey = "date"
                default:
                    items.sort { $0.date < $1.date }
                    sortKey = "date"
                }
                tableView.reloadData()
                //messageView.insertText("SORT by \(sortKey)\n")
                return
            }
        }
    }
    
    //エクスポートボタン
    @objc func exportButtonTapped() {
        // データをCSV形式に変換
        var csvText = "番号,名前,ページ,状態,時間,メッセージ,コード\n"
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        for item in items {
            // Int型のプロパティをString型に変換
            let pageString = String(item.page)
            let statusString = String(item.status)
            let messageString = item.message
            let codeString = item.codetext.replacingOccurrences(of: "\n", with: "\r")
                .replacingOccurrences(of: "\"", with: "\"\"") // ダブルクォーテーションをエスケープ
            // 各フィールドをエスケープして連結
            let newLine = "\(item.number),\(item.name),\(pageString),\(statusString),\(dateFormatter.string(from: item.date)),\(messageString),\"\(codeString)\"\n"
            csvText.append(newLine)
        }
        
        if !items.isEmpty {
            // クリップボードにコピー
            UIPasteboard.general.string = csvText

            // 「コピーしました」のメッセージを短時間表示
            let alert = UIAlertController(title: nil, message: "クリップボードにコピーしました", preferredStyle: .alert)
            self.present(alert, animated: true) {
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                    alert.dismiss(animated: true, completion: nil)
                }
            }
        } else {
            // データが空の時のメッセージ
            let confirmAlert = UIAlertController(title: "コピーできません。", message: "コピーするデータがありません。", preferredStyle: .alert)
            confirmAlert.addAction(UIAlertAction(title: "OK", style: .default))
            self.present(confirmAlert, animated: true, completion: nil)
        }
    }

    
    public func didReceiveMessage(messageText: String, codeText: String) {
        // メッセージを解析して新しいアイテムを追加
        //self.messageView.insertText("受信:" + messageText)
        let components = messageText.split(separator: ",")
        if components.count == 5 {
            print("Parsed components: \(components)")
            let number = String(components[0])
            let name = String(components[1])
            if let page = Int(components[2]),
               let status = Int(components[3]) {
                let messageText = String(components[4])
                let date = Date()
                let newItem = Item(number: number, name: name, page: page, status: status, message: messageText, codetext: codeText, date: date)
                items.append(newItem)
                tableView.reloadData()
                // 最下行のインデックスパスを取得
                let lastIndexPath = IndexPath(row: self.items.count - 1, section: 0)
                // UI 更新後にスクロールを行う
                DispatchQueue.main.async {
                    self.tableView.scrollToRow(at: lastIndexPath, at: .bottom, animated: true)
                }
                saveItems()  // データを保存
                updateGroupedItems()// グループ化されたデータを更新
                summaryTableView.reloadData()
                // status に応じたサウンドを再生
                self.playSound(forStatus: status)
            } else {
                print("Failed to parse page or status")
            }
        } else {
            print("Invalid message format")
        }
    }
    
    public func didWebReceiveMessage(messageText: String, codeText: String) {
        // 受信したメッセージを処理
        DispatchQueue.main.async { [weak self] in
            // メッセージを解析して新しいアイテムを追加
            let components = messageText.split(separator: ",")
            if components.count == 5 {
                print("Parsed components: \(components)")
                let number = String(components[0])
                let name = String(components[1])
                if let page = Int(components[2]),
                   let status = Int(components[3]) {
                    let messageText = String(components[4])
                    let date = Date()
                    let newItem = Item(number: number, name: name, page: page, status: status, message: messageText, codetext: codeText, date: date)
                    self!.items.append(newItem)
                    self!.tableView.reloadData()
                    // 最下行のインデックスパスを取得
                    let lastIndexPath = IndexPath(row: self!.items.count - 1, section: 0)
                    // UI 更新後にスクロールを行う
                    DispatchQueue.main.async {
                        self!.tableView.scrollToRow(at: lastIndexPath, at: .bottom, animated: true)
                    }
                    self!.saveItems()  // データを保存
                    self!.updateGroupedItems()// グループ化されたデータを更新
                    self!.summaryTableView.reloadData()
                    // status に応じたサウンドを再生
                    self!.playSound(forStatus: status)
                } else {
                    print("Failed to parse page or status")
                }
            } else {
                self?.messageView.insertText("データエラー : " + messageText)
            }
        }
    }
    
    private func playSound(forStatus status: Int) {
        var soundFileName: String?
        
        switch status {
        case 1:
            soundFileName = "recv_sound1" // サウンドファイルの名前（拡張子は不要）
        case 2:
            soundFileName = "recv_sound2" // サウンドファイルの名前（拡張子は不要）
        default:
            print("No sound for status \(status)")
        }
        
        if let soundFileName = soundFileName {
            if let soundURL = Bundle.main.url(forResource: soundFileName, withExtension: "mp3") {
                do {
                    audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
                    audioPlayer?.play()
                } catch {
                    print("Error playing sound: \(error.localizedDescription)")
                }
            } else {
                print("Sound file \(soundFileName) not found")
            }
        }
    }
    
    public func didWebFailWithError(_ error: any Error) {
        DispatchQueue.main.async { [weak self] in
            // 修正点: エラーメッセージの表示
            self?.messageView.text += "エラー: \(error.localizedDescription)\n問い合わせを中止しました。\n"
            self?.httpPolling?.stopPolling()
        }
    }
    
    func loadItems() {
        if case let .data(encodedItems)? = PlaygroundKeyValueStore.current["items"] {
            let decoder = JSONDecoder()
            if let decodedItems = try? decoder.decode([Item].self, from: encodedItems) {
                items = decodedItems
                updateGroupedItems()
            }
        }
    }

    func saveItems() {
        let encoder = JSONEncoder()
        if let encodedItems = try? encoder.encode(items) {
            PlaygroundKeyValueStore.current["items"] = .data(encodedItems)
        }
    }
    
    func updateGroupedItems() {
        var grouped = [String: GroupedItem]()
        let blankStatus: Int = -1 // 空白文字を表すステータスの値（例えば -1）

        // データのグループ化
        for item in items {
            if var existingGroup = grouped[item.number] {
                existingGroup.statuses[item.page] = item.status
                grouped[item.number] = existingGroup
            } else {
                grouped[item.number] = GroupedItem(number: item.number, name: item.name, statuses: [item.page: item.status])
            }
        }

        // すべてのページに対してステータスが設定されていない場合に空白文字を設定
        for number in grouped.keys {
            var group = grouped[number]!
            for page in 1...17 {
                if group.statuses[page] == nil {
                    group.statuses[page] = blankStatus
                }
            }
            grouped[number] = group
        }
        // グループ化されたデータを番号でソート
        groupedItems = Array(grouped.values).sorted {
            let number1 = Int($0.number) ?? Int.max
            let number2 = Int($1.number) ?? Int.max
            return number1 < number2
        }
    }

}

extension SituationViewController: PlaygroundLiveViewMessageHandler {
    //Playgroundページからメッセージを受け取る際の処理。
    public func receive(_ message: PlaygroundValue) {
        if case let .string(text) = message {
            let arr:[String] = text.components(separatedBy: " ")
            if(arr[0] == "schoolCode") {
                return
            }
        }
    }
    //Playgroundページにメッセージを送る際のサンプル。
    //public func tapped() {
    //    send(message)
    // }
}
