CREATE TABLE IF NOT EXISTS roles (
  id VARCHAR(36) NOT NULL,
  code VARCHAR(80) NOT NULL,
  name VARCHAR(80) NOT NULL,
  permissions JSON NULL,
  created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (id),
  UNIQUE KEY uk_roles_code (code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS users (
  id VARCHAR(36) NOT NULL,
  name VARCHAR(80) NOT NULL,
  email VARCHAR(160) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  enabled TINYINT NOT NULL DEFAULT 1,
  last_login_at TIMESTAMP NULL,
  created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (id),
  UNIQUE KEY uk_users_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS user_roles (
  user_id VARCHAR(36) NOT NULL,
  role_id VARCHAR(36) NOT NULL,
  PRIMARY KEY (user_id, role_id),
  KEY idx_user_roles_user_id (user_id),
  KEY idx_user_roles_role_id (role_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

SET @users_last_login_at_exists := (
  SELECT COUNT(*)
  FROM information_schema.columns
  WHERE table_schema = DATABASE()
    AND table_name = 'users'
    AND column_name = 'last_login_at'
);
SET @users_last_login_at_sql := IF(
  @users_last_login_at_exists = 0,
  'ALTER TABLE users ADD COLUMN last_login_at TIMESTAMP NULL',
  'SELECT 1'
);
PREPARE users_last_login_at_stmt FROM @users_last_login_at_sql;
EXECUTE users_last_login_at_stmt;
DEALLOCATE PREPARE users_last_login_at_stmt;

CREATE TABLE IF NOT EXISTS login_logs (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id VARCHAR(36) NULL,
  username VARCHAR(64) NOT NULL,
  result VARCHAR(32) NOT NULL,
  failure_reason VARCHAR(255) NULL,
  ip_address VARCHAR(64) NULL,
  user_agent VARCHAR(512) NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  KEY idx_login_logs_user_id (user_id),
  KEY idx_login_logs_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE login_logs MODIFY COLUMN user_id VARCHAR(36) NULL;

CREATE TABLE IF NOT EXISTS audit_logs (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  actor_id VARCHAR(36) NULL,
  actor_username VARCHAR(64) NULL,
  action VARCHAR(64) NOT NULL,
  resource_type VARCHAR(64) NULL,
  resource_id VARCHAR(64) NULL,
  metadata JSON NULL,
  ip_address VARCHAR(64) NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  KEY idx_audit_logs_actor_id (actor_id),
  KEY idx_audit_logs_created_at (created_at),
  KEY idx_audit_logs_action (action)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE audit_logs MODIFY COLUMN actor_id VARCHAR(36) NULL;

INSERT INTO roles (id, code, name, permissions)
SELECT
  '738cbba4-f6f9-444c-ada3-65fa28285aa1',
  'super_admin',
  '超级管理员',
  JSON_ARRAY('*')
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE code = 'super_admin');

INSERT INTO users (id, name, email, password_hash, enabled)
SELECT
  '0f4e6efb-bfb4-4f12-b76c-20e6d0a5aa31',
  'root',
  'root@local.dev',
  '$2b$10$VV/DpPjPNgSDM5fj1B2JxOxFanDrpcwt4qgm27ez8sN4Y8LpfYGna',
  1
WHERE NOT EXISTS (
  SELECT 1
  FROM users
  WHERE name = 'root' OR email = 'root@local.dev'
);

INSERT INTO user_roles (user_id, role_id)
SELECT users.id, roles.id
FROM users
JOIN roles ON roles.code = 'super_admin'
WHERE (users.name = 'root' OR users.email = 'root@local.dev')
  AND NOT EXISTS (
    SELECT 1
    FROM user_roles
    WHERE user_roles.user_id = users.id
      AND user_roles.role_id = roles.id
  );
