CREATE TABLE mail_accounts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name TEXT NOT NULL DEFAULT '',
    email TEXT NOT NULL,
    provider TEXT NOT NULL DEFAULT 'imap',
    imap_host TEXT NOT NULL DEFAULT '',
    imap_port INT NOT NULL DEFAULT 993,
    imap_tls BOOLEAN NOT NULL DEFAULT true,
    smtp_host TEXT NOT NULL DEFAULT '',
    smtp_port INT NOT NULL DEFAULT 587,
    smtp_tls BOOLEAN NOT NULL DEFAULT true,
    credentials BYTEA,
    last_sync_at TIMESTAMPTZ,
    sync_state JSONB NOT NULL DEFAULT '{}',
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_mail_accounts_user ON mail_accounts(user_id);

CREATE TABLE mail_identities (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    email TEXT NOT NULL,
    name TEXT NOT NULL DEFAULT '',
    is_default BOOLEAN NOT NULL DEFAULT false,
    signature_html TEXT NOT NULL DEFAULT '',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_mail_identities_account ON mail_identities(account_id);

CREATE TABLE mail_folders (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    remote_name TEXT NOT NULL,
    folder_type TEXT NOT NULL DEFAULT 'custom',
    uidvalidity BIGINT NOT NULL DEFAULT 0,
    highest_modseq BIGINT NOT NULL DEFAULT 0,
    message_count INT NOT NULL DEFAULT 0,
    unread_count INT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(account_id, remote_name)
);

CREATE INDEX idx_mail_folders_account ON mail_folders(account_id);

CREATE TABLE messages (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    folder_id UUID NOT NULL REFERENCES mail_folders(id) ON DELETE CASCADE,
    message_id TEXT NOT NULL DEFAULT '',
    thread_id UUID,
    uid BIGINT NOT NULL DEFAULT 0,
    subject TEXT NOT NULL DEFAULT '',
    from_addr JSONB NOT NULL DEFAULT '[]',
    to_addrs JSONB NOT NULL DEFAULT '[]',
    cc_addrs JSONB NOT NULL DEFAULT '[]',
    bcc_addrs JSONB NOT NULL DEFAULT '[]',
    reply_to JSONB NOT NULL DEFAULT '[]',
    date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    snippet TEXT NOT NULL DEFAULT '',
    body_text TEXT NOT NULL DEFAULT '',
    body_html TEXT NOT NULL DEFAULT '',
    flags TEXT[] NOT NULL DEFAULT '{}',
    labels TEXT[] NOT NULL DEFAULT '{}',
    has_attachments BOOLEAN NOT NULL DEFAULT false,
    raw_size INT NOT NULL DEFAULT 0,
    in_reply_to TEXT NOT NULL DEFAULT '',
    references_header TEXT[] NOT NULL DEFAULT '{}',
    search_vector tsvector,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_messages_account_folder ON messages(account_id, folder_id);
CREATE INDEX idx_messages_thread ON messages(thread_id);
CREATE INDEX idx_messages_date ON messages(date DESC);
CREATE INDEX idx_messages_message_id ON messages(message_id);
CREATE INDEX idx_messages_flags ON messages USING GIN(flags);
CREATE INDEX idx_messages_labels ON messages USING GIN(labels);
CREATE INDEX idx_messages_search ON messages USING GIN(search_vector);
CREATE UNIQUE INDEX idx_messages_uid ON messages(folder_id, uid);

-- Auto-update search_vector on insert/update
CREATE FUNCTION messages_search_vector_update() RETURNS trigger AS $$
BEGIN
    NEW.search_vector := 
        setweight(to_tsvector('simple', COALESCE(NEW.subject, '')), 'A') ||
        setweight(to_tsvector('simple', COALESCE(NEW.from_addr::text, '')), 'B') ||
        setweight(to_tsvector('simple', COALESCE(NEW.to_addrs::text, '')), 'B') ||
        setweight(to_tsvector('simple', COALESCE(NEW.body_text, '')), 'C');
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER messages_search_trigger
    BEFORE INSERT OR UPDATE OF subject, from_addr, to_addrs, body_text
    ON messages
    FOR EACH ROW
    EXECUTE FUNCTION messages_search_vector_update();

CREATE TABLE attachments (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
    filename TEXT NOT NULL DEFAULT '',
    content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
    size BIGINT NOT NULL DEFAULT 0,
    s3_bucket TEXT NOT NULL DEFAULT 'mail-attachments',
    s3_key TEXT NOT NULL DEFAULT '',
    content_id TEXT NOT NULL DEFAULT '',
    is_inline BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_attachments_message ON attachments(message_id);

CREATE TABLE mail_rules (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    account_id UUID REFERENCES mail_accounts(id) ON DELETE CASCADE,
    name TEXT NOT NULL DEFAULT '',
    priority INT NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT true,
    conditions JSONB NOT NULL DEFAULT '[]',
    actions JSONB NOT NULL DEFAULT '[]',
    llm_config JSONB,
    match_count BIGINT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_mail_rules_user ON mail_rules(user_id);
CREATE INDEX idx_mail_rules_priority ON mail_rules(user_id, priority);

CREATE TABLE webhook_templates (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    url TEXT NOT NULL,
    method TEXT NOT NULL DEFAULT 'POST',
    headers JSONB NOT NULL DEFAULT '{}',
    body_template TEXT NOT NULL DEFAULT '',
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_webhook_templates_user ON webhook_templates(user_id);

CREATE TABLE webhook_logs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    template_id UUID NOT NULL REFERENCES webhook_templates(id) ON DELETE CASCADE,
    message_id UUID REFERENCES messages(id) ON DELETE SET NULL,
    status_code INT,
    response_body TEXT NOT NULL DEFAULT '',
    error TEXT NOT NULL DEFAULT '',
    duration_ms INT NOT NULL DEFAULT 0,
    executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_webhook_logs_template ON webhook_logs(template_id);
CREATE INDEX idx_webhook_logs_executed ON webhook_logs(executed_at DESC);

CREATE TABLE outbox (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    identity_id UUID REFERENCES mail_identities(id) ON DELETE SET NULL,
    to_addrs JSONB NOT NULL DEFAULT '[]',
    cc_addrs JSONB NOT NULL DEFAULT '[]',
    bcc_addrs JSONB NOT NULL DEFAULT '[]',
    subject TEXT NOT NULL DEFAULT '',
    body_text TEXT NOT NULL DEFAULT '',
    body_html TEXT NOT NULL DEFAULT '',
    in_reply_to TEXT NOT NULL DEFAULT '',
    references_header TEXT[] NOT NULL DEFAULT '{}',
    attachments JSONB NOT NULL DEFAULT '[]',
    scheduled_at TIMESTAMPTZ,
    sent_at TIMESTAMPTZ,
    status TEXT NOT NULL DEFAULT 'draft',
    error TEXT NOT NULL DEFAULT '',
    retry_count INT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_outbox_user ON outbox(user_id);
CREATE INDEX idx_outbox_status ON outbox(status) WHERE status IN ('queued', 'sending');
CREATE INDEX idx_outbox_scheduled ON outbox(scheduled_at) WHERE scheduled_at IS NOT NULL AND status = 'queued';
