-- Ported from backend/src/main/resources/db/migration/V1__init.sql

CREATE TABLE users (
    id                   BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at           TIMESTAMP    NOT NULL,
    updated_at           TIMESTAMP    NOT NULL,
    username             VARCHAR(50)  NOT NULL UNIQUE,
    password_hash        VARCHAR(255) NOT NULL,
    full_name            VARCHAR(80)  NOT NULL,
    email                VARCHAR(120),
    department           VARCHAR(80),
    must_change_password BOOLEAN      NOT NULL,
    enabled              BOOLEAN      NOT NULL,
    locked               BOOLEAN      NOT NULL
);

CREATE TABLE user_roles (
    user_id BIGINT      NOT NULL REFERENCES users (id),
    role    VARCHAR(20) NOT NULL
);
CREATE INDEX idx_user_roles_user ON user_roles (user_id);

CREATE TABLE zones (
    id             BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at     TIMESTAMP    NOT NULL,
    updated_at     TIMESTAMP    NOT NULL,
    code           VARCHAR(30)  NOT NULL UNIQUE,
    name           VARCHAR(80)  NOT NULL,
    description    VARCHAR(255),
    security_level INTEGER      NOT NULL,
    active         BOOLEAN      NOT NULL
);

CREATE TABLE visitors (
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at TIMESTAMP    NOT NULL,
    updated_at TIMESTAMP    NOT NULL,
    name       VARCHAR(80)  NOT NULL,
    company    VARCHAR(120),
    contact    VARCHAR(40),
    email      VARCHAR(120),
    vehicle_no VARCHAR(20)
);
CREATE INDEX idx_visitor_name ON visitors (name);
CREATE INDEX idx_visitor_contact ON visitors (contact);

CREATE TABLE visit_requests (
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at TIMESTAMP    NOT NULL,
    updated_at TIMESTAMP    NOT NULL,
    visitor_id BIGINT       NOT NULL REFERENCES visitors (id),
    host_id    BIGINT       NOT NULL REFERENCES users (id),
    zone_name  VARCHAR(80),
    purpose    VARCHAR(255) NOT NULL,
    visit_from TIMESTAMP    NOT NULL,
    visit_to   TIMESTAMP    NOT NULL,
    status     VARCHAR(20)  NOT NULL,
    qr_token   VARCHAR(64)
);
CREATE INDEX idx_vr_status ON visit_requests (status);
CREATE INDEX idx_vr_visit_from ON visit_requests (visit_from);
CREATE INDEX idx_vr_qr_token ON visit_requests (qr_token);

CREATE TABLE approvals (
    id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at       TIMESTAMP    NOT NULL,
    updated_at       TIMESTAMP    NOT NULL,
    visit_request_id BIGINT       NOT NULL REFERENCES visit_requests (id),
    approver_id      BIGINT       NOT NULL REFERENCES users (id),
    decision         VARCHAR(20)  NOT NULL,
    comment          VARCHAR(500),
    decided_at       TIMESTAMP    NOT NULL
);

CREATE TABLE access_events (
    id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at       TIMESTAMP   NOT NULL,
    updated_at       TIMESTAMP   NOT NULL,
    visit_request_id BIGINT      NOT NULL REFERENCES visit_requests (id),
    direction        VARCHAR(8)  NOT NULL,
    gate_id          VARCHAR(40),
    operator_id      BIGINT      REFERENCES users (id),
    event_at         TIMESTAMP   NOT NULL
);
CREATE INDEX idx_ae_visit_request ON access_events (visit_request_id);
CREATE INDEX idx_ae_event_at ON access_events (event_at);
CREATE INDEX idx_ae_direction ON access_events (direction);

CREATE TABLE blacklist (
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    created_at TIMESTAMP    NOT NULL,
    updated_at TIMESTAMP    NOT NULL,
    name       VARCHAR(80)  NOT NULL,
    company    VARCHAR(120),
    contact    VARCHAR(40),
    reason     VARCHAR(255) NOT NULL,
    active     BOOLEAN      NOT NULL,
    created_by BIGINT       REFERENCES users (id)
);
CREATE INDEX idx_bl_name ON blacklist (name);
CREATE INDEX idx_bl_contact ON blacklist (contact);

INSERT INTO zones (created_at, updated_at, code, name, description, security_level, active) VALUES
    (now(), now(), 'LOBBY',       '로비',     NULL, 1, TRUE),
    (now(), now(), 'OFFICE',      '사무공간', NULL, 2, TRUE),
    (now(), now(), 'SERVER_ROOM', '전산실',   NULL, 3, TRUE);
