import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";

const nullableText = z.string().nullable().default(null);
const style8DSchema = z.object({
  d1Tone: nullableText,
  d2Structure: nullableText,
  d3Interaction: nullableText,
  d4Topics: nullableText,
  d5Rhythm: nullableText,
  d6Visual: nullableText,
  d7Conversion: nullableText,
  d8Risk: nullableText,
}).default({});

const accountStrategySchema = z.object({
  message: z.string().default("我已依照你的方向更新帳號策略。"),
  fields: z.object({
    displayName: nullableText,
    username: nullableText,
    brief: nullableText,
    persona: nullableText,
    targetAudience: nullableText,
    productBrief: nullableText,
    goals: nullableText,
    style8D: style8DSchema,
  }).default({}),
});

export type AccountStrategyFields = z.infer<typeof accountStrategySchema>["fields"];

function normalizeAccountStrategy(value: unknown): unknown {
  if (!value || typeof value !== "object") return value;
  let root = value as Record<string, unknown>;
  for (const key of ["result", "data", "output", "strategy"]) {
    const nested = root[key];
    if (nested && typeof nested === "object" && !Array.isArray(nested)) {
      root = nested as Record<string, unknown>;
      break;
    }
  }

  const fieldsValue = root.fields ?? root.form ?? root.account ?? root;
  const fields = fieldsValue && typeof fieldsValue === "object" && !Array.isArray(fieldsValue)
    ? { ...(fieldsValue as Record<string, unknown>) }
    : {};
  fields.style8D ??= fields.style8d ?? root.style8D ?? root.style8d;
  return {
    message: root.message ?? root.reply ?? root.summary,
    fields,
  };
}

export async function generateAccountStrategy(input: {
  instruction: string;
  current: Partial<AccountStrategyFields> & {
    style8D?: Partial<AccountStrategyFields["style8D"]>;
  };
  aiProvider: string;
  aiModel: string;
  apiKeys?: ProviderApiKeys;
}) {
  const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});

  const object = await generateStructuredObject({
    model,
    provider: input.aiProvider,
    modelId: input.aiModel,
    schema: accountStrategySchema,
    system: `你是 Threads 帳號策略顧問，也是產品 onboarding 助手。

你的任務：根據使用者自然語言，幫他把「帳號策略表單」補成可直接使用的內容。

填寫原則：
- 使用繁體中文、台灣語感
- 內容要具體、可執行，不要空泛
- 不要使用誇大承諾或保證結果
- 如果使用者提到醫療、健康、營養、心理等高敏感領域，語氣要合規：避免療效保證、診斷語氣、恐嚇式行銷；可以強調衛教、陪伴、風險提醒、就醫建議
- 優先補齊空欄位；已有內容可優化，但不要完全無視原本方向
- username 不確定時回傳 null，不要亂編
- displayName 可用使用者描述推測一個給自己看的名稱
- 使用者提到 8D、語氣、結構、互動、主題、節奏、視覺、轉換或風險時，直接更新 fields.style8D 對應欄位
- 沒有要求修改的 8D 維度回傳 null，不要覆蓋現有內容
- message 用 1-2 句說明你幫他補了什麼`,
    prompt: `目前表單內容：
${JSON.stringify(input.current, null, 2)}

使用者跟小幫手說：
${input.instruction}

請回傳可套用到表單的欄位。`,
    normalize: normalizeAccountStrategy,
    jsonPromptSuffix: `\n\n只回傳以下 JSON，不要 markdown：\n{"message":"","fields":{"displayName":null,"username":null,"brief":null,"persona":null,"targetAudience":null,"productBrief":null,"goals":null,"style8D":{"d1Tone":null,"d2Structure":null,"d3Interaction":null,"d4Topics":null,"d5Rhythm":null,"d6Visual":null,"d7Conversion":null,"d8Risk":null}}}`,
  });

  return object;
}
