import {
  boolean,
  doublePrecision,
  index,
  integer,
  jsonb,
  pgTable,
  primaryKey,
  text,
  timestamp,
  uuid,
} from "drizzle-orm/pg-core";
import {
  createdAt,
  creatorLevelEnum,
  eventTypeEnum,
  notificationTypeEnum,
  profileVisibilityEnum,
  updatedAt,
} from "./_shared.js";
import { households } from "./households.js";
import { users } from "./users.js";

/**
 * Domänhändelser (spec §55) i outbox-mönster: skrivs transaktionellt med
 * affärsdata och publiceras asynkront till konsumenter (analytics, memory,
 * recommendations, training).
 */
export const domainEvents = pgTable(
  "domain_events",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    type: eventTypeEnum("type").notNull(),
    userId: uuid("user_id"),
    householdId: uuid("household_id"),
    payload: jsonb("payload").notNull(),
    correlationId: text("correlation_id"),
    occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
    publishedAt: timestamp("published_at", { withTimezone: true }),
  },
  (t) => [
    index("domain_events_unpublished_idx").on(t.publishedAt, t.occurredAt),
    index("domain_events_type_idx").on(t.type, t.occurredAt),
    index("domain_events_household_idx").on(t.householdId, t.occurredAt),
  ],
);

export const featureFlags = pgTable("feature_flags", {
  key: text("key").primaryKey(),
  enabled: boolean("enabled").notNull().default(false),
  descriptionSv: text("description_sv"),
  rolloutPercent: integer("rollout_percent").notNull().default(100),
  updatedAt: updatedAt(),
});

/** Audit log (spec §56): vem gjorde vad, när, mot vad. */
export const auditLogs = pgTable(
  "audit_logs",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    actorUserId: uuid("actor_user_id"),
    actorType: text("actor_type").notNull().default("user"),
    action: text("action").notNull(),
    targetType: text("target_type"),
    targetId: text("target_id"),
    metadata: jsonb("metadata"),
    ip: text("ip"),
    correlationId: text("correlation_id"),
    createdAt: createdAt(),
  },
  (t) => [
    index("audit_logs_actor_idx").on(t.actorUserId, t.createdAt),
    index("audit_logs_action_idx").on(t.action, t.createdAt),
  ],
);

/** Idempotency-nycklar för säkra POST-retries (spec §56, §59). */
export const idempotencyKeys = pgTable(
  "idempotency_keys",
  {
    userId: uuid("user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    key: text("key").notNull(),
    endpoint: text("endpoint").notNull(),
    responseStatus: integer("response_status"),
    responseBody: jsonb("response_body"),
    createdAt: createdAt(),
  },
  (t) => [primaryKey({ columns: [t.userId, t.key, t.endpoint] })],
);

/** Notiser (spec §40). */
export const notifications = pgTable(
  "notifications",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    userId: uuid("user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    type: notificationTypeEnum("type").notNull(),
    titleSv: text("title_sv").notNull(),
    bodySv: text("body_sv").notNull(),
    data: jsonb("data"),
    /** i18n-spec §26: mall + variabler; titleSv/bodySv är renderad cache. */
    templateKey: text("template_key"),
    variables: jsonb("variables"),
    locale: text("locale"),
    scheduledFor: timestamp("scheduled_for", { withTimezone: true }),
    sentAt: timestamp("sent_at", { withTimezone: true }),
    readAt: timestamp("read_at", { withTimezone: true }),
    createdAt: createdAt(),
  },
  (t) => [index("notifications_user_idx").on(t.userId, t.createdAt)],
);

/** Push-tokens för Expo push. */
export const pushTokens = pgTable(
  "push_tokens",
  {
    userId: uuid("user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    token: text("token").notNull(),
    platform: text("platform").notNull(),
    updatedAt: updatedAt(),
  },
  (t) => [primaryKey({ columns: [t.userId, t.token] })],
);

/** Creator-statistik (spec §37). */
export const creatorStats = pgTable("creator_stats", {
  userId: uuid("user_id")
    .primaryKey()
    .references(() => users.id, { onDelete: "cascade" }),
  visibility: profileVisibilityEnum("visibility").notNull().default("private"),
  level: creatorLevelEnum("level").notNull().default("beginner"),
  publishedRecipes: integer("published_recipes").notNull().default(0),
  followers: integer("followers").notNull().default(0),
  totalCooks: integer("total_cooks").notNull().default(0),
  totalFavorites: integer("total_favorites").notNull().default(0),
  averageRating: doublePrecision("average_rating"),
  verifiedRecipes: integer("verified_recipes").notNull().default(0),
  badges: text("badges").array().notNull().default([]),
  updatedAt: updatedAt(),
});

export const creatorFollows = pgTable(
  "creator_follows",
  {
    followerUserId: uuid("follower_user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    creatorUserId: uuid("creator_user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    createdAt: createdAt(),
  },
  (t) => [primaryKey({ columns: [t.followerUserId, t.creatorUserId] })],
);

/** AI-evals (spec §34): fast testbibliotek + körningar. Ingen modelländring utan eval. */
export const aiEvalCases = pgTable("ai_eval_cases", {
  id: uuid("id").primaryKey().defaultRandom(),
  taskType: text("task_type").notNull(),
  nameSv: text("name_sv").notNull(),
  inputRef: jsonb("input_ref").notNull(),
  expectedOutput: jsonb("expected_output").notNull(),
  category: text("category").notNull().default("standard"),
  active: boolean("active").notNull().default(true),
  createdAt: createdAt(),
});

export const aiEvalRuns = pgTable(
  "ai_eval_runs",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    taskType: text("task_type").notNull(),
    modelVersion: text("model_version").notNull(),
    promptVersion: text("prompt_version").notNull(),
    metrics: jsonb("metrics").notNull(),
    passed: boolean("passed").notNull(),
    notes: text("notes"),
    createdAt: createdAt(),
  },
  (t) => [index("ai_eval_runs_task_idx").on(t.taskType, t.createdAt)],
);

/** Householdsvinn per vecka – aggregat för budget/matsvinnsvyer (spec §26). */
export const wasteSummaries = pgTable(
  "waste_summaries",
  {
    householdId: uuid("household_id")
      .notNull()
      .references(() => households.id, { onDelete: "cascade" }),
    weekStartDate: text("week_start_date").notNull(),
    discardedCount: integer("discarded_count").notNull().default(0),
    discardedValueMinor: integer("discarded_value_minor").notNull().default(0),
    updatedAt: updatedAt(),
  },
  (t) => [primaryKey({ columns: [t.householdId, t.weekStartDate] })],
);
