//
// OpenRocky — Voice-first AI Agent
// https://github.com/openrocky
//
// Developed by everettjf with the assistance of Claude Code and Codex.
// Date: 2026-04-06
// Copyright (c) 2026 everettjf. All rights reserved.
//

import SwiftUI

struct OpenRockyEmailSettingsView: View {
    @ObservedObject var toolStore: OpenRockyBuiltInToolStore

    @State private var providerType: OpenRockyEmailProvider = .smtp

    // SMTP state
    @State private var selectedPreset: EmailPreset = .gmail
    @State private var smtpHost: String = ""
    @State private var smtpPort: String = ""
    @State private var smtpUsername: String = ""
    @State private var smtpPassword: String = ""
    @State private var useTLS: Bool = true

    // Resend state
    @State private var resendApiKey: String = ""
    @State private var resendFromAddress: String = OpenRockyEmailConfig.resendSandboxFrom

    // Shared state
    @State private var defaultRecipient: String = ""

    // UI state
    @State private var showingTestResult = false
    @State private var testResultMessage = ""
    @State private var isTesting = false
    @State private var showDeleteConfirmation = false

    enum EmailPreset: String, CaseIterable {
        case gmail = "Gmail"
        case outlook = "Outlook"
        case qq = "QQ Mail"
        case custom = "Custom SMTP"

        var config: OpenRockyEmailConfig? {
            switch self {
            case .gmail: return .gmailPreset
            case .outlook: return .outlookPreset
            case .qq: return .qqPreset
            case .custom: return nil
            }
        }
    }

    private var isConfigured: Bool {
        guard let config = OpenRockyEmailConfig.load() else { return false }
        return config.isConfigured && config.hasCredential
    }

    private var canSave: Bool {
        switch providerType {
        case .smtp:
            return !smtpHost.isEmpty && !smtpUsername.isEmpty && !smtpPassword.isEmpty
        case .resend:
            return !resendApiKey.isEmpty && !resendFromAddress.isEmpty
        }
    }

    var body: some View {
        List {
            statusSection
            providerTypeSection

            switch providerType {
            case .smtp:
                smtpPresetSection
                smtpServerSection
                smtpAccountSection
            case .resend:
                resendSection
            }

            defaultRecipientSection

            actionsSection

            if isConfigured {
                removeSection
            }
        }
        .navigationTitle("Email Setup")
        .navigationBarTitleDisplayMode(.inline)
        .alert("Test Result", isPresented: $showingTestResult) {
            Button("OK") { }
        } message: {
            Text(testResultMessage)
        }
        .onAppear { loadExistingConfig() }
    }

    // MARK: - Sections

    private var statusSection: some View {
        Section {
            HStack(spacing: 12) {
                ZStack {
                    RoundedRectangle(cornerRadius: 12, style: .continuous)
                        .fill(isConfigured ? OpenRockyPalette.success.opacity(0.14) : Color.orange.opacity(0.14))
                        .frame(width: 48, height: 48)
                    Image(systemName: isConfigured ? "checkmark.circle.fill" : "exclamationmark.triangle.fill")
                        .font(.system(size: 20, weight: .bold))
                        .foregroundStyle(isConfigured ? OpenRockyPalette.success : .orange)
                }
                VStack(alignment: .leading, spacing: 4) {
                    Text(isConfigured ? "Email Configured" : "Setup Required")
                        .font(.headline)
                    Text(isConfigured ? "Ready to send via \(providerType.displayName)." : "Pick a provider type and fill in the credentials below.")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            }
            .padding(.vertical, 4)
        }
    }

    private var providerTypeSection: some View {
        Section {
            Picker("Provider Type", selection: $providerType) {
                ForEach(OpenRockyEmailProvider.allCases, id: \.self) { type in
                    Text(type.displayName).tag(type)
                }
            }
            .pickerStyle(.segmented)
        } footer: {
            switch providerType {
            case .smtp:
                Text("SMTP works with Gmail, Outlook, QQ Mail, and other standard providers. Requires an app password.")
            case .resend:
                Text("Resend is an HTTP email API — sign up at resend.com, grab an API key, and you can start sending in under a minute.")
            }
        }
    }

    private var smtpPresetSection: some View {
        Section {
            Picker("Email Provider", selection: $selectedPreset) {
                ForEach(EmailPreset.allCases, id: \.self) { preset in
                    Text(LocalizedStringKey(preset.rawValue)).tag(preset)
                }
            }
            .onChange(of: selectedPreset) { _, newPreset in
                if let config = newPreset.config {
                    smtpHost = config.smtpHost
                    smtpPort = String(config.smtpPort)
                    useTLS = config.useTLS
                }
            }
        } header: {
            Text("Provider")
        } footer: {
            switch selectedPreset {
            case .gmail:
                Text("Use a Google App Password (not your Gmail password). Generate one at myaccount.google.com → Security → App passwords.")
            case .outlook:
                Text("Use your Outlook/Microsoft account password or an app password if 2FA is enabled.")
            case .qq:
                Text("Use QQ Mail authorization code (not your QQ password). Get it from QQ Mail Settings → Account → POP3/SMTP.")
            case .custom:
                EmptyView()
            }
        }
    }

    private var smtpServerSection: some View {
        Section("SMTP Server") {
            LabeledContent("Host") {
                TextField("smtp.gmail.com", text: $smtpHost)
                    .textContentType(.URL)
                    .autocapitalization(.none)
                    .multilineTextAlignment(.trailing)
            }
            LabeledContent("Port") {
                TextField("465", text: $smtpPort)
                    .keyboardType(.numberPad)
                    .multilineTextAlignment(.trailing)
            }
            Toggle("Use TLS", isOn: $useTLS)
        }
    }

    private var smtpAccountSection: some View {
        Section("Account") {
            LabeledContent("Email") {
                TextField("you@gmail.com", text: $smtpUsername)
                    .textContentType(.emailAddress)
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)
                    .multilineTextAlignment(.trailing)
            }
            LabeledContent("App Password") {
                SecureField("App password", text: $smtpPassword)
                    .multilineTextAlignment(.trailing)
            }
        }
    }

    private var resendSection: some View {
        Section {
            LabeledContent("API Key") {
                SecureField("re_...", text: $resendApiKey)
                    .autocapitalization(.none)
                    .multilineTextAlignment(.trailing)
            }
            LabeledContent("From") {
                TextField(OpenRockyEmailConfig.resendSandboxFrom, text: $resendFromAddress)
                    .textContentType(.emailAddress)
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)
                    .multilineTextAlignment(.trailing)
            }
        } header: {
            Text("Resend")
        } footer: {
            Text("Get your API key at resend.com → API Keys. The default From `\(OpenRockyEmailConfig.resendSandboxFrom)` works without domain verification but can only deliver to your Resend account email. To send to anyone, verify your own domain in Resend and use an address on it.")
        }
    }

    private var defaultRecipientSection: some View {
        Section {
            LabeledContent("Send To") {
                TextField("you@example.com", text: $defaultRecipient)
                    .textContentType(.emailAddress)
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)
                    .multilineTextAlignment(.trailing)
            }
        } header: {
            Text("Default Recipient")
        } footer: {
            Text("Where to send when you ask Rocky to email something without naming a recipient (e.g. \"write this up and email it to me\"). You can always override it by naming an address out loud.")
        }
    }

    private var actionsSection: some View {
        Section {
            Button {
                saveConfig()
            } label: {
                HStack {
                    Image(systemName: "square.and.arrow.down")
                    Text("Save Configuration")
                }
            }
            .disabled(!canSave)

            Button {
                Task { await testConnection() }
            } label: {
                HStack {
                    if isTesting {
                        ProgressView()
                            .scaleEffect(0.8)
                    } else {
                        Image(systemName: "paperplane")
                    }
                    Text(isTesting ? "Testing..." : "Send Test Email")
                }
            }
            .disabled(!isConfigured || isTesting)
        }
    }

    private var removeSection: some View {
        Section {
            Button(role: .destructive) {
                showDeleteConfirmation = true
            } label: {
                HStack {
                    Image(systemName: "trash")
                    Text("Remove Email Configuration")
                }
            }
            .confirmationDialog("Remove email configuration?", isPresented: $showDeleteConfirmation) {
                Button("Remove", role: .destructive) {
                    OpenRockyEmailConfig.remove()
                    toolStore.setEnabled("email-send", enabled: false)
                    clearFields()
                }
            } message: {
                Text("This will remove your email provider settings and credentials. The email tool will be disabled.")
            }
        }
    }

    // MARK: - Load / Save

    private func loadExistingConfig() {
        // Always restore any per-provider keychain credentials so switching tabs
        // doesn't force the user to re-enter them.
        if let saved = OpenRockyKeychain.live.value(for: OpenRockyEmailConfig.smtpKeychainAccount) {
            smtpPassword = saved
        }
        if let saved = OpenRockyKeychain.live.value(for: OpenRockyEmailConfig.resendKeychainAccount) {
            resendApiKey = saved
        }

        guard let config = OpenRockyEmailConfig.load() else { return }
        providerType = config.provider

        smtpHost = config.smtpHost
        smtpPort = String(config.smtpPort)
        smtpUsername = config.username
        useTLS = config.useTLS
        if !config.resendFromAddress.isEmpty {
            resendFromAddress = config.resendFromAddress
        }
        defaultRecipient = config.defaultRecipient

        // Detect SMTP preset
        switch config.smtpHost {
        case "smtp.gmail.com": selectedPreset = .gmail
        case "smtp.office365.com": selectedPreset = .outlook
        case "smtp.qq.com": selectedPreset = .qq
        default: selectedPreset = config.smtpHost.isEmpty ? .gmail : .custom
        }
    }

    private func saveConfig() {
        let config: OpenRockyEmailConfig
        let credential: String
        switch providerType {
        case .smtp:
            config = OpenRockyEmailConfig(
                provider: .smtp,
                smtpHost: smtpHost,
                smtpPort: Int(smtpPort) ?? 465,
                username: smtpUsername,
                useTLS: useTLS,
                resendFromAddress: resendFromAddress,  // preserve other provider's UI state
                defaultRecipient: defaultRecipient.trimmingCharacters(in: .whitespaces)
            )
            credential = smtpPassword
        case .resend:
            config = OpenRockyEmailConfig(
                provider: .resend,
                smtpHost: smtpHost,
                smtpPort: Int(smtpPort) ?? 465,
                username: smtpUsername,
                useTLS: useTLS,
                resendFromAddress: resendFromAddress,
                defaultRecipient: defaultRecipient.trimmingCharacters(in: .whitespaces)
            )
            credential = resendApiKey
        }
        config.save()
        OpenRockyKeychain.live.set(credential, for: config.keychainAccount)
        toolStore.setEnabled("email-send", enabled: true)
    }

    private func clearFields() {
        smtpHost = ""
        smtpPort = ""
        smtpUsername = ""
        smtpPassword = ""
        resendApiKey = ""
        resendFromAddress = OpenRockyEmailConfig.resendSandboxFrom
        defaultRecipient = ""
    }

    // MARK: - Test

    private func testConnection() async {
        isTesting = true
        defer { isTesting = false }

        // Recipient for the test email: SMTP sends to itself, Resend sends to the From
        // (which for sandbox `onboarding@resend.dev` is delivered to the account email
        // by Resend's routing rules).
        let recipient: String
        switch providerType {
        case .smtp: recipient = smtpUsername
        case .resend: recipient = resendFromAddress
        }

        do {
            let messageID = try await OpenRockyEmailService.shared.send(
                to: [recipient],
                subject: "Rocky Email Test",
                body: "This is a test email from Rocky. If you received this, your email configuration is working correctly!"
            )
            testResultMessage = "Test email sent successfully! Check your inbox.\n\nMessage ID: \(messageID)"
        } catch {
            testResultMessage = "Failed: \(error.localizedDescription)"
        }
        showingTestResult = true
    }
}
