CREATE DATABASE IF NOT EXISTS spaces;
USE spaces;

CREATE TABLE IF NOT EXISTS roles (
  id INT PRIMARY KEY AUTO_INCREMENT,
  role VARCHAR(16) NOT NULL
);

INSERT IGNORE INTO roles (role)
  VALUES ('owner'), ('developer'), ('user');

CREATE TABLE IF NOT EXISTS user (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(32) NOT NULL UNIQUE,
  email VARCHAR(64),
  passwordHash VARCHAR(256) NOT NULL,
  role INT DEFAULT 3,
  createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  lastActive TIMESTAMP DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  isActive BOOLEAN DEFAULT FALSE,
  profilePicture VARCHAR(256),
  bio VARCHAR(256),
  website VARCHAR(64),
  FOREIGN KEY (role) REFERENCES roles (id) ON DELETE CASCADE
);

INSERT IGNORE INTO user (username, email, passwordHash, role, profilePicture)
  VALUES ('joshashton', 'me@joshashton.dev', '$2y$12$CDMWB7IzcURWaxPxb1RrZezgy5acNFU7kSogM/ObohAZPT0.3H75K', 1, '2025.jpg');

CREATE TABLE IF NOT EXISTS rememberUser (
  token VARCHAR(128) PRIMARY KEY,
  id INT NOT NULL,
  remoteAddr VARCHAR(64) NOT NULL,
  httpForward VARCHAR(64),
  createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (id) REFERENCES user (id) ON DELETE CASCADE
); -- TODO: Need cron job to auto-delete after 30 days of inactivity

CREATE TABLE IF NOT EXISTS postTypes (
  id INT PRIMARY KEY AUTO_INCREMENT,
  postType VARCHAR(16)
);

INSERT IGNORE INTO postTypes (postType)
  VALUES ('essay'), ('moment'), ('thought');

CREATE TABLE IF NOT EXISTS postStatus (
    id INT PRIMARY KEY AUTO_INCREMENT,
    status VARCHAR(16)
);

INSERT IGNORE INTO postStatus (status)
    VALUES ('draft'), ('published');

CREATE TABLE IF NOT EXISTS spaceVisibility (
  id INT PRIMARY KEY AUTO_INCREMENT,
  spaceVisibility VARCHAR(16)
);

INSERT IGNORE INTO spaceVisibility (spaceVisibility)
  VALUES ('open'), ('public'), ('request'), ('invite'), ('private');

CREATE TABLE IF NOT EXISTS space (
    id INT PRIMARY KEY AUTO_INCREMENT,
    visibility INT NOT NULL,
    name VARCHAR(64) NOT NULL,
    description TEXT,
    parent INT DEFAULT NULL,
    createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (parent) REFERENCES space(id) ON DELETE SET NULL,
    FOREIGN KEY (visibility) REFERENCES spaceVisibility(id)
);

INSERT IGNORE INTO space (visibility, name, description)
    VALUES (5, "joshashton", "Thoughts, Moments, and Essays that I braindump.");

CREATE TABLE IF NOT EXISTS spaceRoles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    role VARCHAR(16) NOT NULL
);

INSERT IGNORE INTO spaceRoles (role)
    VALUES ("owner"), ("administrator"), ("moderator"), ("viewer");

CREATE TABLE IF NOT EXISTS spaceMembers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user INT NOT NULL,
    space INT NOT NULL,
    role INT NOT NULL,
    addedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    favorited BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (user) REFERENCES user(id),
    FOREIGN KEY (space) REFERENCES space(id),
    FOREIGN KEY (role) REFERENCES spaceRoles(id)
);

INSERT IGNORE INTO spaceMembers (id, user, space, role)
    VALUES (1, 1, 1, 1);

CREATE TABLE IF NOT EXISTS post (
    id INT PRIMARY KEY AUTO_INCREMENT,
    space INT NOT NULL,
    creator INT NOT NULL,
    postType INT NOT NULL,
    status INT NOT NULL,
    title VARCHAR(255), -- Make title nullable to accommodate Moments and Thoughts
    markdown TEXT,      -- For Essays
    excerpt VARCHAR(255), -- For Essays
    caption TEXT,       -- For Moments
    images TEXT,        -- Store image filenames as JSON for Moments
    thought TEXT,       -- For Thoughts
    seenCount INT DEFAULT 0,
    createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE,
    FOREIGN KEY (status) REFERENCES postStatus(id) ON DELETE CASCADE,
    FOREIGN KEY (creator) REFERENCES user(id) ON DELETE CASCADE,
    FOREIGN KEY (postType) REFERENCES postTypes(id)
);

CREATE TABLE IF NOT EXISTS spacePosts (
    post INT NOT NULL,
    space INT NOT NULL,
    PRIMARY KEY (post, space),
    FOREIGN KEY (post) REFERENCES post(id) ON DELETE CASCADE,
    FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS topics (
  id INT PRIMARY KEY AUTO_INCREMENT,
  topic VARCHAR(16) NOT NULL
);

CREATE TABLE IF NOT EXISTS postTopics (
  post INT NOT NULL,
  topic INT NOT NULL,
  PRIMARY KEY (post, topic),
  FOREIGN KEY (post) REFERENCES post(id) ON DELETE CASCADE,
  FOREIGN KEY (topic) REFERENCES topics(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS todoPriority (
    id INT PRIMARY KEY AUTO_INCREMENT,
    priority VARCHAR(16) NOT NULL
);

INSERT IGNORE INTO todoPriority (priority)
    VALUES ("Low"), ("Medium"), ("High"), ("Urgent");

CREATE TABLE IF NOT EXISTS todo (
    id INT NOT NULL,
    space INT NOT NULL,
    title VARCHAR(32) NOT NULL,
    description TEXT,
    due DATETIME,
    priority INT NOT NULL,
    link TEXT,
    createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id, space),
    FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE,
    FOREIGN KEY (priority) REFERENCES todoPriority(id)
);

INSERT IGNORE INTO todo (id, space, title, description, due, priority, link)
    VALUES (2026, 1, "weave.space", "Need to finish building this site.", CURRENT_TIMESTAMP, 3, "weave.space");

CREATE TABLE IF NOT EXISTS follows (
    follower INT NOT NULL,
    following INT NOT NULL,
    notifyUser BOOLEAN DEFAULT FALSE,
    followed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (follower, following),
    FOREIGN KEY (follower) REFERENCES user(id) ON DELETE CASCADE,
    FOREIGN KEY (following) REFERENCES user(id) ON DELETE CASCADE
);
