-- Updated User Appeal System Migration
-- Changes: More nuanced violation handling - content deletion + account marking instead of immediate bans

-- Update user_violations table to include content deletion tracking
ALTER TABLE user_violations ADD COLUMN IF NOT EXISTS content_deleted BOOLEAN DEFAULT false;
ALTER TABLE user_violations ADD COLUMN IF NOT EXISTS content_deletion_reason TEXT;
ALTER TABLE user_violations ADD COLUMN IF NOT EXISTS account_status_change VARCHAR(20) DEFAULT 'none';

-- Update user_violation_history table
ALTER TABLE user_violation_history ADD COLUMN IF NOT EXISTS content_deletions INTEGER DEFAULT 0;
ALTER TABLE user_violation_history ADD COLUMN IF NOT EXISTS account_warnings INTEGER DEFAULT 0;
ALTER TABLE user_violation_history ADD COLUMN IF NOT EXISTS account_suspensions INTEGER DEFAULT 0;

-- Update appeal guidelines to reflect new approach
UPDATE appeal_guidelines SET 
    auto_ban_threshold = 999, -- Disable auto-ban
    hard_violation_ban_threshold = 999, -- Disable auto-ban
    is_active = true
WHERE violation_type IN ('hard_violation', 'soft_violation');

-- Add new status options for user accounts
ALTER TABLE users ADD CONSTRAINT IF NOT EXISTS users_status_check 
    CHECK (status IN ('active', 'warning', 'suspended', 'banned', 'under_review'));

-- Update the ban checking function to use content deletion instead
CREATE OR REPLACE FUNCTION check_user_violation_status(p_user_id UUID) RETURNS TEXT AS $$
DECLARE
    v_hard_count INTEGER;
    v_total_count INTEGER;
    v_soft_count INTEGER;
    v_content_deletions INTEGER;
    v_new_status TEXT := 'active';
BEGIN
    -- Get counts from last 30 days
    SELECT 
        COUNT(CASE WHEN violation_type = 'hard_violation' THEN 1 END),
        COUNT(*),
        COUNT(CASE WHEN violation_type = 'soft_violation' THEN 1 END),
        COUNT(CASE WHEN content_deleted = true THEN 1 END)
    INTO v_hard_count, v_total_count, v_soft_count, v_content_deletions
    FROM user_violations 
    WHERE user_id = p_user_id 
    AND created_at >= NOW() - INTERVAL '30 days';
    
    -- Determine account status based on violation patterns
    IF v_hard_count >= 3 THEN
        v_new_status := 'banned';
    ELSIF v_total_count >= 8 THEN
        v_new_status := 'banned';
    ELSIF v_hard_count >= 2 THEN
        v_new_status := 'suspended';
    ELSIF v_total_count >= 5 THEN
        v_new_status := 'suspended';
    ELSIF v_hard_count >= 1 OR v_total_count >= 3 THEN
        v_new_status := 'warning';
    END IF;
    
    -- Update user status if it needs to change
    IF v_new_status != 'active' THEN
        UPDATE users 
        SET status = v_new_status, updated_at = NOW()
        WHERE id = p_user_id AND status != v_new_status;
        
        -- Update violation history
        UPDATE user_violation_history 
        SET 
            current_status = v_new_status,
            content_deletions = v_content_deletions,
            account_warnings = CASE WHEN v_new_status = 'warning' THEN account_warnings + 1 ELSE account_warnings END,
            account_suspensions = CASE WHEN v_new_status = 'suspended' THEN account_suspensions + 1 ELSE account_suspensions END,
            updated_at = NOW()
        WHERE user_id = p_user_id AND violation_date = CURRENT_DATE;
    END IF;
    
    RETURN v_new_status;
END;
$$ LANGUAGE plpgsql;

-- Create function to handle content deletion for violations
CREATE OR REPLACE FUNCTION handle_violation_content_deletion(
    p_user_id UUID,
    p_moderation_flag_id UUID,
    p_violation_type TEXT
) RETURNS BOOLEAN AS $$
DECLARE
    v_post_id UUID;
    v_comment_id UUID;
    v_content_deleted BOOLEAN := false;
BEGIN
    -- Get the content ID from the moderation flag
    SELECT post_id, comment_id 
    INTO v_post_id, v_comment_id
    FROM moderation_flags 
    WHERE id = p_moderation_flag_id;
    
    -- Delete or hide the content based on violation type
    IF p_violation_type = 'hard_violation' THEN
        -- Hard violations: delete content immediately
        IF v_post_id IS NOT NULL THEN
            UPDATE posts SET status = 'deleted', updated_at = NOW() WHERE id = v_post_id;
            v_content_deleted := true;
        END IF;
        
        IF v_comment_id IS NOT NULL THEN
            UPDATE comments SET status = 'deleted', updated_at = NOW() WHERE id = v_comment_id;
            v_content_deleted := true;
        END IF;
        
        -- Mark the violation record
        UPDATE user_violations 
        SET content_deleted = true, 
            content_deletion_reason = 'Hard violation - immediate deletion',
            account_status_change = CASE 
                WHEN (SELECT COUNT(*) FROM user_violations WHERE user_id = p_user_id AND violation_type = 'hard_violation') >= 2 THEN 'suspended'
                WHEN (SELECT COUNT(*) FROM user_violations WHERE user_id = p_user_id AND violation_type = 'hard_violation') >= 1 THEN 'warning'
                ELSE 'none'
            END,
            updated_at = NOW()
        WHERE moderation_flag_id = p_moderation_flag_id;
        
    ELSIF p_violation_type = 'soft_violation' THEN
        -- Soft violations: hide content pending appeal
        IF v_post_id IS NOT NULL THEN
            UPDATE posts SET status = 'pending_moderation', updated_at = NOW() WHERE id = v_post_id;
        END IF;
        
        IF v_comment_id IS NOT NULL THEN
            UPDATE comments SET status = 'pending_moderation', updated_at = NOW() WHERE id = v_comment_id;
        END IF;
        
        -- Mark the violation record
        UPDATE user_violations 
        SET content_deleted = false, 
            content_deletion_reason = 'Soft violation - pending moderation',
            account_status_change = 'none',
            updated_at = NOW()
        WHERE moderation_flag_id = p_moderation_flag_id;
    END IF;
    
    -- Check if user status needs updating
    PERFORM check_user_violation_status(p_user_id);
    
    RETURN v_content_deleted;
END;
$$ LANGUAGE plpgsql;

-- Update the create_user_violation function to use the new content handling
CREATE OR REPLACE FUNCTION create_user_violation(
    p_user_id UUID,
    p_moderation_flag_id UUID,
    p_flag_reason TEXT,
    p_scores JSONB
) RETURNS UUID AS $$
DECLARE
    v_violation_id UUID;
    v_violation_type TEXT;
    v_severity DECIMAL;
    v_is_appealable BOOLEAN;
    v_appeal_deadline TIMESTAMP WITH TIME ZONE;
BEGIN
    -- Determine violation type based on scores and reason
    CASE 
        WHEN p_flag_reason IN ('hate') AND (p_scores->>'hate')::DECIMAL > 0.8 THEN
            BEGIN
                v_violation_type := 'hard_violation';
                v_severity := (p_scores->>'hate')::DECIMAL;
                v_is_appealable := false;
                v_appeal_deadline := NULL;
            END;
        WHEN p_flag_reason IN ('hate', 'violence', 'sexual') AND (p_scores->>'hate')::DECIMAL > 0.6 THEN
            BEGIN
                v_violation_type := 'hard_violation';
                v_severity := GREATEST((p_scores->>'hate')::DECIMAL, (p_scores->>'greed')::DECIMAL, (p_scores->>'delusion')::DECIMAL);
                v_is_appealable := false;
                v_appeal_deadline := NULL;
            END;
        ELSE
            BEGIN
                v_violation_type := 'soft_violation';
                v_severity := GREATEST((p_scores->>'hate')::DECIMAL, (p_scores->>'greed')::DECIMAL, (p_scores->>'delusion')::DECIMAL);
                v_is_appealable := true;
                v_appeal_deadline := NOW() + (SELECT appeal_window_hours FROM appeal_guidelines WHERE violation_type = 'soft_violation' AND is_active = true LIMIT 1) * INTERVAL '1 hour';
            END;
    END CASE;
    
    -- Create the violation record
    INSERT INTO user_violations (user_id, moderation_flag_id, violation_type, violation_reason, severity_score, is_appealable, appeal_deadline)
    VALUES (p_user_id, p_moderation_flag_id, v_violation_type, p_flag_reason, v_severity, v_is_appealable, v_appeal_deadline)
    RETURNING id INTO v_violation_id;
    
    -- Update violation history
    INSERT INTO user_violation_history (user_id, violation_date, total_violations, hard_violations, soft_violations)
    VALUES (p_user_id, CURRENT_DATE, 1, 
            CASE WHEN v_violation_type = 'hard_violation' THEN 1 ELSE 0 END,
            CASE WHEN v_violation_type = 'soft_violation' THEN 1 ELSE 0 END)
    ON CONFLICT (user_id, violation_date) 
    DO UPDATE SET
        total_violations = user_violation_history.total_violations + 1,
        hard_violations = user_violation_history.hard_violations + CASE WHEN v_violation_type = 'hard_violation' THEN 1 ELSE 0 END,
        soft_violations = user_violation_history.soft_violations + CASE WHEN v_violation_type = 'soft_violation' THEN 1 ELSE 0 END,
        updated_at = NOW();
    
    -- Handle content deletion based on violation type
    PERFORM handle_violation_content_deletion(p_user_id, p_moderation_flag_id, v_violation_type);
    
    RETURN v_violation_id;
END;
$$ LANGUAGE plpgsql;
