import UIKit

@MainActor
final class SettingsViewController: UITableViewController {
    private let context: AppContext
    private let appearanceControl = UISegmentedControl(items: ["Auto", "Light", "Dark"])
    private let notificationSwitch = UISwitch()
    private var notificationStatus = "Managed by iOS"

    init(context: AppContext) {
        self.context = context
        super.init(style: .insetGrouped)
        title = "Settings"
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }

    override func viewDidLoad() {
        super.viewDidLoad()
        let settings = context.core.settings()
        appearanceControl.selectedSegmentIndex = Int(settings.appearance)
        appearanceControl.addTarget(self, action: #selector(appearanceChanged), for: .valueChanged)
        notificationSwitch.isOn = settings.notificationsEnabled
        notificationSwitch.accessibilityLabel = "Background notifications"
        notificationSwitch.addTarget(self, action: #selector(notificationsChanged), for: .valueChanged)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        notificationSwitch.isOn = context.core.settings().notificationsEnabled
        Task {
            notificationStatus = await context.notifications.authorizationDescription()
            updateNotificationSettingsCell()
        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int { 2 }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        section == 0 ? 1 : 2
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        section == 0 ? "Appearance" : "Notifications"
    }

    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        if section == 0 {
            return "Follow iOS automatically or choose a fixed appearance."
        }
        return "Gotcha checks periodically for server notifications. iOS decides when background refresh runs; delivery style, sounds, Focus, and summaries remain under your control in iOS Settings."
    }

    override func tableView(
        _ tableView: UITableView,
        cellForRowAt indexPath: IndexPath
    ) -> UITableViewCell {
        guard indexPath.section == 0 else {
            if indexPath.row == 0 {
                let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
                var content = cell.defaultContentConfiguration()
                content.text = "Background notifications"
                cell.contentConfiguration = content
                cell.accessoryView = notificationSwitch
                cell.selectionStyle = .none
                return cell
            }
            let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
            var content = cell.defaultContentConfiguration()
            content.text = "Notification Settings"
            content.secondaryText = notificationStatus
            cell.contentConfiguration = content
            cell.accessoryType = .disclosureIndicator
            return cell
        }
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        appearanceControl.translatesAutoresizingMaskIntoConstraints = false
        cell.contentView.addSubview(appearanceControl)
        NSLayoutConstraint.activate([
            appearanceControl.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 16),
            appearanceControl.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: -16),
            appearanceControl.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 8),
            appearanceControl.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: -8),
        ])
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        guard indexPath.section == 1, indexPath.row == 1 else { return }
        context.notifications.openSystemSettings()
    }

    @objc private func appearanceChanged() {
        do {
            try context.core.setAppearance(index: UInt32(appearanceControl.selectedSegmentIndex))
            context.applyAppearance()
        } catch {
            show(error: error)
        }
    }

    @objc private func notificationsChanged() {
        let requested = notificationSwitch.isOn
        notificationSwitch.isEnabled = false
        Task {
            do {
                let enabled = try await context.notifications.setEnabled(requested)
                notificationSwitch.isOn = enabled
                if requested && !enabled { showNotificationsDisabledAlert() }
            } catch {
                notificationSwitch.isOn = context.core.settings().notificationsEnabled
                show(error: error)
            }
            notificationSwitch.isEnabled = true
            notificationStatus = await context.notifications.authorizationDescription()
            updateNotificationSettingsCell()
        }
    }

    private func updateNotificationSettingsCell() {
        guard let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 1)) else { return }
        var content = cell.defaultContentConfiguration()
        content.text = "Notification Settings"
        content.secondaryText = notificationStatus
        cell.contentConfiguration = content
    }

    private func showNotificationsDisabledAlert() {
        let alert = UIAlertController(
            title: "Notifications Are Disabled",
            message: "Allow notifications in iOS Settings, then turn Background notifications on again.",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "Not Now", style: .cancel))
        alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { [weak self] _ in
            self?.context.notifications.openSystemSettings()
        })
        present(alert, animated: true)
    }
}
