-- +goose Up
-- +goose StatementBegin

-- =========================================
-- ТРИГГЕР: Автообновление updated_at
-- =========================================
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Применяем триггер к таблицам с updated_at
CREATE TRIGGER update_users_updated_at
    BEFORE UPDATE ON users
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_requests_updated_at
    BEFORE UPDATE ON requests
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_volunteer_responses_updated_at
    BEFORE UPDATE ON volunteer_responses
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_ratings_updated_at
    BEFORE UPDATE ON ratings
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_complaints_updated_at
    BEFORE UPDATE ON complaints
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

COMMENT ON FUNCTION update_updated_at_column IS 'Автоматическое обновление поля updated_at при изменении записи';

-- =========================================
-- ТРИГГЕР: Обновление рейтинга волонтёра
-- =========================================
CREATE OR REPLACE FUNCTION update_volunteer_rating()
RETURNS TRIGGER AS $$
BEGIN
    -- Обновляем средний рейтинг и количество выполненных заявок
    UPDATE users
    SET
        volunteer_rating = (
            SELECT COALESCE(ROUND(AVG(rating)::numeric, 2), 0)
            FROM ratings
            WHERE volunteer_id = NEW.volunteer_id
        ),
        completed_requests_count = (
            SELECT COUNT(*)
            FROM ratings
            WHERE volunteer_id = NEW.volunteer_id
        )
    WHERE id = NEW.volunteer_id;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Триггеры для INSERT и UPDATE рейтингов
CREATE TRIGGER update_volunteer_rating_on_insert
    AFTER INSERT ON ratings
    FOR EACH ROW
    EXECUTE FUNCTION update_volunteer_rating();

CREATE TRIGGER update_volunteer_rating_on_update
    AFTER UPDATE ON ratings
    FOR EACH ROW
    WHEN (OLD.rating IS DISTINCT FROM NEW.rating OR OLD.volunteer_id IS DISTINCT FROM NEW.volunteer_id)
    EXECUTE FUNCTION update_volunteer_rating();

COMMENT ON FUNCTION update_volunteer_rating IS 'Автоматический пересчёт рейтинга волонтёра при добавлении/изменении оценки';

-- =========================================
-- ТРИГГЕР: Синхронизация статуса блокировки пользователя
-- =========================================
CREATE OR REPLACE FUNCTION sync_user_block_status()
RETURNS TRIGGER AS $$
BEGIN
    -- При INSERT или UPDATE активной блокировки
    IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') AND NEW.is_active = TRUE THEN
        UPDATE users SET is_blocked = TRUE WHERE id = NEW.user_id;

    -- При DELETE или деактивации блокировки
    ELSIF TG_OP = 'DELETE' OR (TG_OP = 'UPDATE' AND NEW.is_active = FALSE) THEN
        -- Проверяем, есть ли другие активные блокировки
        UPDATE users
        SET is_blocked = EXISTS(
            SELECT 1
            FROM user_blocks
            WHERE user_id = COALESCE(NEW.user_id, OLD.user_id)
            AND is_active = TRUE
            AND id != COALESCE(NEW.id, OLD.id)
        )
        WHERE id = COALESCE(NEW.user_id, OLD.user_id);
    END IF;

    RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER sync_user_block_status_trigger
    AFTER INSERT OR UPDATE OR DELETE ON user_blocks
    FOR EACH ROW
    EXECUTE FUNCTION sync_user_block_status();

COMMENT ON FUNCTION sync_user_block_status IS 'Синхронизация флага is_blocked в users при изменении блокировок';

-- =========================================
-- ТРИГГЕР: Автоматическое создание записи в истории статусов
-- =========================================
CREATE OR REPLACE FUNCTION log_request_status_change()
RETURNS TRIGGER AS $$
BEGIN
    -- При создании заявки
    IF TG_OP = 'INSERT' THEN
        INSERT INTO request_status_history (request_id, from_status, to_status, changed_by)
        VALUES (NEW.id, NULL, NEW.status, NEW.requester_id);

    -- При изменении статуса
    ELSIF TG_OP = 'UPDATE' AND OLD.status IS DISTINCT FROM NEW.status THEN
        INSERT INTO request_status_history (request_id, from_status, to_status, changed_by)
        VALUES (
            NEW.id,
            OLD.status,
            NEW.status,
            COALESCE(NEW.moderated_by, NEW.assigned_volunteer_id, NEW.requester_id)
        );
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER log_request_status_change_trigger
    AFTER INSERT OR UPDATE ON requests
    FOR EACH ROW
    EXECUTE FUNCTION log_request_status_change();

COMMENT ON FUNCTION log_request_status_change IS 'Автоматическое логирование всех изменений статусов заявок';

-- =========================================
-- ТРИГГЕР: Проверка истечения временной блокировки
-- =========================================
CREATE OR REPLACE FUNCTION check_block_expiration()
RETURNS TRIGGER AS $$
BEGIN
    -- Если блокировка временная и истекла, деактивируем её
    IF NEW.blocked_until IS NOT NULL AND NEW.blocked_until < CURRENT_TIMESTAMP THEN
        NEW.is_active = FALSE;
        NEW.unblocked_at = CURRENT_TIMESTAMP;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER check_block_expiration_trigger
    BEFORE INSERT OR UPDATE ON user_blocks
    FOR EACH ROW
    WHEN (NEW.blocked_until IS NOT NULL)
    EXECUTE FUNCTION check_block_expiration();

COMMENT ON FUNCTION check_block_expiration IS 'Автоматическая деактивация истёкших временных блокировок';

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin

-- Удаляем триггеры
DROP TRIGGER IF EXISTS check_block_expiration_trigger ON user_blocks;
DROP TRIGGER IF EXISTS log_request_status_change_trigger ON requests;
DROP TRIGGER IF EXISTS sync_user_block_status_trigger ON user_blocks;
DROP TRIGGER IF EXISTS update_volunteer_rating_on_update ON ratings;
DROP TRIGGER IF EXISTS update_volunteer_rating_on_insert ON ratings;
DROP TRIGGER IF EXISTS update_complaints_updated_at ON complaints;
DROP TRIGGER IF EXISTS update_ratings_updated_at ON ratings;
DROP TRIGGER IF EXISTS update_volunteer_responses_updated_at ON volunteer_responses;
DROP TRIGGER IF EXISTS update_requests_updated_at ON requests;
DROP TRIGGER IF EXISTS update_users_updated_at ON users;

-- Удаляем функции
DROP FUNCTION IF EXISTS check_block_expiration;
DROP FUNCTION IF EXISTS log_request_status_change;
DROP FUNCTION IF EXISTS sync_user_block_status;
DROP FUNCTION IF EXISTS update_volunteer_rating;
DROP FUNCTION IF EXISTS update_updated_at_column;

-- +goose StatementEnd
