import {
  boolean,
  index,
  integer,
  jsonb,
  pgTable,
  text,
  timestamp,
  uniqueIndex,
  uuid,
} from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
import {
  createdAt,
  subscriptionPlanEnum,
  subscriptionProviderEnum,
  subscriptionStatusEnum,
  updatedAt,
} from "./_shared.js";
import { households } from "./households.js";
import { users } from "./users.js";

/** Backend är source of truth för Premium (spec §47, §61.14). */
export const subscriptions = pgTable(
  "subscriptions",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    userId: uuid("user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    householdId: uuid("household_id").references(() => households.id, { onDelete: "set null" }),
    provider: subscriptionProviderEnum("provider").notNull(),
    productId: text("product_id").notNull(),
    plan: subscriptionPlanEnum("plan").notNull(),
    originalTransactionId: text("original_transaction_id"),
    status: subscriptionStatusEnum("status").notNull(),
    purchasedAt: timestamp("purchased_at", { withTimezone: true }),
    expiresAt: timestamp("expires_at", { withTimezone: true }),
    gracePeriodExpiresAt: timestamp("grace_period_expires_at", { withTimezone: true }),
    canceledAt: timestamp("canceled_at", { withTimezone: true }),
    lastVerifiedAt: timestamp("last_verified_at", { withTimezone: true }),
    createdAt: createdAt(),
    updatedAt: updatedAt(),
  },
  (t) => [
    index("subscriptions_user_idx").on(t.userId),
    uniqueIndex("subscriptions_original_tx_unique")
      .on(t.provider, t.originalTransactionId)
      .where(sql`${t.originalTransactionId} IS NOT NULL`),
  ],
);

/** Händelselogg: köp, förnyelse, grace, churn (spec §47). */
export const subscriptionEvents = pgTable(
  "subscription_events",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    subscriptionId: uuid("subscription_id").references(() => subscriptions.id, {
      onDelete: "cascade",
    }),
    userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
    eventType: text("event_type").notNull(),
    payload: jsonb("payload"),
    createdAt: createdAt(),
  },
  (t) => [index("subscription_events_sub_idx").on(t.subscriptionId, t.createdAt)],
);

/** Råa store-transaktioner för revision (spec §47). */
export const storeTransactions = pgTable(
  "store_transactions",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    provider: subscriptionProviderEnum("provider").notNull(),
    transactionId: text("transaction_id").notNull(),
    originalTransactionId: text("original_transaction_id"),
    userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
    productId: text("product_id"),
    rawPayload: jsonb("raw_payload").notNull(),
    processedAt: timestamp("processed_at", { withTimezone: true }),
    createdAt: createdAt(),
  },
  (t) => [uniqueIndex("store_transactions_unique").on(t.provider, t.transactionId)],
);

/** App Store Server Notifications / Play RTDN – tas emot rått, processas av worker. */
export const storeNotifications = pgTable(
  "store_notifications",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    provider: subscriptionProviderEnum("provider").notNull(),
    notificationType: text("notification_type"),
    rawPayload: jsonb("raw_payload").notNull(),
    signatureVerified: boolean("signature_verified").notNull().default(false),
    processed: boolean("processed").notNull().default(false),
    processedAt: timestamp("processed_at", { withTimezone: true }),
    error: text("error"),
    createdAt: createdAt(),
  },
  (t) => [index("store_notifications_pending_idx").on(t.processed, t.createdAt)],
);

/** Trial-spårning: en trial per användare (spec §46). */
export const trials = pgTable("trials", {
  userId: uuid("user_id")
    .primaryKey()
    .references(() => users.id, { onDelete: "cascade" }),
  startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
  endsAt: timestamp("ends_at", { withTimezone: true }).notNull(),
});

/** Månatlig AI-användning för fair use / gratiskvot (spec §45–46). */
export const aiUsageCounters = pgTable(
  "ai_usage_counters",
  {
    userId: uuid("user_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    /** Format YYYY-MM. */
    month: text("month").notNull(),
    aiScans: integer("ai_scans").notNull().default(0),
    aiTokensIn: integer("ai_tokens_in").notNull().default(0),
    aiTokensOut: integer("ai_tokens_out").notNull().default(0),
    updatedAt: updatedAt(),
  },
  (t) => [uniqueIndex("ai_usage_user_month_unique").on(t.userId, t.month)],
);
