-- 007_fix_canonical_order.sql
-- 정사 경로 순서 계산 로직 수정

-- 기존 트리거 삭제
DROP TRIGGER IF EXISTS trigger_update_canonical_order ON memo_nodes;
DROP FUNCTION IF EXISTS update_canonical_order();

-- 정사 경로 순서를 올바르게 계산하는 함수
CREATE OR REPLACE FUNCTION update_canonical_order()
RETURNS TRIGGER AS $$
BEGIN
    -- 정사로 설정될 때
    IF NEW.is_canonical = TRUE AND (OLD.is_canonical IS NULL OR OLD.is_canonical = FALSE) THEN
        -- 같은 부모를 가진 다른 형제 노드들의 정사 상태 해제 (분기점에서 하나만 선택)
        IF NEW.parent_id IS NOT NULL THEN
            UPDATE memo_nodes 
            SET is_canonical = FALSE, canonical_order = NULL, story_path = NULL
            WHERE tree_id = NEW.tree_id 
            AND parent_id = NEW.parent_id 
            AND id != NEW.id 
            AND is_canonical = TRUE;
        END IF;
        
        -- 정사 경로 업데이트
        NEW.story_path = COALESCE(NEW.path, '');
        
        -- 순서는 별도 함수에서 일괄 계산
        PERFORM recalculate_canonical_orders(NEW.tree_id);
    END IF;
    
    -- 정사에서 제외될 때
    IF NEW.is_canonical = FALSE AND OLD.is_canonical = TRUE THEN
        NEW.canonical_order = NULL;
        NEW.story_path = NULL;
        
        -- 순서 재계산
        PERFORM recalculate_canonical_orders(NEW.tree_id);
    END IF;
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 트리별 정사 경로 순서를 DFS로 재계산하는 함수
CREATE OR REPLACE FUNCTION recalculate_canonical_orders(tree_uuid UUID)
RETURNS VOID AS $$
DECLARE
    current_order INTEGER := 1;
BEGIN
    -- 모든 정사 노드의 순서를 NULL로 초기화
    UPDATE memo_nodes 
    SET canonical_order = NULL 
    WHERE tree_id = tree_uuid AND is_canonical = TRUE;
    
    -- DFS로 순서 할당 (재귀 CTE 사용)
    WITH RECURSIVE canonical_path AS (
        -- 루트 노드들 (정사인 것만)
        SELECT id, parent_id, title, 1 as order_num, ARRAY[id] as path
        FROM memo_nodes 
        WHERE tree_id = tree_uuid 
        AND parent_id IS NULL 
        AND is_canonical = TRUE
        
        UNION ALL
        
        -- 자식 노드들 (정사인 것만)
        SELECT n.id, n.parent_id, n.title, 
               cp.order_num + 1 as order_num,
               cp.path || n.id
        FROM memo_nodes n
        INNER JOIN canonical_path cp ON n.parent_id = cp.id
        WHERE n.tree_id = tree_uuid 
        AND n.is_canonical = TRUE
    )
    UPDATE memo_nodes 
    SET canonical_order = cp.order_num
    FROM canonical_path cp
    WHERE memo_nodes.id = cp.id;
END;
$$ LANGUAGE plpgsql;

-- 트리거 다시 생성
CREATE TRIGGER trigger_update_canonical_order
    AFTER UPDATE ON memo_nodes
    FOR EACH ROW
    EXECUTE FUNCTION update_canonical_order();

-- 기존 데이터의 순서 재계산
DO $$
DECLARE
    tree_rec RECORD;
BEGIN
    FOR tree_rec IN SELECT DISTINCT tree_id FROM memo_nodes WHERE is_canonical = TRUE
    LOOP
        PERFORM recalculate_canonical_orders(tree_rec.tree_id);
    END LOOP;
END $$;
