//
//  EditSourceView.swift
//  Yattee
//
//  Unified sheet for editing any source type.
//

import SwiftUI

struct EditSourceView: View {
    let source: UnifiedSource

    @Environment(\.dismiss) private var dismiss
    @Environment(\.appEnvironment) private var appEnvironment

    var body: some View {
        switch source {
        case .remoteServer(let instance):
            EditRemoteServerContent(instance: instance)
        case .fileSource(let mediaSource):
            EditFileSourceContent(source: mediaSource)
        }
    }
}

// MARK: - Remote Server Content

private struct EditRemoteServerContent: View {
    let instance: Instance

    @Environment(\.dismiss) private var dismiss
    @Environment(\.appEnvironment) private var appEnvironment

    @State private var name: String
    @State private var isEnabled: Bool
    @State private var allowInvalidCertificates: Bool

    // Yattee Server credentials
    @State private var yatteeServerUsername: String = ""
    @State private var yatteeServerPassword: String = ""

    // Invidious login state
    @State private var showLoginSheet = false
    @State private var isLoggedIn = false

    // Yattee Server validation
    @State private var showingYatteeServerWarning = false

    // Delete confirmation
    @State private var showingDeleteConfirmation = false

    // Yattee Server info
    @State private var serverInfo: InstanceDetectorModels.YatteeServerFullInfo?
    @State private var isLoadingServerInfo = false
    @State private var serverInfoError: String?

    // Connection testing
    @State private var isTesting = false
    @State private var testResult: RemoteServerTestResult?

    enum RemoteServerTestResult {
        case success
        case failure(String)
    }

    init(instance: Instance) {
        self.instance = instance
        _name = State(initialValue: instance.name ?? "")
        _isEnabled = State(initialValue: instance.isEnabled)
        _allowInvalidCertificates = State(initialValue: instance.allowInvalidCertificates)
    }

    var body: some View {
        NavigationStack {
            #if os(tvOS)
            VStack(spacing: 0) {
                HStack {
                    Button(String(localized: "common.cancel")) {
                        dismiss()
                    }
                    .buttonStyle(TVToolbarButtonStyle())
                    Spacer()
                    Text(String(localized: "sources.editSource"))
                        .font(.title2)
                        .fontWeight(.semibold)
                    Spacer()
                    Button(String(localized: "common.save")) {
                        saveChanges()
                    }
                    .buttonStyle(TVToolbarButtonStyle())
                }
                .padding(.horizontal, 48)
                .padding(.vertical, 24)

                formContent
                .accessibilityIdentifier("editSource.view")
            }
            #else
            formContent
                .navigationTitle(String(localized: "sources.editSource"))
                #if os(iOS)
                .navigationBarTitleDisplayMode(.inline)
                #endif
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button(String(localized: "common.cancel")) {
                            dismiss()
                        }
                    }
                    ToolbarItem(placement: .confirmationAction) {
                        Button(String(localized: "common.save")) {
                            saveChanges()
                        }
                    }
                }
                .accessibilityIdentifier("editSource.view")
            #endif
        }
    }

    private var formContent: some View {
        Form {
            Section {
                LabeledContent(String(localized: "sources.field.type"), value: instance.type.displayName)
                LabeledContent(String(localized: "sources.field.url"), value: instance.url.absoluteString)
            }

            Section {
                #if os(tvOS)
                TVSettingsTextField(title: String(localized: "sources.field.name"), text: $name)
                TVSettingsToggle(title: String(localized: "sources.field.enabled"), isOn: $isEnabled)
                #else
                TextField(String(localized: "sources.field.name"), text: $name)
                Toggle(String(localized: "sources.field.enabled"), isOn: $isEnabled)
                #endif
            }

            if instance.type == .yatteeServer {
                Section {
                    #if os(tvOS)
                    TVSettingsTextField(title: String(localized: "sources.field.username"), text: $yatteeServerUsername)
                    TVSettingsTextField(title: String(localized: "sources.field.password"), text: $yatteeServerPassword, isSecure: true)
                    #else
                    TextField(String(localized: "sources.field.username"), text: $yatteeServerUsername)
                        .textContentType(.username)
                        #if os(iOS)
                        .textInputAutocapitalization(.never)
                        #endif
                        .autocorrectionDisabled()

                    SecureField(String(localized: "sources.field.password"), text: $yatteeServerPassword)
                        .textContentType(.password)
                    #endif
                } header: {
                    Text(String(localized: "sources.header.auth"))
                } footer: {
                    Text(String(localized: "sources.footer.yatteeServerAuth"))
                }

                // Server Info Section
                Section {
                    if isLoadingServerInfo {
                        HStack {
                            ProgressView()
                                .controlSize(.small)
                            Text(String(localized: "sources.serverInfo.loading"))
                                .foregroundStyle(.secondary)
                        }
                    } else if let info = serverInfo {
                        LabeledContent(String(localized: "sources.field.serverVersion"), value: info.version ?? "—")
                        LabeledContent(String(localized: "sources.field.ytdlp"), value: info.dependencies?.ytDlp ?? "—")
                        LabeledContent(String(localized: "sources.field.ffmpeg"), value: info.dependencies?.ffmpeg ?? "—")
                        LabeledContent(String(localized: "sources.field.invidiousInstance"), value: invidiousDisplayValue(info))

                        // Extractors section
                        if info.config?.allowAllSitesForExtraction == true {
                            LabeledContent(String(localized: "sources.field.extractors"), value: String(localized: "sources.serverInfo.allSitesSupported"))
                        } else if let sites = info.sites, !sites.isEmpty {
                            #if os(tvOS)
                            LabeledContent(String(localized: "sources.field.extractors"), value: "\(sites.count)")
                            #else
                            DisclosureGroup(String(localized: "sources.serverInfo.enabledExtractors \(sites.count)")) {
                                ForEach(sites, id: \.name) { site in
                                    Text(site.name)
                                        .foregroundStyle(.secondary)
                                }
                            }
                            #endif
                        } else {
                            LabeledContent(String(localized: "sources.field.extractors"), value: String(localized: "sources.serverInfo.noneConfigured"))
                        }
                    } else if let error = serverInfoError {
                        Label(error, systemImage: "exclamationmark.triangle")
                            .foregroundStyle(.orange)
                    }
                } header: {
                    Text(String(localized: "sources.header.serverInfo"))
                }
            }

            if instance.supportsAuthentication {
                Section {
                    if isLoggedIn {
                        Button(role: .destructive) {
                            logout()
                        } label: {
                            Label(String(localized: "login.logout"), systemImage: "rectangle.portrait.and.arrow.forward")
                        }
                        #if os(tvOS)
                        .buttonStyle(TVSettingsButtonStyle())
                        #endif
                    } else {
                        Button {
                            showLoginSheet = true
                        } label: {
                            Label(String(localized: "login.loginToAccount"), systemImage: "person.badge.key")
                        }
                        #if os(tvOS)
                        .buttonStyle(TVSettingsButtonStyle())
                        #endif
                    }
                } header: {
                    Text(String(localized: "login.header.account"))
                } footer: {
                    if isLoggedIn {
                        Text(String(localized: "login.footer.loggedIn"))
                    } else {
                        Text(String(localized: "login.footer.loginBenefits"))
                    }
                }

                // Import section - show when logged in for Invidious and Piped instances
                if isLoggedIn && (instance.type == .invidious || instance.type == .piped) {
                    Section {
                        NavigationLink {
                            ImportSubscriptionsView(instance: instance)
                        } label: {
                            Label(String(localized: "sources.import.subscriptions"), systemImage: "person.2")
                        }
                        .accessibilityIdentifier("sources.import.subscriptions")

                        NavigationLink {
                            ImportPlaylistsView(instance: instance)
                        } label: {
                            Label(String(localized: "sources.import.playlists"), systemImage: "list.bullet.rectangle")
                        }
                        .accessibilityIdentifier("sources.import.playlists")
                    } header: {
                        Text(String(localized: "sources.header.import"))
                    }
                }
            }

            Section {
                #if os(tvOS)
                TVSettingsToggle(
                    title: String(localized: "sources.field.allowInvalidCertificates"),
                    isOn: $allowInvalidCertificates
                )
                #else
                Toggle(String(localized: "sources.field.allowInvalidCertificates"), isOn: $allowInvalidCertificates)
                #endif
            } header: {
                Text(String(localized: "sources.header.security"))
            } footer: {
                Text(String(localized: "sources.footer.allowInvalidCertificates"))
            }

            Section {
                Button {
                    testConnection()
                } label: {
                    if isTesting {
                        HStack {
                            ProgressView()
                                .controlSize(.small)
                            Text(String(localized: "sources.testing"))
                        }
                    } else {
                        Label(String(localized: "sources.testConnection"), systemImage: "network")
                    }
                }
                .disabled(isTesting)
                #if os(tvOS)
                .buttonStyle(TVSettingsButtonStyle())
                #endif
            }

            if let result = testResult {
                testResultSection(result)
            }

            Section {
                Button(role: .destructive) {
                    showingDeleteConfirmation = true
                } label: {
                    Label(String(localized: "sources.deleteSource"), systemImage: "trash")
                }
                #if os(tvOS)
                .buttonStyle(TVSettingsButtonStyle())
                #endif
            }
        }
        #if os(iOS)
        .scrollDismissesKeyboard(.interactively)
        #endif
        .confirmationDialog(
            String(localized: "sources.delete.confirmation.single \(instance.displayName)"),
            isPresented: $showingDeleteConfirmation,
            titleVisibility: .visible
        ) {
            Button(String(localized: "common.delete"), role: .destructive) {
                appEnvironment?.instancesManager.remove(instance)
                dismiss()
            }
            Button(String(localized: "common.cancel"), role: .cancel) {}
        }
        .sheet(isPresented: $showLoginSheet) {
            InstanceLoginView(instance: instance) { credential in
                appEnvironment?.credentialsManager(for: instance)?.setCredential(credential, for: instance)
                isLoggedIn = true
            }
        }
        .onAppear {
            isLoggedIn = appEnvironment?.credentialsManager(for: instance)?.isLoggedIn(for: instance) ?? false

            // Load existing Yattee Server credentials
            if instance.type == .yatteeServer,
               let credentials = appEnvironment?.yatteeServerCredentialsManager.credentials(for: instance) {
                yatteeServerUsername = credentials.username
                yatteeServerPassword = credentials.password
            }
        }
        .task {
            await loadServerInfo()
        }
        .confirmationDialog(
            String(localized: "sources.yatteeServer.warning.title"),
            isPresented: $showingYatteeServerWarning,
            titleVisibility: .visible
        ) {
            Button(String(localized: "sources.yatteeServer.warning.disableOthers"), role: .destructive) {
                appEnvironment?.instancesManager.disableOtherYatteeServerInstances(except: instance.id)
                performSave()
            }
            Button(String(localized: "common.cancel"), role: .cancel) {}
        } message: {
            Text(String(localized: "sources.yatteeServer.warning.message"))
        }
    }

    // MARK: - Computed Properties

    private var hasYatteeServer: Bool {
        appEnvironment?.instancesManager.hasYatteeServerInstances ?? false
    }

    private func invidiousDisplayValue(_ info: InstanceDetectorModels.YatteeServerFullInfo) -> String {
        guard let invidiousInstance = info.config?.invidiousInstance else {
            return String(localized: "sources.serverInfo.notConfigured")
        }
        if invidiousInstance == "not configured" || invidiousInstance.isEmpty {
            return String(localized: "sources.serverInfo.notConfigured")
        }
        // Extract just the host from the URL for cleaner display
        if let url = URL(string: invidiousInstance), let host = url.host {
            return host
        }
        return invidiousInstance
    }

    // MARK: - Actions

    private func logout() {
        appEnvironment?.credentialsManager(for: instance)?.deleteCredential(for: instance)
        isLoggedIn = false
    }

    private func loadServerInfo() async {
        guard instance.type == .yatteeServer, let appEnvironment else { return }

        isLoadingServerInfo = true
        serverInfoError = nil

        do {
            serverInfo = try await appEnvironment.contentService.yatteeServerInfo(for: instance)
        } catch {
            serverInfoError = String(localized: "sources.serverInfo.loadError")
        }

        isLoadingServerInfo = false
    }

    private func saveChanges() {
        // Check if we're enabling a Yattee Server instance
        let wasDisabled = !instance.isEnabled
        let willBeEnabled = isEnabled
        let isYatteeServer = instance.type == .yatteeServer

        if isYatteeServer && wasDisabled && willBeEnabled {
            let otherEnabled = appEnvironment?.instancesManager.enabledYatteeServerInstances ?? []
            if !otherEnabled.isEmpty {
                showingYatteeServerWarning = true
                return
            }
        }

        performSave()
    }

    private func performSave() {
        var updated = instance
        updated.name = name.isEmpty ? nil : name
        updated.isEnabled = isEnabled
        updated.allowInvalidCertificates = allowInvalidCertificates

        // Save Yattee Server credentials if provided
        if instance.type == .yatteeServer && !yatteeServerUsername.isEmpty && !yatteeServerPassword.isEmpty {
            appEnvironment?.yatteeServerCredentialsManager.setCredentials(
                username: yatteeServerUsername,
                password: yatteeServerPassword,
                for: instance
            )
        }

        appEnvironment?.instancesManager.update(updated)
        dismiss()
    }

    private func testConnection() {
        guard let appEnvironment else { return }
        isTesting = true
        testResult = nil

        Task {
            do {
                _ = try await appEnvironment.contentService.popular(for: instance)
                await MainActor.run {
                    isTesting = false
                    testResult = .success
                }
            } catch {
                await MainActor.run {
                    isTesting = false
                    testResult = .failure(error.localizedDescription)
                }
            }
        }
    }

    @ViewBuilder
    private func testResultSection(_ result: RemoteServerTestResult) -> some View {
        Section {
            switch result {
            case .success:
                Label(String(localized: "sources.test.success"), systemImage: "checkmark.circle.fill")
                    .foregroundStyle(.green)
            case .failure(let error):
                Label(error, systemImage: "xmark.circle.fill")
                    .foregroundStyle(.red)
            }
        }
    }
}

// MARK: - File Source Content

private struct EditFileSourceContent: View {
    let source: MediaSource

    @Environment(\.dismiss) private var dismiss
    @Environment(\.appEnvironment) private var appEnvironment

    @State private var name: String
    @State private var isEnabled: Bool
    @State private var username: String
    @State private var password: String
    @State private var allowInvalidCertificates: Bool
    @State private var smbProtocolVersion: SMBProtocol = .auto
    @State private var isTesting = false
    @State private var testResult: TestResult?
    @State private var testProgress: String?
    @State private var hasExistingPassword = false
    @State private var showingDeleteConfirmation = false

    enum TestResult {
        case success
        case successWithBandwidth(BandwidthTestResult)
        case failure(String)
    }

    init(source: MediaSource) {
        self.source = source
        _name = State(initialValue: source.name)
        _isEnabled = State(initialValue: source.isEnabled)
        _username = State(initialValue: source.username ?? "")
        _password = State(initialValue: "")
        _allowInvalidCertificates = State(initialValue: source.allowInvalidCertificates)
    }

    var body: some View {
        NavigationStack {
            #if os(tvOS)
            VStack(spacing: 0) {
                HStack {
                    Button(String(localized: "common.cancel")) {
                        dismiss()
                    }
                    .buttonStyle(TVToolbarButtonStyle())
                    Spacer()
                    Text(String(localized: "sources.editSource"))
                        .font(.title2)
                        .fontWeight(.semibold)
                    Spacer()
                    Button(String(localized: "common.save")) {
                        saveChanges()
                    }
                    .disabled(name.isEmpty)
                    .buttonStyle(TVToolbarButtonStyle())
                }
                .padding(.horizontal, 48)
                .padding(.vertical, 24)

                formContent
            }
            .onAppear {
                hasExistingPassword = appEnvironment?.mediaSourcesManager.password(for: source) != nil
                smbProtocolVersion = source.smbProtocolVersion ?? .auto
            }
            #else
            formContent
                .navigationTitle(String(localized: "sources.editSource"))
                #if os(iOS)
                .navigationBarTitleDisplayMode(.inline)
                #endif
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button(String(localized: "common.cancel")) {
                            dismiss()
                        }
                    }

                    ToolbarItem(placement: .confirmationAction) {
                        Button(String(localized: "common.save")) {
                            saveChanges()
                        }
                        .disabled(name.isEmpty)
                    }
                }
                .onAppear {
                    hasExistingPassword = appEnvironment?.mediaSourcesManager.password(for: source) != nil
                    smbProtocolVersion = source.smbProtocolVersion ?? .auto
                }
            #endif
        }
    }

    private var formContent: some View {
        Form {
            Section {
                #if os(tvOS)
                TVSettingsTextField(title: String(localized: "sources.field.name"), text: $name)
                TVSettingsToggle(title: String(localized: "sources.field.enabled"), isOn: $isEnabled)
                #else
                TextField(String(localized: "sources.field.name"), text: $name)
                Toggle(String(localized: "sources.field.enabled"), isOn: $isEnabled)
                #endif
            } header: {
                Text(String(localized: "sources.header.general"))
            }

            Section {
                HStack {
                    Text(String(localized: "sources.field.type"))
                    Spacer()
                    Label(source.type.displayName, systemImage: source.type.systemImage)
                        .foregroundStyle(.secondary)
                }
                #if !os(tvOS)
                .alignmentGuide(.listRowSeparatorLeading) { d in d[.leading] }
                #endif

                #if os(macOS)
                HStack {
                    Text(String(localized: "sources.field.url"))
                    Spacer()
                    Text(source.url.absoluteString)
                        .foregroundStyle(.secondary)
                        .lineLimit(1)
                }
                #else
                if source.type != .localFolder {
                    HStack {
                        Text(String(localized: "sources.field.url"))
                        Spacer()
                        Text(source.url.absoluteString)
                            .foregroundStyle(.secondary)
                            .lineLimit(1)
                    }
                }
                #endif
            }

            if source.type == .webdav || source.type == .smb {
                Section {
                    #if os(tvOS)
                    TVSettingsTextField(title: String(localized: "sources.field.username"), text: $username)
                    TVSettingsTextField(
                        title: hasExistingPassword
                            ? String(localized: "sources.field.passwordKeep")
                            : String(localized: "sources.field.passwordRequired"),
                        text: $password,
                        isSecure: true
                    )
                    #else
                    TextField(String(localized: "sources.field.username"), text: $username)
                        .textContentType(.username)
                        #if os(iOS)
                        .textInputAutocapitalization(.never)
                        #endif
                        .autocorrectionDisabled()

                    SecureField(
                        hasExistingPassword
                            ? String(localized: "sources.field.passwordKeep")
                            : String(localized: "sources.field.passwordRequired"),
                        text: $password
                    )
                    .textContentType(.password)
                    #endif
                } header: {
                    Text(String(localized: "sources.header.auth"))
                }
            }

            if source.type == .smb {
                Section {
                    Picker(String(localized: "sources.field.smbProtocol"), selection: $smbProtocolVersion) {
                        ForEach(SMBProtocol.allCases, id: \.self) { proto in
                            Text(proto.displayName).tag(proto)
                        }
                    }
                } header: {
                    Text(String(localized: "sources.header.advanced"))
                } footer: {
                    Text(String(localized: "sources.footer.smbProtocol"))
                }
            }

            if source.type == .webdav {
                Section {
                    #if os(tvOS)
                    TVSettingsToggle(
                        title: String(localized: "sources.field.allowInvalidCertificates"),
                        isOn: $allowInvalidCertificates
                    )
                    #else
                    Toggle(String(localized: "sources.field.allowInvalidCertificates"), isOn: $allowInvalidCertificates)
                    #endif
                } header: {
                    Text(String(localized: "sources.header.security"))
                } footer: {
                    Text(String(localized: "sources.footer.allowInvalidCertificates"))
                }

                Section {
                    Button {
                        testConnection()
                    } label: {
                        if isTesting {
                            HStack {
                                ProgressView()
                                    .controlSize(.small)
                                Text(testProgress ?? String(localized: "sources.testing"))
                            }
                        } else {
                            Label(String(localized: "sources.testConnection"), systemImage: "speedometer")
                        }
                    }
                    .disabled(isTesting)
                    #if os(tvOS)
                    .buttonStyle(TVSettingsButtonStyle())
                    #endif
                }

                if let result = testResult {
                    testResultSection(result)
                }
            }

            Section {
                Button(role: .destructive) {
                    showingDeleteConfirmation = true
                } label: {
                    Label(String(localized: "sources.deleteSource"), systemImage: "trash")
                        .foregroundStyle(.red)
                }
                #if os(tvOS)
                .buttonStyle(TVSettingsButtonStyle())
                #endif
            }
        }
        #if os(iOS)
        .scrollDismissesKeyboard(.interactively)
        #endif
        .confirmationDialog(
            String(localized: "sources.delete.confirmation.single \(source.name)"),
            isPresented: $showingDeleteConfirmation,
            titleVisibility: .visible
        ) {
            Button(String(localized: "common.delete"), role: .destructive) {
                deleteSource()
            }
            Button(String(localized: "common.cancel"), role: .cancel) {}
        }
    }

    @ViewBuilder
    private func testResultSection(_ result: TestResult) -> some View {
        Section {
            switch result {
            case .success:
                Label(String(localized: "sources.status.connected"), systemImage: "checkmark.circle.fill")
                    .foregroundStyle(.green)
            case .successWithBandwidth(let bandwidth):
                VStack(alignment: .leading, spacing: 4) {
                    Label(String(localized: "sources.status.connected"), systemImage: "checkmark.circle.fill")
                        .foregroundStyle(.green)
                    if bandwidth.hasWriteAccess {
                        if let upload = bandwidth.formattedUploadSpeed {
                            Label(String(localized: "sources.bandwidth.upload \(upload)"), systemImage: "arrow.up.circle")
                                .font(.subheadline)
                                .foregroundStyle(.secondary)
                        }
                    }
                    if let download = bandwidth.formattedDownloadSpeed {
                        Label(String(localized: "sources.bandwidth.download \(download)"), systemImage: "arrow.down.circle")
                            .font(.subheadline)
                            .foregroundStyle(.secondary)
                    }
                    if !bandwidth.hasWriteAccess {
                        Label(String(localized: "sources.status.readOnly"), systemImage: "lock.fill")
                            .font(.subheadline)
                            .foregroundStyle(.orange)
                    }
                    if let warning = bandwidth.warning {
                        Text(warning)
                            .font(.caption)
                            .foregroundStyle(.secondary)
                    }
                }
            case .failure(let error):
                Label(error, systemImage: "xmark.circle.fill")
                    .foregroundStyle(.red)
            }
        }
    }

    private func testConnection() {
        guard let appEnvironment else { return }

        isTesting = true
        testResult = nil
        testProgress = nil

        let testPassword = password.isEmpty
            ? appEnvironment.mediaSourcesManager.password(for: source)
            : password

        var updatedSource = source
        updatedSource.username = username.isEmpty ? nil : username
        updatedSource.allowInvalidCertificates = allowInvalidCertificates

        // Use factory to create client with appropriate SSL settings
        let webDAVClient = appEnvironment.webDAVClientFactory.createClient(for: updatedSource)

        Task {
            do {
                let bandwidthResult = try await webDAVClient.testBandwidth(
                    source: updatedSource,
                    password: testPassword
                ) { status in
                    Task { @MainActor in
                        self.testProgress = status
                    }
                }
                await MainActor.run {
                    isTesting = false
                    testProgress = nil
                    testResult = .successWithBandwidth(bandwidthResult)
                }
            } catch {
                await MainActor.run {
                    isTesting = false
                    testProgress = nil
                    testResult = .failure(error.localizedDescription)
                }
            }
        }
    }

    private func saveChanges() {
        guard let appEnvironment else { return }

        var updatedSource = source
        updatedSource.name = name
        updatedSource.isEnabled = isEnabled

        if source.type == .webdav || source.type == .smb {
            updatedSource.username = username.isEmpty ? nil : username

            if !password.isEmpty {
                appEnvironment.mediaSourcesManager.setPassword(password, for: source)
            }
        }

        if source.type == .webdav {
            updatedSource.allowInvalidCertificates = allowInvalidCertificates
        }

        if source.type == .smb {
            updatedSource.smbProtocolVersion = smbProtocolVersion

            // Clear SMB cache if credentials or protocol changed
            let credentialsChanged = (source.username != updatedSource.username) || !password.isEmpty
            let protocolChanged = source.smbProtocolVersion != smbProtocolVersion

            if credentialsChanged || protocolChanged {
                Task {
                    await appEnvironment.smbClient.clearCache(for: source)
                }
            }
        }

        appEnvironment.mediaSourcesManager.update(updatedSource)
        dismiss()
    }

    private func deleteSource() {
        guard let appEnvironment else { return }
        appEnvironment.mediaSourcesManager.remove(source)
        dismiss()
    }
}

// MARK: - Preview

#Preview("Remote Server") {
    EditSourceView(
        source: .remoteServer(Instance(type: .invidious, url: URL(string: "https://invidious.example.com")!))
    )
    .appEnvironment(.preview)
}

#Preview("WebDAV") {
    EditSourceView(
        source: .fileSource(.webdav(name: "My NAS", url: URL(string: "https://nas.local:5006")!, username: "user"))
    )
    .appEnvironment(.preview)
}
