import { relations } from 'drizzle-orm';
import { int, text, sqliteTable as table, primaryKey, blob } from 'drizzle-orm/sqlite-core';

export const usersTable = table("users", {
    id: int().primaryKey({ autoIncrement: true }),
    username: text().notNull().unique(),
    email: text().notNull().unique(),
    hash: text().notNull().unique(),
    state: int().notNull().default(0),
});

export const usersDataTable = table("users_data", {
    id: int().primaryKey().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    signin: int({ mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
    lastTimestamp: int({ mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
});

export const userSessionsTable = table("user_sessions", {
    id: int().notNull(),
    user_id: int().notNull().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    timestamp: int({ mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
}, (table) => [primaryKey({ columns: [table.id, table.user_id] })]);

export const userPermissionsTable = table("user_permissions", {
    id: int().notNull().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    permission: text().notNull(),
}, (table) => [primaryKey({ columns: [table.id, table.permission] })]);

export const projectFilesTable = table("project_files", {
    id: text().primaryKey(),
    path: text().notNull().unique(),
    owner: int().notNull().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    title: text().notNull(),
    type: text({ enum: ['file', 'folder', 'markdown', 'canvas', 'map'] }).notNull(),
    navigable: int({ mode: 'boolean' }).notNull().default(true),
    private: int({ mode: 'boolean' }).notNull().default(false),
    order: int().notNull(),
    timestamp: int({ mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
});

export const projectContentTable = table("project_content", {
    id: text().primaryKey(),
    content: blob({ mode: 'buffer' }),
});

export const emailValidationTable = table("email_validation", {
    id: text().primaryKey(),
    timestamp: int({ mode: 'timestamp' }).notNull(),
})

export const characterTable = table("character", {
    id: int().primaryKey({ autoIncrement: true }),
    name: text().notNull(),
    owner: int().notNull().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    people: text().notNull(),
    level: int().notNull().default(1),
    variables: text({ mode: 'json' }).notNull().default('{"health": 0,"mana": 0,"spells": [],"items": [],"exhaustion": 0,"sickness": [],"poisons": []}'),
    aspect: int(),
    public_notes: text(),
    private_notes: text(),
    
    visibility: text({ enum: ['private', 'public'] }).notNull().default('private'),
    thumbnail: blob(),
});

export const characterTrainingTable = table("character_training", {
    character: int().notNull().references(() => characterTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    stat: text({ enum: ["strength","dexterity","constitution","intelligence","curiosity","charisma","psyche"] }).notNull(),
    level: int().notNull(),
    choice: int().notNull(),
}, (table) => [primaryKey({ columns: [table.character, table.stat, table.level] })]);

export const characterLevelingTable = table("character_leveling", {
    character: int().notNull().references(() => characterTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    level: int().notNull(),
    choice: int().notNull(),
}, (table) => [primaryKey({ columns: [table.character, table.level] })]);

export const characterAbilitiesTable = table("character_abilities", {
    character: int().notNull().references(() => characterTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    ability: text({ enum: ["athletics","acrobatics","intimidation","sleightofhand","stealth","survival","investigation","history","religion","arcana","understanding","perception","performance","medecine","persuasion","animalhandling","deception"] }).notNull(),
    value: int().notNull().default(0),
    max: int().notNull().default(0),
}, (table) => [primaryKey({ columns: [table.character, table.ability] })]);

export const characterChoicesTable = table("character_choices", {
    character: int().notNull().references(() => characterTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
    id: text().notNull(),
    choice: int().notNull(),
}, (table) => [primaryKey({ columns: [table.character, table.id, table.choice] })]);

export const usersRelation = relations(usersTable, ({ one, many }) => ({
    data: one(usersDataTable, { fields: [usersTable.id], references: [usersDataTable.id], }),
    session: many(userSessionsTable),
    permission: many(userPermissionsTable),
    files: many(projectFilesTable),
}));
export const usersDataRelation = relations(usersDataTable, ({ one }) => ({
    users: one(usersTable, { fields: [usersDataTable.id], references: [usersTable.id], }),
}));
export const userSessionsRelation = relations(userSessionsTable, ({ one }) => ({
    users: one(usersTable, { fields: [userSessionsTable.user_id], references: [usersTable.id], }),
}));
export const userPermissionsRelation = relations(userPermissionsTable, ({ one }) => ({
    users: one(usersTable, { fields: [userPermissionsTable.id], references: [usersTable.id], }),
}));
export const projectFilesRelation = relations(projectFilesTable, ({ one }) => ({
    users: one(usersTable, { fields: [projectFilesTable.owner], references: [usersTable.id], }),
}));
export const characterRelation = relations(characterTable, ({ one, many }) => ({
    user: one(usersTable, { fields: [characterTable.owner], references: [usersTable.id], }),
    training: many(characterTrainingTable),
    levels: many(characterLevelingTable),
    abilities: many(characterAbilitiesTable),
    choices: many(characterChoicesTable)
}));

export const characterTrainingRelation = relations(characterTrainingTable, ({ one }) => ({
    character: one(characterTable, { fields: [characterTrainingTable.character], references: [characterTable.id] })
}));
export const characterLevelingRelation = relations(characterLevelingTable, ({ one }) => ({
    character: one(characterTable, { fields: [characterLevelingTable.character], references: [characterTable.id] })
}));
export const characterAbilitiesRelation = relations(characterAbilitiesTable, ({ one }) => ({
    character: one(characterTable, { fields: [characterAbilitiesTable.character], references: [characterTable.id] })
}));
export const characterChoicesRelation = relations(characterChoicesTable, ({ one }) => ({
    character: one(characterTable, { fields: [characterChoicesTable.character], references: [characterTable.id] })
}));