import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
import {
  buildSingleChannelSecretPromptState,
  hasConfiguredSecretInput,
  promptSingleChannelSecretInput,
  type ChannelOnboardingAdapter,
  type OpenClawConfig,
  type SecretInput,
  type WizardPrompter,
} from "openclaw/plugin-sdk/mattermost";
import {
  listMattermostAccountIds,
  resolveDefaultMattermostAccountId,
  resolveMattermostAccount,
} from "./mattermost/accounts.js";
import { resolveAccountIdForConfigure } from "./onboarding-helpers.js";

const channel = "mattermost" as const;

async function noteMattermostSetup(prompter: WizardPrompter): Promise<void> {
  await prompter.note(
    [
      "1) Mattermost System Console -> Integrations -> Bot Accounts",
      "2) Create a bot + copy its token",
      "3) Use your server base URL (e.g., https://chat.example.com)",
      "Tip: the bot must be a member of any channel you want it to monitor.",
      "Docs: https://docs.openclaw.ai/channels/mattermost",
    ].join("\n"),
    "Mattermost bot token",
  );
}

async function promptMattermostBaseUrl(params: {
  prompter: WizardPrompter;
  initialValue?: string;
}): Promise<string> {
  const baseUrl = String(
    await params.prompter.text({
      message: "Enter Mattermost base URL",
      initialValue: params.initialValue,
      validate: (value) => (value?.trim() ? undefined : "Required"),
    }),
  ).trim();
  return baseUrl;
}

export const mattermostOnboardingAdapter: ChannelOnboardingAdapter = {
  channel,
  getStatus: async ({ cfg }) => {
    const configured = listMattermostAccountIds(cfg).some((accountId) => {
      const account = resolveMattermostAccount({
        cfg,
        accountId,
        allowUnresolvedSecretRef: true,
      });
      const tokenConfigured =
        Boolean(account.botToken) || hasConfiguredSecretInput(account.config.botToken);
      return tokenConfigured && Boolean(account.baseUrl);
    });
    return {
      channel,
      configured,
      statusLines: [`Mattermost: ${configured ? "configured" : "needs token + url"}`],
      selectionHint: configured ? "configured" : "needs setup",
      quickstartScore: configured ? 2 : 1,
    };
  },
  configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
    const defaultAccountId = resolveDefaultMattermostAccountId(cfg);
    const accountId = await resolveAccountIdForConfigure({
      cfg,
      prompter,
      label: "Mattermost",
      accountOverride: accountOverrides.mattermost,
      shouldPromptAccountIds,
      listAccountIds: listMattermostAccountIds,
      defaultAccountId,
    });

    let next = cfg;
    const resolvedAccount = resolveMattermostAccount({
      cfg: next,
      accountId,
      allowUnresolvedSecretRef: true,
    });
    const accountConfigured = Boolean(resolvedAccount.botToken && resolvedAccount.baseUrl);
    const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
    const hasConfigToken = hasConfiguredSecretInput(resolvedAccount.config.botToken);
    const hasConfigValues = hasConfigToken || Boolean(resolvedAccount.config.baseUrl);
    const tokenPromptState = buildSingleChannelSecretPromptState({
      accountConfigured,
      hasConfigToken,
      allowEnv: allowEnv && !hasConfigValues,
      envValue:
        process.env.MATTERMOST_BOT_TOKEN?.trim() && process.env.MATTERMOST_URL?.trim()
          ? process.env.MATTERMOST_BOT_TOKEN
          : undefined,
    });

    let botToken: SecretInput | null = null;
    let baseUrl: string | null = null;

    if (!accountConfigured) {
      await noteMattermostSetup(prompter);
    }

    const botTokenResult = await promptSingleChannelSecretInput({
      cfg: next,
      prompter,
      providerHint: "mattermost",
      credentialLabel: "bot token",
      accountConfigured: tokenPromptState.accountConfigured,
      canUseEnv: tokenPromptState.canUseEnv,
      hasConfigToken: tokenPromptState.hasConfigToken,
      envPrompt: "MATTERMOST_BOT_TOKEN + MATTERMOST_URL detected. Use env vars?",
      keepPrompt: "Mattermost bot token already configured. Keep it?",
      inputPrompt: "Enter Mattermost bot token",
      preferredEnvVar: "MATTERMOST_BOT_TOKEN",
    });
    if (botTokenResult.action === "keep") {
      return { cfg: next, accountId };
    }

    if (botTokenResult.action === "use-env") {
      if (accountId === DEFAULT_ACCOUNT_ID) {
        next = {
          ...next,
          channels: {
            ...next.channels,
            mattermost: {
              ...next.channels?.mattermost,
              enabled: true,
            },
          },
        };
      }
      return { cfg: next, accountId };
    }

    botToken = botTokenResult.value;
    baseUrl = await promptMattermostBaseUrl({
      prompter,
      initialValue: resolvedAccount.baseUrl ?? process.env.MATTERMOST_URL?.trim(),
    });

    if (accountId === DEFAULT_ACCOUNT_ID) {
      next = {
        ...next,
        channels: {
          ...next.channels,
          mattermost: {
            ...next.channels?.mattermost,
            enabled: true,
            botToken,
            baseUrl,
          },
        },
      };
    } else {
      next = {
        ...next,
        channels: {
          ...next.channels,
          mattermost: {
            ...next.channels?.mattermost,
            enabled: true,
            accounts: {
              ...next.channels?.mattermost?.accounts,
              [accountId]: {
                ...next.channels?.mattermost?.accounts?.[accountId],
                enabled: next.channels?.mattermost?.accounts?.[accountId]?.enabled ?? true,
                botToken,
                baseUrl,
              },
            },
          },
        },
      };
    }

    return { cfg: next, accountId };
  },
  disable: (cfg: OpenClawConfig) => ({
    ...cfg,
    channels: {
      ...cfg.channels,
      mattermost: { ...cfg.channels?.mattermost, enabled: false },
    },
  }),
};
