-- =====================================================================
-- expense_db 초기화 스크립트 (PostgreSQL)
-- =====================================================================
-- 실행 방법 (운영 PostgreSQL 컨테이너명: postgres-db):
--
--   1) DB / 역할 생성 (superuser 로 1회)
--      docker exec -i postgres-db psql -U postgres -v app_password='<강한비밀번호>' \
--          < scripts/sql/expense_db_init.sql
--
--   2) main-app .env 에 연결 정보 등록
--      EXPENSE_DB_URL=postgresql://expense_app:<강한비밀번호>@postgres-db:5432/expense_db
--
-- 주의:
--   - 기존 DB 가 있으면 DROP 하지 않는다. CREATE DATABASE 만 IF NOT EXISTS 대체.
--   - 비밀번호는 절대 Git 에 커밋하지 않는다. psql -v 또는 \set 으로만 전달.
--   - DROP/TRUNCATE 가 필요한 경우 본 스크립트를 수정하지 말고 별도 작업으로 진행.
-- =====================================================================

\set ON_ERROR_STOP on

-- DB 가 없을 때만 생성
SELECT 'CREATE DATABASE expense_db ENCODING ''UTF8'' TEMPLATE template0'
WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = 'expense_db')
\gexec

-- 앱 전용 로그인 역할
DO $$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'expense_app') THEN
    EXECUTE format('CREATE ROLE expense_app LOGIN PASSWORD %L', :'app_password');
  ELSE
    EXECUTE format('ALTER ROLE expense_app WITH LOGIN PASSWORD %L', :'app_password');
  END IF;
END$$;

GRANT CONNECT ON DATABASE expense_db TO expense_app;

-- 이제 expense_db 컨텍스트로 전환
\connect expense_db

CREATE TABLE IF NOT EXISTS expense_items (
    id           TEXT        PRIMARY KEY,
    owner        TEXT        NOT NULL,
    spent_at     DATE        NOT NULL,
    category     TEXT        NOT NULL,
    method       TEXT        NOT NULL,
    merchant     TEXT        NOT NULL DEFAULT '',
    amount       BIGINT      NOT NULL DEFAULT 0 CHECK (amount >= 0),
    memo         TEXT        NOT NULL DEFAULT '',
    status       TEXT        NOT NULL DEFAULT '작성중',
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_expense_owner_spent  ON expense_items (owner, spent_at DESC);
CREATE INDEX IF NOT EXISTS idx_expense_status       ON expense_items (status);
CREATE INDEX IF NOT EXISTS idx_expense_created_at   ON expense_items (created_at DESC);

-- updated_at 자동 갱신 트리거
CREATE OR REPLACE FUNCTION expense_set_updated_at() RETURNS trigger AS $$
BEGIN
  NEW.updated_at := now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_expense_set_updated_at ON expense_items;
CREATE TRIGGER trg_expense_set_updated_at
  BEFORE UPDATE ON expense_items
  FOR EACH ROW EXECUTE FUNCTION expense_set_updated_at();

-- 권한
GRANT USAGE ON SCHEMA public TO expense_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON expense_items TO expense_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO expense_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO expense_app;

-- 확인용 출력
SELECT 'expense_db ready' AS status;
