-- ALSO Cloud Billing foundation
-- Import jobs, import lines queue, and mapping tables

CREATE TABLE IF NOT EXISTS also_import_jobs (
    id SERIAL PRIMARY KEY,
    source_type VARCHAR(32) NOT NULL CHECK (source_type IN ('api', 'xml', 'json_export', 'xml_export', 'csv')),
    source_label VARCHAR(255),
    status VARCHAR(32) NOT NULL DEFAULT 'new',
    file_name VARCHAR(512),
    import_version VARCHAR(128),
    imported_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
    imported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    started_at TIMESTAMP,
    finished_at TIMESTAMP,
    raw_payload_json JSONB NOT NULL DEFAULT '{}'::jsonb,
    log_json JSONB NOT NULL DEFAULT '[]'::jsonb,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_also_import_jobs_status ON also_import_jobs(status);
CREATE INDEX IF NOT EXISTS idx_also_import_jobs_imported_at ON also_import_jobs(imported_at DESC);


CREATE TABLE IF NOT EXISTS also_import_lines (
    id BIGSERIAL PRIMARY KEY,
    import_job_id INTEGER NOT NULL REFERENCES also_import_jobs(id) ON DELETE CASCADE,
    line_no INTEGER,
    queue_status VARCHAR(32) NOT NULL DEFAULT 'new' CHECK (queue_status IN (
        'new',
        'matching_products',
        'matching_customers',
        'ready_for_approval',
        'approved',
        'invoiced',
        'error'
    )),
    source_line_ref VARCHAR(255),
    line_hash VARCHAR(128) NOT NULL,

    also_company_id VARCHAR(128),
    company VARCHAR(255),
    customer_id VARCHAR(128),
    account_id VARCHAR(128),
    vat VARCHAR(64),

    material_number VARCHAR(128),
    product_name VARCHAR(512),
    vendor VARCHAR(255),

    cost_amount NUMERIC(14, 4),
    sales_price NUMERIC(14, 4),
    unit_price NUMERIC(14, 4),
    total_price NUMERIC(14, 4),
    currency VARCHAR(16),

    billing_start DATE,
    charge_interval VARCHAR(64),
    billing_interval VARCHAR(64),
    billable_parameters NUMERIC(14, 4),

    matched_customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
    matched_product_id INTEGER REFERENCES products(id) ON DELETE SET NULL,
    validation_errors_json JSONB NOT NULL DEFAULT '[]'::jsonb,
    raw_line_json JSONB NOT NULL DEFAULT '{}'::jsonb,

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT uniq_also_import_line_hash UNIQUE (import_job_id, line_hash)
);

CREATE INDEX IF NOT EXISTS idx_also_import_lines_job ON also_import_lines(import_job_id);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_status ON also_import_lines(queue_status);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_material_vendor ON also_import_lines(material_number, vendor);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_customer_keys ON also_import_lines(also_company_id, customer_id, vat);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_unmatched_customer ON also_import_lines(matched_customer_id) WHERE matched_customer_id IS NULL;
CREATE INDEX IF NOT EXISTS idx_also_import_lines_unmatched_product ON also_import_lines(matched_product_id) WHERE matched_product_id IS NULL;


CREATE TABLE IF NOT EXISTS also_company_mapping (
    id SERIAL PRIMARY KEY,
    also_company_id VARCHAR(128) NOT NULL UNIQUE,
    also_customer_id VARCHAR(128),
    customer_id INTEGER NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
    match_confidence NUMERIC(5, 2),
    notes TEXT,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_also_company_mapping_customer ON also_company_mapping(customer_id);


CREATE TABLE IF NOT EXISTS also_product_mapping (
    id SERIAL PRIMARY KEY,
    material_number VARCHAR(128) NOT NULL,
    vendor VARCHAR(255) NOT NULL,
    hub_product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
    product_name_snapshot VARCHAR(512),
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uniq_also_product_mapping UNIQUE (material_number, vendor)
);

CREATE INDEX IF NOT EXISTS idx_also_product_mapping_product ON also_product_mapping(hub_product_id);
