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

// Enums for better type safety
export const contentTypeEnum = pgEnum('content_type', ['video', 'oddaja', 'music_video', 'documentary', 'live']);
export const genreEnum = pgEnum('genre', ['volksmusik', 'schlager', 'pop', 'rock', 'country', 'instrumental', 'dance', 'other']);

export const videos = pgTable("videos", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  title: text("title").notNull(),
  artist: text("artist"), // Izvajalec/Artist name
  description: text("description").default("").notNull(),
  filename: text("filename"), // Original file name from Bunny.net
  episodeNumber: integer("episode_number"), // For shows like "Folx Stadl"
  episodeTitle: text("episode_title"), // Episode title for shows
  thumbnailUrl: text("thumbnail_url").notNull(),
  customThumbnailUrl: text("custom_thumbnail_url"),
  faceCenterPosition: text("face_center_position"), // CSS object-position for face centering
  facesDetected: integer("faces_detected").default(0), // Number of faces detected
  faceConfidence: real("face_confidence").default(0), // Confidence score of primary face
  videoUrl: text("video_url").notNull(),
  videoUrlMp4: text("video_url_mp4"),
  videoUrlIframe: text("video_url_iframe"),
  duration: integer("duration").notNull(), // in seconds
  views: integer("views").notNull().default(0),
  category: text("category").default("").notNull(),
  contentType: contentTypeEnum("content_type").default('video').notNull(),
  genre: genreEnum("genre").default('other').notNull(),
  tags: text("tags").array().default([]).notNull(),
  isPublic: boolean("is_public").default(true).notNull(),
  uploadStatus: text("upload_status").default("pending").notNull(), // pending, processing, completed, failed
  originalFileName: text("original_file_name"),
  fileSize: integer("file_size"), // in bytes
  bitrate: integer("bitrate"), // in kbps
  resolution: text("resolution"), // e.g., "1920x1080"
  format: text("format"), // e.g., "mp4", "avi", "mov"
  encoding: text("encoding"), // e.g., "h264", "h265"
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
  updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// User table for authentication and video ownership
export const users = pgTable("users", {
  id: varchar("id").primaryKey(),
  username: varchar("username", { length: 50 }).notNull().unique(),
  email: varchar("email", { length: 255 }).notNull().unique(),
  passwordHash: varchar("password_hash", { length: 255 }).notNull(),
  firstName: varchar("first_name", { length: 100 }),
  lastName: varchar("last_name", { length: 100 }),
  avatar: text("avatar"),
  isActive: boolean("is_active").default(true).notNull(),
  isAdmin: boolean("is_admin").default(false),
  isSuperAdmin: boolean("is_super_admin").default(false).notNull(),
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
  updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// Video uploads table for tracking upload progress
export const videoUploads = pgTable("video_uploads", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  userId: varchar("user_id").notNull().references(() => users.id),
  videoId: varchar("video_id").references(() => videos.id),
  originalFileName: text("original_file_name").notNull(),
  fileSize: integer("file_size").notNull(),
  mimeType: text("mime_type").notNull(),
  uploadStatus: text("upload_status").default("uploading").notNull(), // uploading, processing, completed, failed
  uploadProgress: real("upload_progress").default(0).notNull(), // 0-1
  errorMessage: text("error_message"),
  uploadUrl: text("upload_url"), // presigned URL for upload
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
  updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// Categories table for better organization
export const categories = pgTable("categories", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  name: text("name").notNull().unique(),
  description: text("description"),
  color: varchar("color", { length: 7 }).default("#000000").notNull(), // hex color
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// Tags table for better organization
export const tags = pgTable("tags", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  name: text("name").notNull().unique(),
  useCount: integer("use_count").default(0).notNull(),
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// Video tags junction table
export const videoTags = pgTable("video_tags", {
  videoId: varchar("video_id").notNull().references(() => videos.id, { onDelete: "cascade" }),
  tagId: varchar("tag_id").notNull().references(() => tags.id, { onDelete: "cascade" }),
});

// Session storage table 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)
]);

// Video ads/spots table for storing advertisement metadata
export const videoAds = pgTable("video_ads", {
  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
  videoId: varchar("video_id").notNull().references(() => videos.id, { onDelete: "cascade" }),
  adType: text("ad_type").notNull(), // preroll, midroll, postroll
  adUrl: text("ad_url").notNull(), // VAST URL or direct video URL
  adTitle: text("ad_title"),
  adDuration: integer("ad_duration"), // in seconds
  position: integer("position").default(0), // for midroll ads - position in video (seconds)
  skipAfter: integer("skip_after"), // seconds after which ad can be skipped
  vastTag: text("vast_tag"), // VAST XML tag URL
  adNetwork: text("ad_network"), // network name (e.g., Google AdX, Publift)
  isActive: boolean("is_active").default(true).notNull(),
  priority: integer("priority").default(1), // ad priority (1 = highest)
  createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
  updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});

// Schemas for form validation and API
export const insertVideoSchema = createInsertSchema(videos).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});

export const updateVideoSchema = createInsertSchema(videos).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
}).partial();

export const insertUserSchema = createInsertSchema(users).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});

export const insertVideoUploadSchema = createInsertSchema(videoUploads).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});

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

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

export const insertVideoAdSchema = createInsertSchema(videoAds).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});

// Type exports
export type Video = typeof videos.$inferSelect;
export type InsertVideo = z.infer<typeof insertVideoSchema>;
export type UpdateVideo = z.infer<typeof updateVideoSchema>;

export type VideoAd = typeof videoAds.$inferSelect;
export type InsertVideoAd = z.infer<typeof insertVideoAdSchema>;

export type User = typeof users.$inferSelect;
export type InsertUser = z.infer<typeof insertUserSchema>;

export type VideoUpload = typeof videoUploads.$inferSelect;
export type InsertVideoUpload = z.infer<typeof insertVideoUploadSchema>;

export type Category = typeof categories.$inferSelect;
export type InsertCategory = z.infer<typeof insertCategorySchema>;

export type Tag = typeof tags.$inferSelect;
export type InsertTag = z.infer<typeof insertTagSchema>;
