// Schema Drizzle pour Postgres.
// Tables d'authentification requises par Better Auth + extensions du plugin admin.
// La couche metier (clients, sites, factures, tickets) sera ajoutee au fur et a mesure
// du branchement reel des fonctionnalites du portail/admin.

import {
  pgTable,
  text,
  timestamp,
  boolean,
  integer,
} from "drizzle-orm/pg-core";

// === Better Auth : user ===
// Champs core + extensions du plugin admin (role / banned / banReason / banExpires).
// Champ metier `client_account_id` pour rattacher un utilisateur client a son compte.
// Les admins Novelia ont `client_account_id` a null.
export const user = pgTable("user", {
  id: text("id").primaryKey(),
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  emailVerified: boolean("email_verified").notNull().default(false),
  image: text("image"),
  // Plugin admin : "admin" pour l'equipe Novelia, "user" pour les clients.
  role: text("role").notNull().default("user"),
  banned: boolean("banned").notNull().default(false),
  banReason: text("ban_reason"),
  banExpires: timestamp("ban_expires"),
  // Rattachement au compte client (null pour les admins Novelia).
  clientAccountId: text("client_account_id"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Better Auth : session ===
export const session = pgTable("session", {
  id: text("id").primaryKey(),
  userId: text("user_id")
    .notNull()
    .references(() => user.id, { onDelete: "cascade" }),
  token: text("token").notNull().unique(),
  expiresAt: timestamp("expires_at").notNull(),
  ipAddress: text("ip_address"),
  userAgent: text("user_agent"),
  // Plugin admin : permet a un admin d'usurper temporairement une session client.
  impersonatedBy: text("impersonated_by"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Better Auth : account ===
// Pour email+password, password est stocke ici (hash argon2/bcrypt par Better Auth).
// Pour OAuth, accessToken / refreshToken / providerId sont utilises.
export const account = pgTable("account", {
  id: text("id").primaryKey(),
  userId: text("user_id")
    .notNull()
    .references(() => user.id, { onDelete: "cascade" }),
  accountId: text("account_id").notNull(),
  providerId: text("provider_id").notNull(),
  accessToken: text("access_token"),
  refreshToken: text("refresh_token"),
  accessTokenExpiresAt: timestamp("access_token_expires_at"),
  refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
  scope: text("scope"),
  idToken: text("id_token"),
  password: text("password"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Better Auth : verification ===
// Tokens de verification email, magic link, reset password.
export const verification = pgTable("verification", {
  id: text("id").primaryKey(),
  identifier: text("identifier").notNull(),
  value: text("value").notNull(),
  expiresAt: timestamp("expires_at").notNull(),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Metier : compte client ===
// Une entreprise cliente de Novelia. Peut avoir 1+ utilisateurs (rattaches via
// user.client_account_id) et 1+ sites (table client_site).
// Montants stockes en centimes (integer) pour eviter les flottants.
export const clientAccount = pgTable("client_account", {
  id: text("id").primaryKey(),
  companyName: text("company_name").notNull(),
  contactName: text("contact_name").notNull(),
  contactEmail: text("contact_email").notNull(),
  // Formule globale du compte (peut etre raffinee par site).
  plan: text("plan").notNull().default("presence"), // 'presence' | 'developpement' | 'ecommerce'
  // Statut operationnel : actif | suspendu | annule.
  status: text("status").notNull().default("actif"),
  // Notes internes Novelia (non visibles cote portail).
  notes: text("notes"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Integrations : token OAuth Google (singleton) ===
// Stocke le refresh_token obtenu via le flow OAuth quand l'admin connecte
// son compte Google a Novelia. Permet d'interroger GSC + GA4 sur tous les
// sites ou il a un acces personnel (Lecteur/Proprietaire).
// id fixe a 'default' tant qu'on a un seul admin connecte.
export const googleOauthToken = pgTable("google_oauth_token", {
  id: text("id").primaryKey(),
  refreshToken: text("refresh_token").notNull(),
  accessToken: text("access_token"),
  scope: text("scope").notNull(),
  tokenType: text("token_type").notNull().default("Bearer"),
  expiresAt: timestamp("expires_at"),
  // Email du compte Google connecte (affiche dans l'UI).
  connectedEmail: text("connected_email"),
  // User Novelia qui a fait la connexion (pour audit).
  connectedByUserId: text("connected_by_user_id").references(() => user.id, {
    onDelete: "set null",
  }),
  connectedAt: timestamp("connected_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// === Metier : site client ===
// Un site livre, rattache a un compte client. Statut, plan et montant mensuel
// peuvent etre propres au site (utile pour les comptes multi-sites a tarifs varies).
export const clientSite = pgTable("client_site", {
  id: text("id").primaryKey(),
  clientAccountId: text("client_account_id")
    .notNull()
    .references(() => clientAccount.id, { onDelete: "cascade" }),
  domain: text("domain").notNull(), // ex: cabinet-vidal.fr
  label: text("label"), // libelle court pour le selecteur (ex: "Cabinet de Lyon")
  status: text("status").notNull().default("en_preparation"), // en_preparation | en_ligne | maintenance
  plan: text("plan").notNull().default("presence"),
  // Montant mensuel en centimes (4999 = 49,99 €).
  monthlyAmountCents: integer("monthly_amount_cents").notNull().default(0),
  // Identifiants Google Cloud (Search Console site + GA4 property) renseignes
  // lors de l'onboarding. Null tant que pas connecte.
  searchConsoleSiteUrl: text("search_console_site_url"),
  ga4PropertyId: text("ga4_property_id"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});
