-- W4 유저 배지/평판. 멱등. db/apply-local-ddl.sh 로 실행 DB 비파괴 적용.
-- 신규 도메인(스토리지 0). 추가만, 파괴 없음. search_path=dev.

-- 1) badges (배지 카탈로그 — 정의 가능·확장 가능)
CREATE SEQUENCE IF NOT EXISTS "badges_id_seq";
CREATE TABLE IF NOT EXISTS "badges" (
    "id"            bigint DEFAULT nextval('badges_id_seq'::regclass) NOT NULL,
    "badge_key"     character varying(50)  NOT NULL,
    "display_name"  character varying(100) NOT NULL,
    "description"   character varying(500),
    "badge_type"    character varying(30)  NOT NULL,
    "criteria_json" text,
    "is_active"     boolean DEFAULT true NOT NULL,
    "created_at"    timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "badges_id_seq" OWNED BY "badges"."id";
CREATE UNIQUE INDEX IF NOT EXISTS "ux_badges_key" ON "badges" ("badge_key");
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'badges_type_check') THEN
        ALTER TABLE "badges"
            ADD CONSTRAINT "badges_type_check"
            CHECK ("badge_type" IN ('REVIEWER', 'TECHNICIAN'));
    END IF;
END
$$;

-- 2) user_badges (유저↔배지 보유. 자동/수동 부여 공통 기록)
CREATE SEQUENCE IF NOT EXISTS "user_badges_id_seq";
CREATE TABLE IF NOT EXISTS "user_badges" (
    "id"            bigint DEFAULT nextval('user_badges_id_seq'::regclass) NOT NULL,
    "user_id"       bigint NOT NULL,
    "badge_key"     character varying(50) NOT NULL,
    "awarded_by"    bigint,
    "awarded_at"    timestamp with time zone DEFAULT now() NOT NULL,
    "revoked_at"    timestamp with time zone,
    "revoke_reason" character varying(500),
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "user_badges_id_seq" OWNED BY "user_badges"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'user_badges_user_id_fkey') THEN
        ALTER TABLE "user_badges"
            ADD CONSTRAINT "user_badges_user_id_fkey"
            FOREIGN KEY ("user_id") REFERENCES "users" ("id");
    END IF;
END
$$;
CREATE UNIQUE INDEX IF NOT EXISTS "ux_user_badges_active"
    ON "user_badges" ("user_id", "badge_key") WHERE "revoked_at" IS NULL;
CREATE INDEX IF NOT EXISTS "idx_user_badges_user_active"
    ON "user_badges" ("user_id") WHERE "revoked_at" IS NULL;

-- 3) reputation_events (평판 신호 감사로그 — append-only, 임계 판정 단일 소스)
CREATE SEQUENCE IF NOT EXISTS "reputation_events_id_seq";
CREATE TABLE IF NOT EXISTS "reputation_events" (
    "id"          bigint DEFAULT nextval('reputation_events_id_seq'::regclass) NOT NULL,
    "user_id"     bigint NOT NULL,
    "event_type"  character varying(40) NOT NULL,
    "source_ref"  character varying(100),
    "weight"      integer DEFAULT 1 NOT NULL,
    "created_at"  timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "reputation_events_id_seq" OWNED BY "reputation_events"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'reputation_events_type_check') THEN
        ALTER TABLE "reputation_events"
            ADD CONSTRAINT "reputation_events_type_check"
            CHECK ("event_type" IN ('REVIEW_WRITTEN', 'GAME_UPLOADED'));
    END IF;
END
$$;
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'reputation_events_user_id_fkey') THEN
        ALTER TABLE "reputation_events"
            ADD CONSTRAINT "reputation_events_user_id_fkey"
            FOREIGN KEY ("user_id") REFERENCES "users" ("id");
    END IF;
END
$$;
CREATE UNIQUE INDEX IF NOT EXISTS "ux_reputation_events_source"
    ON "reputation_events" ("user_id", "event_type", "source_ref")
    WHERE "source_ref" IS NOT NULL;
CREATE INDEX IF NOT EXISTS "idx_reputation_events_user_type"
    ON "reputation_events" ("user_id", "event_type");
