-- ================================================
-- 마이그레이션: 013_add_inbox_workflow_system.sql
-- 목적: 수신함 워크플로우를 위한 DB 스키마 추가
-- 작성일: 2025-10-25
-- 주의: 배포 시 반드시 이 파일이 실행되는지 확인 필요!
-- ================================================

-- 트랜잭션 시작 (실패 시 롤백)
BEGIN;

-- 1. 새로운 ENUM 타입 생성
-- 검토 상태 (수신함 워크플로우용)
DO $$ 
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'review_status') THEN
        CREATE TYPE review_status AS ENUM (
            'pending_review',    -- 수신함 (검토 대기)
            'in_progress',       -- 관리함 (진행 중)
            'completed',         -- 관리함 (완료됨)
            'disposed'           -- 폐기함 (폐기됨)
        );
        RAISE NOTICE '✅ review_status ENUM 타입이 생성되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ review_status ENUM 타입이 이미 존재합니다.';
    END IF;
END $$;

-- 폐기 사유 타입
DO $$ 
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'disposal_reason_type') THEN
        CREATE TYPE disposal_reason_type AS ENUM (
            'duplicate',         -- 중복 (기본값)
            'invalid_report',    -- 잘못된 신고
            'not_applicable',    -- 해당 없음
            'spam',             -- 스팸/오류
            'custom'            -- 직접 입력
        );
        RAISE NOTICE '✅ disposal_reason_type ENUM 타입이 생성되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ disposal_reason_type ENUM 타입이 이미 존재합니다.';
    END IF;
END $$;

-- 2. issues 테이블에 새로운 컬럼 추가 (안전하게)
-- 검토 상태 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'review_status'
    ) THEN
        ALTER TABLE issues ADD COLUMN review_status review_status DEFAULT 'pending_review';
        RAISE NOTICE '✅ issues.review_status 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.review_status 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 폐기 사유 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'disposal_reason'
    ) THEN
        ALTER TABLE issues ADD COLUMN disposal_reason disposal_reason_type;
        RAISE NOTICE '✅ issues.disposal_reason 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.disposal_reason 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 사용자 정의 폐기 사유 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'custom_disposal_reason'
    ) THEN
        ALTER TABLE issues ADD COLUMN custom_disposal_reason TEXT;
        RAISE NOTICE '✅ issues.custom_disposal_reason 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.custom_disposal_reason 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 폐기 날짜 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'disposed_at'
    ) THEN
        ALTER TABLE issues ADD COLUMN disposed_at TIMESTAMP WITH TIME ZONE;
        RAISE NOTICE '✅ issues.disposed_at 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.disposed_at 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 검토자 ID 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'reviewed_by_id'
    ) THEN
        ALTER TABLE issues ADD COLUMN reviewed_by_id INTEGER REFERENCES users(id);
        RAISE NOTICE '✅ issues.reviewed_by_id 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.reviewed_by_id 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 검토 날짜 컬럼
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'reviewed_at'
    ) THEN
        ALTER TABLE issues ADD COLUMN reviewed_at TIMESTAMP WITH TIME ZONE;
        RAISE NOTICE '✅ issues.reviewed_at 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.reviewed_at 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 원본 데이터 보존 컬럼 (JSONB)
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'original_data'
    ) THEN
        ALTER TABLE issues ADD COLUMN original_data JSONB;
        RAISE NOTICE '✅ issues.original_data 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.original_data 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 수정 이력 컬럼 (JSONB)
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'issues' AND column_name = 'modification_log'
    ) THEN
        ALTER TABLE issues ADD COLUMN modification_log JSONB DEFAULT '[]'::jsonb;
        RAISE NOTICE '✅ issues.modification_log 컬럼이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ issues.modification_log 컬럼이 이미 존재합니다.';
    END IF;
END $$;

-- 3. 인덱스 추가 (성능 최적화)
-- review_status 인덱스
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE tablename = 'issues' AND indexname = 'idx_issues_review_status'
    ) THEN
        CREATE INDEX idx_issues_review_status ON issues(review_status);
        RAISE NOTICE '✅ idx_issues_review_status 인덱스가 생성되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ idx_issues_review_status 인덱스가 이미 존재합니다.';
    END IF;
END $$;

-- reviewed_by_id 인덱스
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE tablename = 'issues' AND indexname = 'idx_issues_reviewed_by_id'
    ) THEN
        CREATE INDEX idx_issues_reviewed_by_id ON issues(reviewed_by_id);
        RAISE NOTICE '✅ idx_issues_reviewed_by_id 인덱스가 생성되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ idx_issues_reviewed_by_id 인덱스가 이미 존재합니다.';
    END IF;
END $$;

-- disposed_at 인덱스
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE tablename = 'issues' AND indexname = 'idx_issues_disposed_at'
    ) THEN
        CREATE INDEX idx_issues_disposed_at ON issues(disposed_at) WHERE disposed_at IS NOT NULL;
        RAISE NOTICE '✅ idx_issues_disposed_at 인덱스가 생성되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ idx_issues_disposed_at 인덱스가 이미 존재합니다.';
    END IF;
END $$;

-- 4. 기존 데이터 마이그레이션 (안전하게)
-- 기존 issues의 review_status를 기존 status에 따라 설정
UPDATE issues 
SET review_status = CASE 
    WHEN status = 'new' THEN 'pending_review'::review_status
    WHEN status = 'progress' THEN 'in_progress'::review_status
    WHEN status = 'complete' THEN 'completed'::review_status
    ELSE 'pending_review'::review_status
END
WHERE review_status = 'pending_review'; -- 기본값인 경우만 업데이트

-- 5. 제약 조건 추가
-- 폐기된 경우 폐기 사유 필수
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.check_constraints 
        WHERE constraint_name = 'chk_disposal_reason_required'
    ) THEN
        ALTER TABLE issues ADD CONSTRAINT chk_disposal_reason_required 
        CHECK (
            (review_status = 'disposed' AND disposal_reason IS NOT NULL) OR 
            (review_status != 'disposed')
        );
        RAISE NOTICE '✅ chk_disposal_reason_required 제약 조건이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ chk_disposal_reason_required 제약 조건이 이미 존재합니다.';
    END IF;
END $$;

-- 사용자 정의 사유는 disposal_reason이 'custom'일 때만
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.check_constraints 
        WHERE constraint_name = 'chk_custom_reason_logic'
    ) THEN
        ALTER TABLE issues ADD CONSTRAINT chk_custom_reason_logic 
        CHECK (
            (disposal_reason = 'custom' AND custom_disposal_reason IS NOT NULL AND LENGTH(TRIM(custom_disposal_reason)) > 0) OR 
            (disposal_reason != 'custom' OR disposal_reason IS NULL)
        );
        RAISE NOTICE '✅ chk_custom_reason_logic 제약 조건이 추가되었습니다.';
    ELSE
        RAISE NOTICE '⚠️ chk_custom_reason_logic 제약 조건이 이미 존재합니다.';
    END IF;
END $$;

-- 6. 마이그레이션 완료 로그
INSERT INTO migration_log (migration_file, executed_at, status, notes) 
VALUES (
    '013_add_inbox_workflow_system.sql', 
    NOW(), 
    'SUCCESS',
    '수신함 워크플로우 시스템 추가: review_status, disposal_reason, 원본데이터 보존, 수정이력 등'
) ON CONFLICT (migration_file) DO UPDATE SET
    executed_at = NOW(),
    status = 'SUCCESS',
    notes = EXCLUDED.notes;

-- 트랜잭션 커밋
COMMIT;

-- 7. 마이그레이션 검증
DO $$ 
DECLARE
    column_count INTEGER;
    enum_count INTEGER;
    index_count INTEGER;
BEGIN
    -- 컬럼 개수 확인
    SELECT COUNT(*) INTO column_count
    FROM information_schema.columns 
    WHERE table_name = 'issues' 
    AND column_name IN (
        'review_status', 'disposal_reason', 'custom_disposal_reason', 
        'disposed_at', 'reviewed_by_id', 'reviewed_at', 
        'original_data', 'modification_log'
    );
    
    -- ENUM 타입 확인
    SELECT COUNT(*) INTO enum_count
    FROM pg_type 
    WHERE typname IN ('review_status', 'disposal_reason_type');
    
    -- 인덱스 확인
    SELECT COUNT(*) INTO index_count
    FROM pg_indexes 
    WHERE tablename = 'issues' 
    AND indexname IN (
        'idx_issues_review_status', 
        'idx_issues_reviewed_by_id', 
        'idx_issues_disposed_at'
    );
    
    RAISE NOTICE '=== 마이그레이션 검증 결과 ===';
    RAISE NOTICE '추가된 컬럼: %/8개', column_count;
    RAISE NOTICE '생성된 ENUM: %/2개', enum_count;
    RAISE NOTICE '생성된 인덱스: %/3개', index_count;
    
    IF column_count = 8 AND enum_count = 2 AND index_count = 3 THEN
        RAISE NOTICE '✅ 마이그레이션이 성공적으로 완료되었습니다!';
    ELSE
        RAISE EXCEPTION '❌ 마이그레이션 검증 실패! 일부 구조가 누락되었습니다.';
    END IF;
END $$;

-- 8. 최종 테이블 구조 출력
\echo '=== 최종 issues 테이블 구조 ==='
\d issues;

\echo '=== 새로운 ENUM 타입들 ==='
\dT+ review_status;
\dT+ disposal_reason_type;

\echo '=== 마이그레이션 013 완료 ==='
