import {
	doublePrecision,
	integer,
	pgTable,
	primaryKey,
	serial,
	text,
	timestamp,
	unique,
} from "drizzle-orm/pg-core";

// ── Users ───────────────────────────────────────────────────────────

export const users = pgTable("users", {
	id: serial("id").primaryKey(),
	logtoSub: text("logto_sub").notNull().unique(),
	displayName: text("display_name"),
	avatarUrl: text("avatar_url"),
	bio: text("bio"),
	createdAt: timestamp("created_at").defaultNow().notNull(),
});

// ── Categories ──────────────────────────────────────────────────────

export const categories = pgTable(
	"categories",
	{
		id: serial("id").primaryKey(),
		name: text("name").notNull(),
		icon: text("icon").notNull().default("package"),
		userId: integer("user_id")
			.notNull()
			.references(() => users.id),
		createdAt: timestamp("created_at").defaultNow().notNull(),
	},
	(table) => [unique().on(table.userId, table.name)],
);

// ── Items ───────────────────────────────────────────────────────────

export const items = pgTable("items", {
	id: serial("id").primaryKey(),
	name: text("name").notNull(),
	weightGrams: doublePrecision("weight_grams"),
	priceCents: integer("price_cents"),
	categoryId: integer("category_id")
		.notNull()
		.references(() => categories.id),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	notes: text("notes"),
	productUrl: text("product_url"),
	imageFilename: text("image_filename"),
	imageSourceUrl: text("image_source_url"),
	quantity: integer("quantity").notNull().default(1),
	globalItemId: integer("global_item_id").references(() => globalItems.id),
	purchasePriceCents: integer("purchase_price_cents"),
	brand: text("brand"),
	dominantColor: text("dominant_color"),
	cropZoom: doublePrecision("crop_zoom"),
	cropX: doublePrecision("crop_x"),
	cropY: doublePrecision("crop_y"),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// ── Threads ─────────────────────────────────────────────────────────

export const threads = pgTable("threads", {
	id: serial("id").primaryKey(),
	name: text("name").notNull(),
	status: text("status").notNull().default("active"),
	resolvedCandidateId: integer("resolved_candidate_id"),
	categoryId: integer("category_id")
		.notNull()
		.references(() => categories.id),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// ── Thread Candidates ───────────────────────────────────────────────

export const threadCandidates = pgTable("thread_candidates", {
	id: serial("id").primaryKey(),
	threadId: integer("thread_id")
		.notNull()
		.references(() => threads.id, { onDelete: "cascade" }),
	name: text("name").notNull(),
	weightGrams: doublePrecision("weight_grams"),
	priceCents: integer("price_cents"),
	categoryId: integer("category_id")
		.notNull()
		.references(() => categories.id),
	notes: text("notes"),
	productUrl: text("product_url"),
	imageFilename: text("image_filename"),
	imageSourceUrl: text("image_source_url"),
	dominantColor: text("dominant_color"),
	cropZoom: doublePrecision("crop_zoom"),
	cropX: doublePrecision("crop_x"),
	cropY: doublePrecision("crop_y"),
	status: text("status").notNull().default("researching"),
	pros: text("pros"),
	cons: text("cons"),
	sortOrder: doublePrecision("sort_order").notNull().default(0),
	globalItemId: integer("global_item_id").references(() => globalItems.id),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// ── Setups ──────────────────────────────────────────────────────────

export const setups = pgTable("setups", {
	id: serial("id").primaryKey(),
	name: text("name").notNull(),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	visibility: text("visibility").notNull().default("private"),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

// ── Setup Items ─────────────────────────────────────────────────────

export const setupItems = pgTable("setup_items", {
	id: serial("id").primaryKey(),
	setupId: integer("setup_id")
		.notNull()
		.references(() => setups.id, { onDelete: "cascade" }),
	itemId: integer("item_id")
		.notNull()
		.references(() => items.id, { onDelete: "cascade" }),
	classification: text("classification").notNull().default("base"),
});

// ── Shares ─────────────────────────────────────────────────────────

export const shares = pgTable("shares", {
	id: serial("id").primaryKey(),
	setupId: integer("setup_id")
		.notNull()
		.references(() => setups.id, { onDelete: "cascade" }),
	token: text("token").notNull().unique(),
	permission: text("permission").notNull().default("read"),
	expiresAt: timestamp("expires_at"),
	userId: integer("user_id").references(() => users.id),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	revokedAt: timestamp("revoked_at"),
});

// ── Global Items ────────────────────────────────────────────────────

export const globalItems = pgTable(
	"global_items",
	{
		id: serial("id").primaryKey(),
		brand: text("brand").notNull(),
		model: text("model").notNull(),
		category: text("category"),
		weightGrams: doublePrecision("weight_grams"),
		priceCents: integer("price_cents"),
		imageUrl: text("image_url"),
		description: text("description"),
		sourceUrl: text("source_url"),
		imageCredit: text("image_credit"),
		imageSourceUrl: text("image_source_url"),
		dominantColor: text("dominant_color"),
		cropZoom: doublePrecision("crop_zoom"),
		cropX: doublePrecision("crop_x"),
		cropY: doublePrecision("crop_y"),
		createdAt: timestamp("created_at").defaultNow().notNull(),
	},
	(table) => [unique().on(table.brand, table.model)],
);

// ── Tags ───────────────────────────────────────────────────────────

export const tags = pgTable("tags", {
	id: serial("id").primaryKey(),
	name: text("name").notNull().unique(),
	createdAt: timestamp("created_at").defaultNow().notNull(),
});

// ── Global Item Tags ───────────────────────────────────────────────

export const globalItemTags = pgTable(
	"global_item_tags",
	{
		globalItemId: integer("global_item_id")
			.notNull()
			.references(() => globalItems.id, { onDelete: "cascade" }),
		tagId: integer("tag_id")
			.notNull()
			.references(() => tags.id, { onDelete: "cascade" }),
	},
	(table) => [primaryKey({ columns: [table.globalItemId, table.tagId] })],
);

// ── Settings ────────────────────────────────────────────────────────

export const settings = pgTable(
	"settings",
	{
		userId: integer("user_id")
			.notNull()
			.references(() => users.id),
		key: text("key").notNull(),
		value: text("value").notNull(),
	},
	(table) => [primaryKey({ columns: [table.userId, table.key] })],
);

// ── API Keys ────────────────────────────────────────────────────────

export const apiKeys = pgTable("api_keys", {
	id: serial("id").primaryKey(),
	name: text("name").notNull(),
	keyHash: text("key_hash").notNull(),
	keyPrefix: text("key_prefix").notNull(),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	createdAt: timestamp("created_at").defaultNow().notNull(),
});

// ── OAuth Clients ───────────────────────────────────────────────────

export const oauthClients = pgTable("oauth_clients", {
	id: serial("id").primaryKey(),
	clientId: text("client_id").notNull().unique(),
	clientName: text("client_name"),
	redirectUris: text("redirect_uris").notNull(), // JSON array
	createdAt: timestamp("created_at").defaultNow().notNull(),
});

// ── OAuth Authorization Codes ───────────────────────────────────────

export const oauthCodes = pgTable("oauth_codes", {
	id: serial("id").primaryKey(),
	code: text("code").notNull().unique(),
	clientId: text("client_id").notNull(),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	codeChallenge: text("code_challenge").notNull(),
	codeChallengeMethod: text("code_challenge_method").notNull().default("S256"),
	redirectUri: text("redirect_uri").notNull(),
	expiresAt: timestamp("expires_at").notNull(),
	used: integer("used").notNull().default(0),
});

// ── OAuth Tokens ────────────────────────────────────────────────────

export const oauthTokens = pgTable("oauth_tokens", {
	id: serial("id").primaryKey(),
	accessTokenHash: text("access_token_hash").notNull().unique(),
	refreshTokenHash: text("refresh_token_hash").notNull().unique(),
	clientId: text("client_id").notNull(),
	userId: integer("user_id")
		.notNull()
		.references(() => users.id),
	expiresAt: timestamp("expires_at").notNull(),
	refreshExpiresAt: timestamp("refresh_expires_at").notNull(),
	createdAt: timestamp("created_at").defaultNow().notNull(),
});
