-- member_center: API 呼叫方白名單表
-- 位置: public schema

BEGIN;

CREATE EXTENSION IF NOT EXISTS pgcrypto;

DO $$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'client_status') THEN
    CREATE TYPE client_status AS ENUM ('active', 'inactive');
  END IF;
END $$;

CREATE TABLE IF NOT EXISTS api_clients (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  client_key TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  status client_status NOT NULL DEFAULT 'active',

  -- 只存 hash，不存明文 key
  api_key_hash TEXT NOT NULL,

  -- 可先留空，之後再嚴格化
  allowed_origins JSONB NOT NULL DEFAULT '[]'::jsonb,
  allowed_ips JSONB NOT NULL DEFAULT '[]'::jsonb,
  allowed_paths JSONB NOT NULL DEFAULT '[]'::jsonb,

  rate_limit_per_min INTEGER,
  expires_at TIMESTAMPTZ,
  last_used_at TIMESTAMPTZ,

  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_api_clients_status ON api_clients(status);
CREATE INDEX IF NOT EXISTS idx_api_clients_expires_at ON api_clients(expires_at);

CREATE OR REPLACE FUNCTION set_updated_at_api_clients()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'trg_api_clients_set_updated_at'
  ) THEN
    CREATE TRIGGER trg_api_clients_set_updated_at
    BEFORE UPDATE ON api_clients
    FOR EACH ROW EXECUTE FUNCTION set_updated_at_api_clients();
  END IF;
END $$;

-- 建議初始化 2~3 個 client（api_key_hash 先放占位，後續再更新）
INSERT INTO api_clients (
  client_key,
  name,
  status,
  api_key_hash,
  allowed_origins,
  allowed_ips,
  allowed_paths,
  rate_limit_per_min
)
VALUES
  (
    'mkt-backend',
    'MKT Backend Service',
    'active',
    'REPLACE_WITH_BCRYPT_OR_ARGON2_HASH',
    '[]'::jsonb,
    '[]'::jsonb,
    '["/internal/users/upsert-by-sub", "/internal/permissions"]'::jsonb,
    600
  ),
  (
    'admin-frontend',
    'Admin Frontend',
    'active',
    'REPLACE_WITH_BCRYPT_OR_ARGON2_HASH',
    '["https://admin.ose.tw", "https://member.ose.tw"]'::jsonb,
    '[]'::jsonb,
    '["/admin"]'::jsonb,
    300
  ),
  (
    'ops-local',
    'Ops Local Tooling',
    'inactive',
    'REPLACE_WITH_BCRYPT_OR_ARGON2_HASH',
    '[]'::jsonb,
    '["127.0.0.1"]'::jsonb,
    '["/internal", "/admin"]'::jsonb,
    120
  )
ON CONFLICT (client_key) DO NOTHING;

COMMIT;

-- 快速檢查
-- SELECT client_key, status, expires_at, created_at FROM api_clients ORDER BY client_key;
