-- ============================================================
-- Norda Biznes Partner - Improved Search Schema Migration
-- ============================================================
--
-- Rozszerzenie wyszukiwania o:
-- 1. pg_trgm dla fuzzy matching (literówki)
-- 2. Rozszerzony search_vector o usługi i kompetencje
-- 3. Indeks trigram dla podobieństwa nazw
--
-- Data: 2025-11-26
-- ============================================================

-- 1. Włącz rozszerzenie pg_trgm (fuzzy matching)
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- 2. Dodaj indeks trigram na nazwę firmy (dla fuzzy matching)
CREATE INDEX IF NOT EXISTS idx_companies_name_trgm
ON companies USING gin(name gin_trgm_ops);

-- 3. Dodaj indeks trigram na opis krótki
CREATE INDEX IF NOT EXISTS idx_companies_desc_trgm
ON companies USING gin(description_short gin_trgm_ops);

-- 4. Rozszerzona funkcja search trigger (uwzględnia usługi i kompetencje)
CREATE OR REPLACE FUNCTION companies_search_trigger_full() RETURNS trigger AS $$
DECLARE
    services_text TEXT;
    competencies_text TEXT;
BEGIN
    -- Pobierz nazwy usług przypisanych do firmy
    SELECT string_agg(s.name, ' ') INTO services_text
    FROM company_services cs
    JOIN services s ON s.id = cs.service_id
    WHERE cs.company_id = NEW.id;

    -- Pobierz nazwy kompetencji przypisanych do firmy
    SELECT string_agg(c.name, ' ') INTO competencies_text
    FROM company_competencies cc
    JOIN competencies c ON c.id = cc.competency_id
    WHERE cc.company_id = NEW.id;

    -- Buduj rozszerzony wektor wyszukiwania
    NEW.search_vector :=
        setweight(to_tsvector('simple', COALESCE(NEW.name, '')), 'A') ||
        setweight(to_tsvector('simple', COALESCE(NEW.description_short, '')), 'B') ||
        setweight(to_tsvector('simple', COALESCE(NEW.description_full, '')), 'C') ||
        setweight(to_tsvector('simple', COALESCE(services_text, '')), 'B') ||
        setweight(to_tsvector('simple', COALESCE(competencies_text, '')), 'B') ||
        setweight(to_tsvector('simple', COALESCE(NEW.address_city, '')), 'D');

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 5. Zastąp stary trigger nowym (jeśli istnieje)
DROP TRIGGER IF EXISTS tsvector_update ON companies;
CREATE TRIGGER tsvector_update BEFORE INSERT OR UPDATE
ON companies FOR EACH ROW EXECUTE FUNCTION companies_search_trigger_full();

-- 6. Funkcja do przebudowy search_vector dla istniejących firm
CREATE OR REPLACE FUNCTION rebuild_search_vectors() RETURNS void AS $$
DECLARE
    company_rec RECORD;
BEGIN
    FOR company_rec IN SELECT id FROM companies LOOP
        -- Trigger zostanie wywołany przez UPDATE
        UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = company_rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

-- 7. Przebuduj search vectory dla wszystkich firm
SELECT rebuild_search_vectors();

-- 8. Dodaj trigger na company_services (gdy dodajemy usługę, przebuduj wektor)
CREATE OR REPLACE FUNCTION update_company_search_on_service_change() RETURNS trigger AS $$
BEGIN
    IF TG_OP = 'DELETE' THEN
        UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = OLD.company_id;
        RETURN OLD;
    ELSE
        UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = NEW.company_id;
        RETURN NEW;
    END IF;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trigger_service_search_update ON company_services;
CREATE TRIGGER trigger_service_search_update
AFTER INSERT OR UPDATE OR DELETE ON company_services
FOR EACH ROW EXECUTE FUNCTION update_company_search_on_service_change();

-- 9. Dodaj trigger na company_competencies
DROP TRIGGER IF EXISTS trigger_competency_search_update ON company_competencies;
CREATE TRIGGER trigger_competency_search_update
AFTER INSERT OR UPDATE OR DELETE ON company_competencies
FOR EACH ROW EXECUTE FUNCTION update_company_search_on_service_change();

-- 10. Podsumowanie
DO $$
BEGIN
    RAISE NOTICE '=== Migracja zakończona pomyślnie ===';
    RAISE NOTICE 'Dodano: pg_trgm, indeksy trigram, rozszerzony search trigger';
    RAISE NOTICE 'Przebudowano search vectors dla wszystkich firm';
END $$;
