import { sql } from "drizzle-orm";
import { pgTable, text, varchar, timestamp, integer, boolean, jsonb, uuid, pgEnum, index } from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";

// Replit Auth: Session storage table (mandatory for Replit Auth)
export const sessions = pgTable(
  "sessions",
  {
    sid: varchar("sid").primaryKey(),
    sess: jsonb("sess").notNull(),
    expire: timestamp("expire").notNull(),
  },
  (table) => [index("IDX_session_expire").on(table.expire)],
);

export const genderEnum = pgEnum("gender", ["male", "female", "non-binary", "other"]);
export const orientationEnum = pgEnum("orientation", ["straight", "gay", "lesbian", "bisexual", "pansexual", "asexual", "other"]);
export const relationshipGoalEnum = pgEnum("relationship_goal", ["casual", "long-term", "marriage", "friendship", "unsure"]);
export const subscriptionTierEnum = pgEnum("subscription_tier", ["free", "plus", "premium"]);
export const reportStatusEnum = pgEnum("report_status", ["pending", "resolved", "dismissed"]);

// Users table - extended from Replit Auth base user
export const users = pgTable("users", {
  // Replit Auth base fields
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  email: varchar("email").unique(),
  firstName: varchar("first_name"),
  lastName: varchar("last_name"),
  profileImageUrl: varchar("profile_image_url"),
  // Dating app specific fields
  displayName: text("display_name"),
  birthDate: timestamp("birth_date"),
  gender: genderEnum("gender"),
  orientation: orientationEnum("orientation"),
  location: text("location"),
  latitude: text("latitude"),
  longitude: text("longitude"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
  lastActiveAt: timestamp("last_active_at").defaultNow().notNull(),
  verified: boolean("verified").default(false).notNull(),
});

export const profiles = pgTable("profiles", {
  id: uuid("id").primaryKey().defaultRandom(),
  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
  bio: text("bio"),
  photos: jsonb("photos").$type<string[]>().default([]).notNull(),
  interests: text("interests").array().default([]).notNull(),
  occupation: text("occupation"),
  education: text("education"),
  height: integer("height"),
  lifestyle: jsonb("lifestyle").$type<{
    smoking?: string;
    drinking?: string;
    pets?: string;
    religion?: string;
  }>(),
  relationshipGoal: relationshipGoalEnum("relationship_goal"),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

export const preferences = pgTable("preferences", {
  id: uuid("id").primaryKey().defaultRandom(),
  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
  minAge: integer("min_age").default(18).notNull(),
  maxAge: integer("max_age").default(99).notNull(),
  genderPreference: text("gender_preference").array().default([]).notNull(),
  maxDistance: integer("max_distance").default(50).notNull(),
  interestsRequired: text("interests_required").array().default([]),
  relationshipGoalPreference: relationshipGoalEnum("relationship_goal_preference"),
});

export const likes = pgTable("likes", {
  id: uuid("id").primaryKey().defaultRandom(),
  fromUserId: varchar("from_user_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  toUserId: varchar("to_user_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  action: text("action").notNull(), // 'like' or 'pass'
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

export const matches = pgTable("matches", {
  id: uuid("id").primaryKey().defaultRandom(),
  userAId: varchar("user_a_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  userBId: varchar("user_b_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  active: boolean("active").default(true).notNull(),
});

export const messages = pgTable("messages", {
  id: uuid("id").primaryKey().defaultRandom(),
  matchId: uuid("match_id").references(() => matches.id, { onDelete: "cascade" }).notNull(),
  senderId: varchar("sender_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  content: text("content").notNull(),
  sentAt: timestamp("sent_at").defaultNow().notNull(),
  readAt: timestamp("read_at"),
});

export const reports = pgTable("reports", {
  id: uuid("id").primaryKey().defaultRandom(),
  reporterId: varchar("reporter_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  reportedUserId: varchar("reported_user_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
  reason: text("reason").notNull(),
  details: text("details"),
  status: reportStatusEnum("status").default("pending").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  resolvedAt: timestamp("resolved_at"),
});

export const subscriptions = pgTable("subscriptions", {
  id: uuid("id").primaryKey().defaultRandom(),
  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }).notNull().unique(),
  tier: subscriptionTierEnum("tier").default("free").notNull(),
  stripeSubscriptionId: text("stripe_subscription_id"),
  startsAt: timestamp("starts_at").defaultNow().notNull(),
  endsAt: timestamp("ends_at"),
  active: boolean("active").default(true).notNull(),
});

// Insert schemas
export const insertUserSchema = createInsertSchema(users).omit({
  id: true,
  createdAt: true,
  lastActiveAt: true,
  verified: true,
}).extend({
  birthDate: z.string().or(z.date()),
});

export const insertProfileSchema = createInsertSchema(profiles).omit({
  id: true,
  updatedAt: true,
}).extend({
  photos: z.array(z.string()).optional(),
  interests: z.array(z.string()).optional(),
});

export const insertPreferenceSchema = createInsertSchema(preferences).omit({
  id: true,
});

export const insertLikeSchema = createInsertSchema(likes).omit({
  id: true,
  createdAt: true,
});

export const insertMatchSchema = createInsertSchema(matches).omit({
  id: true,
  createdAt: true,
  active: true,
});

export const insertMessageSchema = createInsertSchema(messages).omit({
  id: true,
  sentAt: true,
  readAt: true,
});

export const insertReportSchema = createInsertSchema(reports).omit({
  id: true,
  createdAt: true,
  resolvedAt: true,
  status: true,
});

export const insertSubscriptionSchema = createInsertSchema(subscriptions).omit({
  id: true,
  startsAt: true,
  active: true,
});

// Types
export type InsertUser = z.infer<typeof insertUserSchema>;
export type User = typeof users.$inferSelect;
export type UpsertUser = typeof users.$inferInsert; // For Replit Auth

export type InsertProfile = z.infer<typeof insertProfileSchema>;
export type Profile = typeof profiles.$inferSelect;

export type InsertPreference = z.infer<typeof insertPreferenceSchema>;
export type Preference = typeof preferences.$inferSelect;

export type InsertLike = z.infer<typeof insertLikeSchema>;
export type Like = typeof likes.$inferSelect;

export type InsertMatch = z.infer<typeof insertMatchSchema>;
export type Match = typeof matches.$inferSelect;

export type InsertMessage = z.infer<typeof insertMessageSchema>;
export type Message = typeof messages.$inferSelect;

export type InsertReport = z.infer<typeof insertReportSchema>;
export type Report = typeof reports.$inferSelect;

export type InsertSubscription = z.infer<typeof insertSubscriptionSchema>;
export type Subscription = typeof subscriptions.$inferSelect;
