//
//  settings.swift
//  Clock
//
//  Created by Serhiy Mytrovtsiy on 24/03/2023
//  Using Swift 5.0
//  Running on macOS 13.2
//
//  Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved.
//

import Cocoa
import Kit

let nameColumnID = NSUserInterfaceItemIdentifier(rawValue: "name")
let formatColumnID = NSUserInterfaceItemIdentifier(rawValue: "format")
let tzColumnID = NSUserInterfaceItemIdentifier(rawValue: "tz")
let statusColumnID = NSUserInterfaceItemIdentifier(rawValue: "status")

internal class Settings: NSStackView, Settings_v, NSTableViewDelegate, NSTableViewDataSource, NSTextFieldDelegate {
    public var callback: (() -> Void) = {}
    
    private var list: [Clock_t] {
        get {
            if let objects = Store.shared.data(key: "\(self.title)_list") {
                let decoder = JSONDecoder()
                if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [Clock_t] {
                    return objectsDecoded
                }
            }
            return [Clock.local]
        }
        set {
            if newValue.isEmpty {
                Store.shared.remove("\(self.title)_list")
            } else {
                let encoder = JSONEncoder()
                if let encoded = try? encoder.encode(newValue){
                    Store.shared.set(key: "\(self.title)_list", value: encoded)
                }
            }
        }
    }
    
    private var title: String
    private var selectedRow: Int = -1
    
    private let scrollView = NSScrollView()
    private let tableView = NSTableView()
    private var footerView: NSStackView? = nil
    private var deleteButton: NSButton? = nil
    
    public init(_ module: ModuleType) {
        self.title = module.stringValue
        
        super.init(frame: NSRect.zero)
        
        self.orientation = .vertical
        self.distribution = .gravityAreas
        self.spacing = 0
        
        self.scrollView.documentView = self.tableView
        self.scrollView.hasHorizontalScroller = false
        self.scrollView.hasVerticalScroller = true
        self.scrollView.autohidesScrollers = true
        self.scrollView.backgroundColor = NSColor.clear
        self.scrollView.drawsBackground = true
        
        self.tableView.frame = self.scrollView.bounds
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.allowsMultipleSelection = false
        self.tableView.focusRingType = .none
        self.tableView.gridColor = .gridColor
        self.tableView.columnAutoresizingStyle = .firstColumnOnlyAutoresizingStyle
        self.tableView.allowsColumnResizing = false
        self.tableView.gridStyleMask = [.solidVerticalGridLineMask, .solidHorizontalGridLineMask]
        self.tableView.usesAlternatingRowBackgroundColors = true
        if #available(macOS 11.0, *) {
            self.tableView.style = .plain
        }
        self.tableView.rowHeight = 32
        
        let nameColumn = NSTableColumn(identifier: nameColumnID)
        nameColumn.headerCell.title = localizedString("Name")
        nameColumn.headerCell.alignment = .center
        let formatColumn = NSTableColumn(identifier: formatColumnID)
        formatColumn.headerCell.title = localizedString("Format")
        formatColumn.headerCell.alignment = .center
        formatColumn.width = 160
        let tzColumn = NSTableColumn(identifier: tzColumnID)
        tzColumn.headerCell.title = localizedString("Time zone")
        tzColumn.headerCell.alignment = .center
        tzColumn.width = 132
        let statusColumn = NSTableColumn(identifier: statusColumnID)
        statusColumn.headerCell.title = ""
        statusColumn.width = 16
        
        self.tableView.addTableColumn(nameColumn)
        self.tableView.addTableColumn(formatColumn)
        self.tableView.addTableColumn(tzColumn)
        self.tableView.addTableColumn(statusColumn)
        
        let separator = NSBox()
        separator.boxType = .separator
        
        self.addArrangedSubview(self.scrollView)
        self.addArrangedSubview(separator)
        self.addArrangedSubview(self.footer())
        
        var hight: CGFloat = 296
        if #available(macOS 26.0, *) {
            hight = 290
        }
        
        NSLayoutConstraint.activate([
            self.scrollView.heightAnchor.constraint(equalToConstant: hight)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func footer() -> NSView {
        let view = NSStackView()
        view.heightAnchor.constraint(equalToConstant: 27).isActive = true
        view.spacing = 4
        view.orientation = .horizontal
        
        var addButton: NSButton {
            let btn = NSButton()
            btn.widthAnchor.constraint(equalToConstant: 27).isActive = true
            btn.heightAnchor.constraint(equalToConstant: 27).isActive = true
            btn.bezelStyle = .rounded
            if #available(macOS 11.0, *) {
                btn.image =  iconFromSymbol(name: "plus", scale: .medium)
            } else {
                btn.title = localizedString("Add")
            }
            btn.action = #selector(self.addNewClock)
            btn.target = self
            btn.toolTip = localizedString("Add new clock")
            btn.focusRingType = .none
            return btn
        }
        var deleteButton: NSButton {
            let btn = NSButton()
            btn.widthAnchor.constraint(equalToConstant: 27).isActive = true
            btn.heightAnchor.constraint(equalToConstant: 27).isActive = true
            btn.bezelStyle = .rounded
            if #available(macOS 11.0, *) {
                btn.image =  iconFromSymbol(name: "minus", scale: .medium)
            } else {
                btn.title = localizedString("Delete")
            }
            btn.action = #selector(self.deleteClock)
            btn.target = self
            btn.toolTip = localizedString("Delete selected clock")
            btn.focusRingType = .none
            return btn
        }
        self.deleteButton = deleteButton
        
        view.addArrangedSubview(addButton)
        view.addArrangedSubview(NSView())
        
        let helpBtn = NSButton()
        helpBtn.widthAnchor.constraint(equalToConstant: 27).isActive = true
        helpBtn.heightAnchor.constraint(equalToConstant: 27).isActive = true
        helpBtn.bezelStyle = .helpButton
        helpBtn.title = ""
        helpBtn.action = #selector(self.openFormatHelp)
        helpBtn.target = self
        helpBtn.toolTip = localizedString("Help with datetime format")
        view.addArrangedSubview(helpBtn)
        
        self.footerView = view
        return view
    }
    
    func load(widgets: [Kit.widget_t]) {
        self.tableView.reloadData()
    }
    
    func numberOfRows(in tableView: NSTableView) -> Int {
        return self.list.count
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        guard let id = tableColumn?.identifier else { return nil }
        let cell = NSTableCellView()
        let item = self.list[row]
        
        switch id {
        case nameColumnID, formatColumnID:
            let text: NSTextField = NSTextField()
            text.identifier = id
            text.drawsBackground = false
            text.isBordered = false
            text.sizeToFit()
            text.delegate = self
            text.stringValue = id == nameColumnID ? item.name : item.format
            text.translatesAutoresizingMaskIntoConstraints = false
            cell.addSubview(text)
            text.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true
            text.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
        case tzColumnID:
            let select: NSPopUpButton = selectView(action: #selector(self.toggleTZ), items: Clock.zones, selected: item.tz)
            select.identifier = NSUserInterfaceItemIdentifier("\(row)")
            select.sizeToFit()
            select.preferredEdge = .maxX
            select.translatesAutoresizingMaskIntoConstraints = false
            select.widthAnchor.constraint(lessThanOrEqualToConstant: 132).isActive = true
            cell.addSubview(select)
        case statusColumnID:
            let button: NSButton = NSButton(frame: NSRect(x: 0, y: 8, width: 10, height: 10))
            button.identifier = NSUserInterfaceItemIdentifier("\(row)")
            button.setButtonType(.switch)
            button.state = item.enabled ? .on : .off
            button.action = #selector(self.toggleClock)
            button.title = ""
            button.isBordered = false
            button.isTransparent = false
            button.target = self
            button.sizeToFit()
            cell.addSubview(button)
        default: break
        }
        
        return cell
    }
    
    func controlTextDidChange(_ notification: Notification) {
        if let textField = notification.object as? NSTextField, let id = textField.identifier {
            let i = self.tableView.selectedRow
            switch id {
            case nameColumnID:
                self.list[i].name = textField.stringValue
            case formatColumnID:
                self.list[i].format = textField.stringValue
            default: return
            }
        }
    }
    
    func tableViewSelectionDidChange(_ notification: Notification) {
        if self.tableView.selectedRow == -1 {
            self.deleteButton?.removeFromSuperview()
        } else {
            if let btn = self.deleteButton {
                self.footerView?.insertArrangedSubview(btn, at: 1)
            }
        }
    }
    
    @objc private func toggleTZ(_ sender: NSMenuItem) {
        guard let key = sender.representedObject as? String, let id = sender.identifier, let i = Int(id.rawValue) else { return }
        self.list[i].tz = key
    }
    @objc private func toggleClock(_ sender: NSButton) {
        guard let id = sender.identifier, let i = Int(id.rawValue) else { return }
        self.list[i].enabled = sender.state == NSControl.StateValue.on
    }
    @objc private func addNewClock(_ sender: Any) {
        self.list.append(Clock_t(name: "\(localizedString("Clock")) \(self.list.count)", format: Clock.local.format, tz: Clock.local.tz))
        self.tableView.reloadData()
    }
    @objc private func deleteClock(_ sender: Any) {
        guard self.tableView.selectedRow != -1 else { return }
        self.list.remove(at: self.tableView.selectedRow)
        self.tableView.reloadData()
        self.deleteButton?.removeFromSuperview()
    }
    @objc private func openFormatHelp(_ sender: NSButton) {
        NSWorkspace.shared.open(URL(string: "https://www.nsdateformatter.com")!)
    }
}
