-- Mail plugin initial migration: creates all mail tables

CREATE TABLE IF NOT EXISTS mail_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    email_address VARCHAR(255) NOT NULL,
    display_name VARCHAR(255) NOT NULL DEFAULT '',
    imap_host VARCHAR(255) NOT NULL,
    imap_port INTEGER NOT NULL DEFAULT 993,
    imap_ssl BOOLEAN NOT NULL DEFAULT TRUE,
    smtp_host VARCHAR(255) NOT NULL,
    smtp_port INTEGER NOT NULL DEFAULT 587,
    smtp_tls BOOLEAN NOT NULL DEFAULT TRUE,
    username VARCHAR(255) NOT NULL,
    encrypted_password TEXT NOT NULL,
    is_shared BOOLEAN NOT NULL DEFAULT FALSE,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_accounts_user ON mail_accounts(user_id);
CREATE INDEX IF NOT EXISTS ix_mail_accounts_tenant ON mail_accounts(tenant_id);

CREATE TABLE IF NOT EXISTS mail_folders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    imap_name VARCHAR(255) NOT NULL,
    parent_id UUID REFERENCES mail_folders(id) ON DELETE CASCADE,
    is_standard BOOLEAN NOT NULL DEFAULT FALSE,
    unread_count INTEGER NOT NULL DEFAULT 0,
    total_count INTEGER NOT NULL DEFAULT 0,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_folders_account ON mail_folders(account_id);
CREATE INDEX IF NOT EXISTS ix_mail_folders_tenant ON mail_folders(tenant_id);

CREATE TABLE IF NOT EXISTS mails (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    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 VARCHAR(512) NOT NULL,
    thread_id VARCHAR(512) NOT NULL DEFAULT '',
    in_reply_to VARCHAR(512),
    references_header TEXT,
    subject VARCHAR(512) NOT NULL DEFAULT '',
    from_address VARCHAR(255) NOT NULL,
    to_addresses TEXT NOT NULL DEFAULT '',
    cc_addresses TEXT NOT NULL DEFAULT '',
    bcc_addresses TEXT NOT NULL DEFAULT '',
    body_text TEXT NOT NULL DEFAULT '',
    body_html TEXT NOT NULL DEFAULT '',
    body_html_sanitized TEXT NOT NULL DEFAULT '',
    is_seen BOOLEAN NOT NULL DEFAULT FALSE,
    is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
    is_draft BOOLEAN NOT NULL DEFAULT FALSE,
    is_answered BOOLEAN NOT NULL DEFAULT FALSE,
    is_forwarded BOOLEAN NOT NULL DEFAULT FALSE,
    has_attachments BOOLEAN NOT NULL DEFAULT FALSE,
    size_bytes INTEGER NOT NULL DEFAULT 0,
    received_at TIMESTAMPTZ,
    sent_at TIMESTAMPTZ,
    contact_id UUID,
    company_id UUID,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mails_folder ON mails(folder_id);
CREATE INDEX IF NOT EXISTS ix_mails_account ON mails(account_id);
CREATE INDEX IF NOT EXISTS ix_mails_tenant ON mails(tenant_id);
CREATE INDEX IF NOT EXISTS ix_mails_thread ON mails(thread_id);

CREATE TABLE IF NOT EXISTS mail_attachments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
    filename VARCHAR(255) NOT NULL,
    mime_type VARCHAR(255) NOT NULL DEFAULT 'application/octet-stream',
    size_bytes INTEGER NOT NULL DEFAULT 0,
    storage_path VARCHAR(1024) NOT NULL,
    dms_file_id UUID,
    content_id VARCHAR(255),
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_attachments_mail ON mail_attachments(mail_id);
CREATE INDEX IF NOT EXISTS ix_mail_attachments_tenant ON mail_attachments(tenant_id);

CREATE TABLE IF NOT EXISTS mail_labels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) NOT NULL,
    color VARCHAR(20) NOT NULL DEFAULT '#808080',
    user_id UUID NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_labels_tenant ON mail_labels(tenant_id);

CREATE TABLE IF NOT EXISTS mail_label_assignments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
    label_id UUID NOT NULL REFERENCES mail_labels(id) ON DELETE CASCADE,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_mail_label_assignment UNIQUE (mail_id, label_id)
);
CREATE INDEX IF NOT EXISTS ix_mail_label_assign_mail ON mail_label_assignments(mail_id);
CREATE INDEX IF NOT EXISTS ix_mail_label_assign_label ON mail_label_assignments(label_id);

CREATE TABLE IF NOT EXISTS mail_rules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID REFERENCES mail_accounts(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    priority INTEGER NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    conditions TEXT NOT NULL DEFAULT '{}',
    actions TEXT NOT NULL DEFAULT '{}',
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_rules_account ON mail_rules(account_id);
CREATE INDEX IF NOT EXISTS ix_mail_rules_tenant ON mail_rules(tenant_id);

CREATE TABLE IF NOT EXISTS mail_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    subject VARCHAR(512) NOT NULL DEFAULT '',
    body_html TEXT NOT NULL DEFAULT '',
    user_id UUID NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_templates_tenant ON mail_templates(tenant_id);

CREATE TABLE IF NOT EXISTS mail_signatures (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    account_id UUID REFERENCES mail_accounts(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    body_html TEXT NOT NULL DEFAULT '',
    is_default BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mail_signatures_tenant ON mail_signatures(tenant_id);

CREATE TABLE IF NOT EXISTS vacation_sent_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    sender_address VARCHAR(255) NOT NULL,
    sent_at TIMESTAMPTZ NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_vacation_sent_log_account ON vacation_sent_log(account_id);
CREATE INDEX IF NOT EXISTS ix_vacation_sent_log_tenant ON vacation_sent_log(tenant_id);

CREATE TABLE IF NOT EXISTS mail_seen_by (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    mail_id UUID NOT NULL REFERENCES mails(id) ON DELETE CASCADE,
    user_id UUID NOT NULL,
    seen_at TIMESTAMPTZ NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_mail_seen_by UNIQUE (mail_id, user_id)
);
CREATE INDEX IF NOT EXISTS ix_mail_seen_by_mail ON mail_seen_by(mail_id);

CREATE TABLE IF NOT EXISTS mail_account_delegates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    delegate_user_id UUID NOT NULL,
    access_level VARCHAR(20) NOT NULL DEFAULT 'read',
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_mail_delegate UNIQUE (account_id, delegate_user_id)
);
CREATE INDEX IF NOT EXISTS ix_mail_delegates_account ON mail_account_delegates(account_id);

CREATE TABLE IF NOT EXISTS mail_account_send_permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL REFERENCES mail_accounts(id) ON DELETE CASCADE,
    user_id UUID NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_mail_send_perm UNIQUE (account_id, user_id)
);
CREATE INDEX IF NOT EXISTS ix_mail_send_perms_account ON mail_account_send_permissions(account_id);

CREATE TABLE IF NOT EXISTS pgp_keys (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    key_id VARCHAR(255) NOT NULL,
    encrypted_private_key TEXT NOT NULL,
    public_key_armored TEXT NOT NULL,
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_pgp_keys_user ON pgp_keys(user_id);

CREATE TABLE IF NOT EXISTS contact_pgp_keys (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    contact_id UUID NOT NULL,
    public_key_armored TEXT NOT NULL,
    key_id VARCHAR(255) NOT NULL DEFAULT '',
    tenant_id UUID NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_contact_pgp_keys_contact ON contact_pgp_keys(contact_id);
