import { sql } from 'drizzle-orm';
import * as t from 'drizzle-orm/pg-core';
import { timestamps } from '../timestamps';
import { municipalities, parishes, states } from './general';
import { authSchema } from './schemas';

// Tabla de Usuarios sistema
export const users = authSchema.table(
  'users',
  {
    id: t.serial('id').primaryKey(),
    username: t.text('username').unique().notNull(),
    email: t.text('email').unique().notNull(),
    fullname: t.text('fullname').notNull(),
    phone: t.text('phone'),
    password: t.text('password').notNull(),
    state: t
      .integer('state')
      .references(() => states.id, { onDelete: 'set null' }),
    municipality: t
      .integer('municipality')
      .references(() => municipalities.id, { onDelete: 'set null' }),
    parish: t
      .integer('parish')
      .references(() => parishes.id, { onDelete: 'set null' }),
    isTwoFactorEnabled: t
      .boolean('is_two_factor_enabled')
      .notNull()
      .default(false),
    twoFactorSecret: t.text('two_factor_secret'),
    isEmailVerified: t.boolean('is_email_verified').notNull().default(false),
    isActive: t.boolean('is_active').notNull().default(true),
    ...timestamps,
  },
  (users) => ({
    usersIdx: t.index('users_idx').on(users.username),
  }),
);

// Tabla de Roles
export const roles = authSchema.table(
  'roles',
  {
    id: t.serial('id').primaryKey(),
    name: t.text('name').notNull(),
    ...timestamps,
  },
  (roles) => ({
    rolesIdx: t.index('roles_idx').on(roles.name),
  }),
);

//tabla User_roles
export const usersRole = authSchema.table(
  'user_role',
  {
    id: t.serial('id').primaryKey(),
    userId: t
      .integer('user_id')
      .references(() => users.id, { onDelete: 'cascade' }),
    roleId: t
      .integer('role_id')
      .references(() => roles.id, { onDelete: 'set null' }),
    ...timestamps,
  },
  (userRole) => ({
    userRoleIdx: t.index('user_role_idx').on(userRole.userId),
  }),
);

export const userAccessView = authSchema.view('user_access_view', {
  userId: t.integer('userId').notNull(),
  username: t.text('username').notNull(),
  email: t.text('email').notNull(),
  fullname: t.text('email').notNull(),
  roleId: t.integer('role_id'),
  roleName: t.text('role_name'),
}).as(sql`
   SELECT
    u.id AS user_id,
    u.username,
    u.email,
    u.fullname,
    r.id AS role_id,
    r.name AS role_name
FROM
  auth.users u
LEFT JOIN
  auth.user_role ur ON u.id = ur.user_id 
LEFT JOIN
  auth.roles r ON ur.role_id  = r.id`);

// Tabla de Sesiones
export const sessions = authSchema.table(
  'sessions',
  {
    id: t
      .uuid('id')
      .primaryKey()
      .default(sql`gen_random_uuid()`),
    userId: t
      .integer('user_id')
      .references(() => users.id, { onDelete: 'cascade' })
      .notNull(),
    sessionToken: t.text('session_token').notNull(),
    expiresAt: t.integer('expires_at').notNull(),
    previousSessionToken: t.varchar('previous_session_token'),
    lastRotatedAt: t.timestamp('last_rotated_at'),

    ...timestamps,
  },
  (sessions) => ({
    sessionsIdx: t.index('sessions_idx').on(sessions.sessionToken),
  }),
);

//tabla de tokens de verificación
export const verificationTokens = authSchema.table(
  'verificationToken',
  {
    identifier: t.text('identifier').notNull(),
    token: t.text('token').notNull(),
    code: t.integer('code'),
    expires: t.timestamp('expires', { mode: 'date' }).notNull(),
    ipAddress: t.text('ip_address').notNull(),
  },
  (verificationToken) => [
    {
      compositePk: t.primaryKey({
        columns: [verificationToken.identifier, verificationToken.token],
      }),
    },
  ],
);
