// ignore_for_file: unused_import, unnecessary_import

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'app_metadata.dart';
import 'app_capabilities.dart';
import 'app_store_policy.dart';
import 'ui_feature_manifest.dart';
import '../i18n/app_language.dart';
import '../models/app_models.dart';
import '../runtime/device_identity_store.dart';

import '../runtime/runtime_bootstrap.dart';
import '../runtime/desktop_platform_service.dart';
import '../runtime/gateway_runtime.dart';
import '../runtime/runtime_controllers.dart';
import '../runtime/runtime_models.dart';
import '../runtime/secret_store.dart';
import '../runtime/secure_config_store.dart';
import '../runtime/embedded_agent_launch_policy.dart';
import '../runtime/runtime_coordinator.dart';
import '../runtime/gateway_acp_client.dart';
import '../runtime/codex_runtime.dart';
import '../runtime/codex_config_bridge.dart';
import '../runtime/code_agent_node_orchestrator.dart';
import '../runtime/assistant_artifacts.dart';
import '../runtime/desktop_thread_artifact_service.dart';
import '../runtime/mode_switcher.dart';
import '../runtime/agent_registry.dart';
import '../runtime/platform_environment.dart';
import 'app_controller_desktop_core.dart';
import 'app_controller_desktop_navigation.dart';
import 'app_controller_desktop_gateway.dart';
import 'app_controller_desktop_thread_sessions.dart';
import 'app_controller_desktop_thread_actions.dart';
import 'app_controller_desktop_workspace_execution.dart';
import 'app_controller_desktop_settings_runtime.dart';
import 'app_controller_desktop_thread_storage.dart';
import 'app_controller_desktop_skill_permissions.dart';
import 'app_controller_desktop_runtime_helpers.dart';

// ignore_for_file: invalid_use_of_visible_for_testing_member, invalid_use_of_protected_member
extension AppControllerDesktopSettings on AppController {
  AppUiState _markSavedGatewayTargetsForChangedProfiles(
    SettingsSnapshot previous,
    SettingsSnapshot snapshot,
  ) {
    var nextState = appUiState;
    if (jsonEncode(previous.primaryGatewayProfile.toJson()) !=
        jsonEncode(snapshot.primaryGatewayProfile.toJson())) {
      nextState = nextState.markGatewayTargetSaved(
        AssistantExecutionTarget.gateway,
      );
    }
    return nextState;
  }

  Future<void> saveSettingsDraft(SettingsSnapshot snapshot) async {
    if (disposedInternal) {
      return;
    }
    settingsDraftInternal = sanitizeFeatureFlagSettingsInternal(
      sanitizeOllamaCloudSettingsInternal(
        sanitizeCodeAgentSettingsInternal(snapshot),
      ),
    );
    settingsDraftInitializedInternal = true;
    settingsDraftStatusMessageInternal = appText(
      '草稿已更新，点击顶部保存并生效。',
      'Draft updated. Use the top button to save and apply it.',
    );
    notifyListeners();
  }

  String draftSecretRefKeyInternal(String refName) =>
      'secret_ref::${refName.trim()}';

  void saveGatewayTokenDraft(String value, {required int profileIndex}) {
    saveSecretDraftInternal(
      draftSecretRefKeyInternal(
        settingsDraft.gatewayProfiles[profileIndex].tokenRef.trim().isEmpty
            ? SecretStore.gatewayTokenRefKey(profileIndex)
            : settingsDraft.gatewayProfiles[profileIndex].tokenRef,
      ),
      value,
    );
  }

  void saveGatewayPasswordDraft(String value, {required int profileIndex}) {
    saveSecretDraftInternal(
      draftSecretRefKeyInternal(
        settingsDraft.gatewayProfiles[profileIndex].passwordRef.trim().isEmpty
            ? SecretStore.gatewayPasswordRefKey(profileIndex)
            : settingsDraft.gatewayProfiles[profileIndex].passwordRef,
      ),
      value,
    );
  }

  void saveAiGatewayApiKeyDraft(String value) {
    saveSecretDraftInternal(
      draftSecretRefKeyInternal(
        settingsDraft.aiGateway.apiKeyRef.trim().isEmpty
            ? AppController.draftAiGatewayApiKeyKeyInternal
            : settingsDraft.aiGateway.apiKeyRef,
      ),
      value,
    );
  }

  void saveVaultTokenDraft(String value) {
    saveSecretDraftInternal(
      draftSecretRefKeyInternal(
        settingsDraft.vault.tokenRef.trim().isEmpty
            ? AppController.draftVaultTokenKeyInternal
            : settingsDraft.vault.tokenRef,
      ),
      value,
    );
  }

  void saveOllamaCloudApiKeyDraft(String value) {
    saveSecretDraftInternal(
      draftSecretRefKeyInternal(
        settingsDraft.ollamaCloud.apiKeyRef.trim().isEmpty
            ? AppController.draftOllamaApiKeyKeyInternal
            : settingsDraft.ollamaCloud.apiKeyRef,
      ),
      value,
    );
  }

  Future<void> saveWorkspacePath(String value) async {
    if (disposedInternal) {
      return;
    }
    final trimmed = value.trim();
    if (settings.workspacePath.trim() == trimmed) {
      if (settingsDraftInitializedInternal) {
        settingsDraftInternal = settingsDraft.copyWith(workspacePath: trimmed);
      }
      notifyListeners();
      return;
    }
    final previous = settings;
    await persistSettingsSnapshotInternal(
      settings.copyWith(workspacePath: trimmed),
    );
    if (disposedInternal) {
      return;
    }
    await applyPersistedSettingsSideEffectsInternal(
      previous: previous,
      current: settings,
      refreshAfterSave: true,
    );
    lastAppliedSettingsInternal = settings;
    settingsDraftInternal = settingsDraftInitializedInternal
        ? settingsDraftInternal.copyWith(workspacePath: settings.workspacePath)
        : settings;
    settingsDraftInitializedInternal = true;
    settingsDraftStatusMessageInternal = appText(
      '工作区路径已保存并立即生效。',
      'Workspace path saved and applied immediately.',
    );
    notifyListeners();
  }

  Future<void> persistSettingsDraft() async {
    if (disposedInternal) {
      return;
    }
    if (!hasSettingsDraftChanges) {
      settingsDraftStatusMessageInternal = appText(
        '没有需要保存的更改。',
        'There are no changes to save.',
      );
      notifyListeners();
      return;
    }
    final nextSettings = _markSavedGatewayTargetsForChangedProfiles(
      settings,
      settingsDraft,
    );
    markPendingApplyDomainsInternal(settings, settingsDraft);
    await persistDraftSecretsInternal();
    if (nextSettings.toJsonString() != appUiState.toJsonString()) {
      await saveAppUiStateInternal(nextSettings);
    }
    if (settingsDraft.toJsonString() != settings.toJsonString()) {
      await persistSettingsSnapshotInternal(settingsDraft);
    }
    settingsDraftInternal = settings;
    settingsDraftInitializedInternal = true;
    pendingSettingsApplyInternal = true;
    settingsDraftStatusMessageInternal = appText(
      '已保存配置，等待立即生效。',
      'Settings saved and waiting to be applied.',
    );
    notifyListeners();
  }

  Future<void> applySettingsDraft() async {
    if (disposedInternal) {
      return;
    }
    if (hasSettingsDraftChanges) {
      await persistSettingsDraft();
    }
    if (!pendingSettingsApplyInternal) {
      settingsDraftStatusMessageInternal = appText(
        '没有需要应用的更改。',
        'There are no saved changes to apply.',
      );
      notifyListeners();
      return;
    }
    final currentSettings = settings;
    await applyPersistedSettingsSideEffectsInternal(
      previous: lastAppliedSettingsInternal,
      current: currentSettings,
      refreshAfterSave: true,
    );
    if (pendingGatewayApplyInternal) {
      await applyPersistedGatewaySettingsInternal(currentSettings);
    }
    if (pendingAiGatewayApplyInternal) {
      await applyPersistedAiGatewaySettingsInternal(currentSettings);
    }
    lastAppliedSettingsInternal = settings;
    pendingSettingsApplyInternal = false;
    pendingGatewayApplyInternal = false;
    pendingAiGatewayApplyInternal = false;
    settingsDraftInternal = settings;
    settingsDraftInitializedInternal = true;
    settingsDraftStatusMessageInternal = appText(
      '已按当前配置生效。',
      'The current configuration is now in effect.',
    );
    notifyListeners();
  }

  Future<void> saveSettings(
    SettingsSnapshot snapshot, {
    bool refreshAfterSave = true,
  }) async {
    if (disposedInternal) {
      return;
    }
    final previous = settings;
    final nextSnapshot = _markSavedGatewayTargetsForChangedProfiles(
      previous,
      snapshot,
    );
    if (nextSnapshot.toJsonString() != appUiState.toJsonString()) {
      await saveAppUiStateInternal(nextSnapshot);
    }
    await persistSettingsSnapshotInternal(snapshot);
    if (disposedInternal) {
      return;
    }
    await applyPersistedSettingsSideEffectsInternal(
      previous: previous,
      current: settings,
      refreshAfterSave: refreshAfterSave,
    );
    lastAppliedSettingsInternal = settings;
    settingsDraftInternal = settings;
    settingsDraftInitializedInternal = true;
    pendingSettingsApplyInternal = false;
    pendingGatewayApplyInternal = false;
    pendingAiGatewayApplyInternal = false;
    draftSecretValuesInternal.clear();
    settingsDraftStatusMessageInternal = '';
  }

  Future<void> clearAssistantLocalState() async {
    await flushAssistantThreadPersistenceInternal();
    await storeInternal.clearAssistantLocalState();
    await storeInternal.clearAppUiState();
    await storeInternal.saveTaskThreads(const <TaskThread>[]);
    final currentSettings = settings;
    appUiStateInternal = AppUiState.defaults();
    taskThreadRepositoryInternal.clear();
    assistantThreadMessagesInternal.clear();
    localSessionMessagesInternal.clear();
    aiGatewayStreamingTextBySessionInternal.clear();
    aiGatewayStreamingClientsInternal.clear();
    aiGatewayPendingSessionKeysInternal.clear();
    aiGatewayAbortedSessionKeysInternal.clear();
    assistantThreadTurnQueuesInternal.clear();
    for (final turn in openClawGatewayQueuedTurnsInternal) {
      turn.cancelled = true;
    }
    for (final turn in openClawGatewayActiveTurnsInternal.values) {
      turn.cancelled = true;
    }
    openClawGatewayQueuedTurnsInternal.clear();
    openClawGatewayQueuedTurnsBySessionInternal.clear();
    openClawGatewayActiveTurnsInternal.clear();
    final sessionKey = createAssistantDraftSessionKeyInternal();
    initializeAssistantThreadContext(
      sessionKey,
      executionTarget: sanitizePersistedExecutionTargetInternal(
        currentSettings.assistantExecutionTarget,
      ),
      messageViewMode: AssistantMessageViewMode.rendered,
    );
    await setCurrentAssistantSessionKeyInternal(
      sessionKey,
      persistSelection: false,
    );
    await flushAssistantThreadPersistenceInternal();
    await storeInternal.saveTaskThreads(
      taskThreadRepositoryInternal.snapshot(),
    );
    chatControllerInternal.clear();
    recomputeTasksInternal();
    notifyListeners();
  }

  void saveSecretDraftInternal(String key, String value) {
    final trimmed = value.trim();
    if (trimmed.isEmpty) {
      draftSecretValuesInternal.remove(key);
    } else {
      draftSecretValuesInternal[key] = trimmed;
    }
    settingsDraftStatusMessageInternal = appText(
      '草稿已更新，点击顶部保存持久化。',
      'Draft updated. Use the top button to save and apply it.',
    );
    notifyListeners();
  }
}
