import AppKit
import VoiceCatCore

final class AccountsSheet: NSViewController {

    private let client: VoiceCatClient
    private var accounts: [Account] = []
    private let tableView = NSTableView()
    private let statusLabel = NSTextField(labelWithString: "Loading…")

    init(client: VoiceCatClient) {
        self.client = client
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) { fatalError() }

    override func loadView() {
        view = NSView(frame: NSRect(x: 0, y: 0, width: 480, height: 340))
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        buildUI()
        refreshAccounts()
    }

    private func buildUI() {
        let titleLabel = NSTextField(labelWithString: "Server Accounts")
        titleLabel.font = .boldSystemFont(ofSize: 13)

        let userCol = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("username"))
        userCol.title = "Username"; userCol.width = 160
        let adminCol = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("admin"))
        adminCol.title = "Admin"; adminCol.width = 60
        let createdCol = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("created"))
        createdCol.title = "Created"; createdCol.width = 120
        let loginCol = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("login"))
        loginCol.title = "Last Login"; loginCol.width = 120

        tableView.addTableColumn(userCol)
        tableView.addTableColumn(adminCol)
        tableView.addTableColumn(createdCol)
        tableView.addTableColumn(loginCol)
        tableView.dataSource = self; tableView.delegate = self
        tableView.allowsMultipleSelection = false
        tableView.setAccessibilityLabel("Server accounts")

        let sv = NSScrollView()
        sv.documentView = tableView; sv.hasVerticalScroller = true
        sv.borderType = .bezelBorder

        let refreshButton = NSButton(title: "Refresh", target: self, action: #selector(refreshClicked))
        refreshButton.bezelStyle = .rounded
        refreshButton.setAccessibilityLabel("Refresh account list")

        let addButton = NSButton(title: "Add…", target: self, action: #selector(addClicked))
        addButton.bezelStyle = .rounded
        addButton.setAccessibilityLabel("Add new account")

        let resetPwButton = NSButton(title: "Reset Password…", target: self, action: #selector(resetPwClicked))
        resetPwButton.bezelStyle = .rounded
        resetPwButton.setAccessibilityLabel("Reset selected account password")

        let deleteButton = NSButton(title: "Delete…", target: self, action: #selector(deleteClicked))
        deleteButton.bezelStyle = .rounded
        deleteButton.setAccessibilityLabel("Delete selected account")

        let doneButton = NSButton(title: "Done", target: self, action: #selector(doneClicked))
        doneButton.bezelStyle = .rounded; doneButton.keyEquivalent = "\r"
        doneButton.setAccessibilityLabel("Close accounts sheet")

        statusLabel.textColor = .secondaryLabelColor
        statusLabel.setAccessibilityLabel("Status")

        let toolbar = NSStackView(views: [refreshButton, addButton, resetPwButton, deleteButton, NSView()])
        toolbar.orientation = .horizontal; toolbar.spacing = 8

        let bottomRow = NSStackView(views: [statusLabel, NSView(), doneButton])
        bottomRow.orientation = .horizontal; bottomRow.spacing = 8

        let stack = NSStackView(views: [titleLabel, sv, toolbar, bottomRow])
        stack.orientation = .vertical; stack.spacing = 10
        stack.edgeInsets = NSEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
        stack.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stack)
        NSLayoutConstraint.activate([
            stack.topAnchor.constraint(equalTo: view.topAnchor),
            stack.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            stack.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            stack.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            sv.heightAnchor.constraint(equalToConstant: 200),
        ])

        client.onEvent = { [weak self] event in
            if event.type == .accountList { self?.pullAccounts() }
        }
    }

    private func refreshAccounts() {
        statusLabel.stringValue = "Loading…"
        client.requestAccountList()
    }

    private func pullAccounts() {
        accounts = client.listAccounts()
        tableView.reloadData()
        statusLabel.stringValue = "\(accounts.count) account\(accounts.count == 1 ? "" : "s")"
    }

    @objc private func refreshClicked() { refreshAccounts() }

    @objc private func addClicked() {
        let sheet = InputSheet(title: "New Account", prompt: "Username:", defaultValue: "")
        sheet.onComplete = { [weak self] username in
            guard let self, let username, !username.isEmpty else { return }
            let pwSheet = PasswordPromptSheet(prompt: "Password for \(username):")
            pwSheet.onComplete = { [weak self] password in
                guard let self, let password, !password.isEmpty else { return }
                let r = self.client.createAccount(username, password: password)
                if r == .ok {
                    self.statusLabel.stringValue = "Account '\(username)' created."
                    self.refreshAccounts()
                } else {
                    self.statusLabel.stringValue = "Failed: \(r.description)"
                }
            }
            self.presentAsSheet(pwSheet)
        }
        presentAsSheet(sheet)
    }

    @objc private func resetPwClicked() {
        let row = tableView.selectedRow
        guard row >= 0, row < accounts.count else { return }
        let account = accounts[row]
        let sheet = PasswordPromptSheet(prompt: "New password for \(account.username):")
        sheet.onComplete = { [weak self] password in
            guard let self, let password, !password.isEmpty else { return }
            let r = self.client.resetPassword(account.username, newPassword: password)
            self.statusLabel.stringValue = r == .ok
                ? "Password reset for '\(account.username)'."
                : "Failed: \(r.description)"
        }
        presentAsSheet(sheet)
    }

    @objc private func deleteClicked() {
        let row = tableView.selectedRow
        guard row >= 0, row < accounts.count else { return }
        let account = accounts[row]
        let alert = NSAlert()
        alert.messageText = "Delete account '\(account.username)'?"
        alert.informativeText = "This cannot be undone."
        alert.addButton(withTitle: "Delete"); alert.addButton(withTitle: "Cancel")
        alert.alertStyle = .warning
        guard let window = view.window else { return }
        alert.beginSheetModal(for: window) { [weak self] response in
            guard response == .alertFirstButtonReturn, let self else { return }
            let r = self.client.deleteAccount(account.username)
            self.statusLabel.stringValue = r == .ok
                ? "Account '\(account.username)' deleted."
                : "Failed: \(r.description)"
            if r == .ok { self.refreshAccounts() }
        }
    }

    @objc private func doneClicked() { dismiss(nil) }

    private func dateString(_ ms: UInt64) -> String {
        guard ms > 0 else { return "—" }
        let date = Date(timeIntervalSince1970: Double(ms) / 1000.0)
        return DateFormatter.localizedString(from: date, dateStyle: .short, timeStyle: .none)
    }
}

// MARK: - NSTableViewDataSource / Delegate

extension AccountsSheet: NSTableViewDataSource, NSTableViewDelegate {
    func numberOfRows(in tableView: NSTableView) -> Int { accounts.count }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let acc = accounts[row]
        let id = tableColumn?.identifier ?? NSUserInterfaceItemIdentifier("cell")
        let cell = tableView.makeView(withIdentifier: id, owner: nil) as? NSTableCellView
                   ?? makeCell(id)
        switch tableColumn?.identifier.rawValue {
        case "username": cell.textField?.stringValue = acc.username
        case "admin":    cell.textField?.stringValue = acc.isAdmin ? "Yes" : ""
        case "created":  cell.textField?.stringValue = dateString(acc.createdAtUnixMs)
        case "login":    cell.textField?.stringValue = dateString(acc.lastLoginUnixMs)
        default: break
        }
        return cell
    }

    private func makeCell(_ id: NSUserInterfaceItemIdentifier) -> NSTableCellView {
        let cell = NSTableCellView(); cell.identifier = id
        let tf = NSTextField(labelWithString: "")
        tf.translatesAutoresizingMaskIntoConstraints = false
        cell.addSubview(tf); cell.textField = tf
        NSLayoutConstraint.activate([
            tf.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 4),
            tf.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -4),
            tf.centerYAnchor.constraint(equalTo: cell.centerYAnchor),
        ])
        return cell
    }
}
