CREATE TABLE crash_signatures (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    repository_id   UUID NOT NULL REFERENCES repositories(id),
    fingerprint     TEXT NOT NULL,
    sample_trace    TEXT,
    first_seen_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_seen_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    occurrence_count INT NOT NULL DEFAULT 1,
    UNIQUE (repository_id, fingerprint)
);

CREATE INDEX idx_crash_signatures_repo ON crash_signatures (repository_id);
CREATE INDEX idx_crash_signatures_last_seen ON crash_signatures (last_seen_at DESC);

CREATE TABLE crash_groups (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    crash_signature_id  UUID NOT NULL UNIQUE REFERENCES crash_signatures(id),
    repository_id       UUID NOT NULL REFERENCES repositories(id),
    title               TEXT NOT NULL,
    status              TEXT NOT NULL DEFAULT 'open',
    forgejo_issue_id    INT,
    forgejo_issue_url   TEXT,
    first_seen_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_seen_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at          TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_crash_groups_repo ON crash_groups (repository_id);
CREATE INDEX idx_crash_groups_status ON crash_groups (status);
CREATE INDEX idx_crash_groups_sig ON crash_groups (crash_signature_id);

ALTER TABLE artifacts ADD COLUMN signature_id UUID REFERENCES crash_signatures(id);
ALTER TABLE artifacts ADD COLUMN fingerprint TEXT;

CREATE INDEX idx_artifacts_signature ON artifacts (signature_id);
CREATE INDEX idx_artifacts_fingerprint ON artifacts (fingerprint);

-- Full-text search support
ALTER TABLE artifacts ADD COLUMN search_vector tsvector;

CREATE INDEX idx_artifacts_search ON artifacts USING GIN (search_vector);

CREATE OR REPLACE FUNCTION artifacts_search_update() RETURNS trigger AS $$
BEGIN
    NEW.search_vector :=
        setweight(to_tsvector('english', COALESCE(NEW.crash_message, '')), 'A') ||
        setweight(to_tsvector('english', COALESCE(NEW.stack_trace, '')), 'B') ||
        setweight(to_tsvector('english', COALESCE(NEW.type, '')), 'C');
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER artifacts_search_trigger
    BEFORE INSERT OR UPDATE ON artifacts
    FOR EACH ROW EXECUTE FUNCTION artifacts_search_update();
