import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import { withAgentSystem } from "./agent";
import type { RawPost } from "@/lib/ranking";

type UnknownRecord = Record<string, unknown>;

function asRecord(value: unknown): UnknownRecord | null {
  return value && typeof value === "object" && !Array.isArray(value)
    ? (value as UnknownRecord)
    : null;
}

function firstValue(record: UnknownRecord, keys: string[]): unknown {
  for (const key of keys) {
    if (record[key] !== undefined) return record[key];
  }
  return undefined;
}

function normalizeDimension(value: unknown) {
  if (typeof value === "string") return { summary: value, evidence: [] };
  const record = asRecord(value);
  if (!record) return undefined;
  const summary = firstValue(record, ["summary", "description", "analysis", "conclusion", "摘要", "結論"]);
  const rawEvidence = firstValue(record, ["evidence", "examples", "quotes", "proof", "證據", "例句"]);
  const evidence = Array.isArray(rawEvidence)
    ? rawEvidence.filter((item): item is string => typeof item === "string").slice(0, 4)
    : typeof rawEvidence === "string"
      ? [rawEvidence]
      : [];
  return typeof summary === "string" ? { summary, evidence } : undefined;
}

export function normalizeStyle8DOutput(value: unknown): unknown {
  let root = asRecord(value);
  if (!root) return value;
  for (const key of ["analysis", "style8d", "style8D", "result", "data", "output"]) {
    const nested = asRecord(root[key]);
    if (nested && !root.d1Tone && !root.d1) {
      root = { ...root, ...nested };
    }
  }

  const dimensions = Array.isArray(root.dimensions) ? root.dimensions : [];
  const dimensionAt = (index: number, aliases: string[]) => {
    const direct = firstValue(root!, aliases);
    if (direct !== undefined) return normalizeDimension(direct);
    const row = dimensions[index];
    return normalizeDimension(row);
  };

  const personaValue = firstValue(root, ["personaDraft", "persona", "persona_draft", "voiceProfile", "人設草稿"]);
  const personaRecord = asRecord(personaValue);
  const personaString = typeof personaValue === "string" ? personaValue : "";
  const personaDraft = {
    identity: String(firstValue(personaRecord ?? {}, ["identity", "role", "我是誰", "定位"]) ?? personaString),
    tone: String(firstValue(personaRecord ?? {}, ["tone", "voice", "語氣"]) ?? "依照 D1 與 D6 執行"),
    audience: String(firstValue(personaRecord ?? {}, ["audience", "targetAudience", "受眾"]) ?? "依帳號目標受眾"),
    hooks: String(firstValue(personaRecord ?? {}, ["hooks", "openings", "開場"]) ?? "依照 D2 執行"),
    examples: String(firstValue(personaRecord ?? {}, ["examples", "sample", "範例"]) ?? "依照 D1–D6 抽象仿寫"),
    avoid: String(firstValue(personaRecord ?? {}, ["avoid", "risks", "避免"]) ?? "依照 D8 執行"),
  };

  return {
    d1Tone: dimensionAt(0, ["d1Tone", "d1", "D1", "tone", "D1 語氣人格", "語氣人格"]),
    d2Structure: dimensionAt(1, ["d2Structure", "d2", "D2", "structure", "D2 結構模板", "結構模板"]),
    d3Interaction: dimensionAt(2, ["d3Interaction", "d3", "D3", "interaction", "D3 互動方式", "互動方式"]),
    d4Topics: dimensionAt(3, ["d4Topics", "d4", "D4", "topics", "D4 主題分布", "主題分布"]),
    d5Rhythm: dimensionAt(4, ["d5Rhythm", "d5", "D5", "rhythm", "D5 發文節奏", "發文節奏"]),
    d6Visual: dimensionAt(5, ["d6Visual", "d6", "D6", "visual", "D6 視覺語法", "視覺語法"]),
    d7Conversion: dimensionAt(6, ["d7Conversion", "d7", "D7", "conversion", "D7 轉換方式", "轉換方式"]),
    d8Risk: dimensionAt(7, ["d8Risk", "d8", "D8", "risk", "D8 風險紅線", "風險紅線"]),
    personaDraft,
  };
}

const dimension = z.object({ summary: z.string(), evidence: z.array(z.string()).max(4) });
const style8dSchema = z.object({
  d1Tone: dimension,
  d2Structure: dimension,
  d3Interaction: dimension,
  d4Topics: dimension,
  d5Rhythm: dimension,
  d6Visual: dimension,
  d7Conversion: dimension,
  d8Risk: dimension,
  personaDraft: z.object({
    identity: z.string(),
    tone: z.string(),
    audience: z.string(),
    hooks: z.string(),
    examples: z.string(),
    avoid: z.string(),
  }),
});

export type Style8DAnalysis = z.infer<typeof style8dSchema>;

export interface BenchmarkEngagement {
  sampleSize: number;
  measuredPosts: number;
  medianInteractions: number;
  averageInteractions: number;
  postsAboveThreshold: number;
  threshold: number;
  verdict: "strong" | "usable" | "unknown";
}

export function evaluateBenchmarkEngagement(posts: RawPost[], threshold = 10): BenchmarkEngagement {
  const values = posts
    .map((post) => (post.likeCount ?? 0) + (post.replyCount ?? 0) * 2 + (post.repostCount ?? 0) * 1.5)
    .filter((value) => value > 0)
    .sort((a, b) => a - b);
  const median = values.length
    ? values.length % 2
      ? values[Math.floor(values.length / 2)]
      : (values[values.length / 2 - 1] + values[values.length / 2]) / 2
    : 0;
  const average = values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0;
  const above = values.filter((value) => value >= threshold).length;
  const verdict = values.length < 3 ? "unknown" : median >= threshold && above >= 3 ? "strong" : "usable";
  return {
    sampleSize: posts.length,
    measuredPosts: values.length,
    medianInteractions: Math.round(median * 10) / 10,
    averageInteractions: Math.round(average * 10) / 10,
    postsAboveThreshold: above,
    threshold,
    verdict,
  };
}

export function serialize8DPersona(draft: Style8DAnalysis["personaDraft"]): string {
  return [
    `【我是誰】\n${draft.identity}`,
    `【語氣】\n${draft.tone}`,
    `【對誰說】\n${draft.audience}`,
    `【開場習慣】\n${draft.hooks}`,
    `【代表句範例】\n${draft.examples}`,
    `【避免】\n${draft.avoid}`,
  ].join("\n\n");
}

export async function analyzeStyle8D(input: {
  username: string;
  posts: RawPost[];
  aiProvider: string;
  aiModel: string;
  apiKeys?: ProviderApiKeys;
}): Promise<Style8DAnalysis> {
  const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});
  const materials = input.posts.slice(0, 12).map((post, index) =>
    `[${index + 1}] ${post.likeCount ?? 0}讚 ${post.replyCount ?? 0}回覆\n${post.text.slice(0, 500)}`
  ).join("\n\n");
  return generateStructuredObject({
    model,
    provider: input.aiProvider,
    modelId: input.aiModel,
    schema: style8dSchema,
    normalize: normalizeStyle8DOutput,
    system: withAgentSystem(`你是 Threads 創作者風格研究員。只能根據提供的近期貼文歸納，不可捏造作者背景。逐一輸出八個維度：D1 語氣人格、D2 結構模板、D3 互動方式、D4 主題分布、D5 發文節奏、D6 視覺語法（emoji、標點、換行）、D7 轉換方式、D8 風險紅線。每個維度要有摘要與可核對的文字證據。最後產生「可供另一個帳號借鑑、但不可冒充或抄襲」的人設草稿。代表句必須是抽象仿寫範例，不可逐字複製原文。`),
    jsonPromptSuffix: `\n\n只回傳以下 JSON 結構，不要 markdown：\n{"d1Tone":{"summary":"","evidence":[]},"d2Structure":{"summary":"","evidence":[]},"d3Interaction":{"summary":"","evidence":[]},"d4Topics":{"summary":"","evidence":[]},"d5Rhythm":{"summary":"","evidence":[]},"d6Visual":{"summary":"","evidence":[]},"d7Conversion":{"summary":"","evidence":[]},"d8Risk":{"summary":"","evidence":[]},"personaDraft":{"identity":"","tone":"","audience":"","hooks":"","examples":"","avoid":""}}`,
    prompt: `對標帳號：@${input.username}\n近期貼文樣本：\n\n${materials}`,
  });
}
