-- Backfill invoice error finder schema on environments where module migrations
-- were not executed through the main production migration flow.

CREATE TABLE IF NOT EXISTS invoice_error_finder_import_runs (
    id SERIAL PRIMARY KEY,
    source_type VARCHAR(50) NOT NULL,
    started_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    completed_at TIMESTAMP,
    status VARCHAR(20) NOT NULL DEFAULT 'running' CHECK (status IN ('running', 'success', 'partial', 'failed')),
    records_imported INTEGER NOT NULL DEFAULT 0,
    records_failed INTEGER NOT NULL DEFAULT 0,
    error_message TEXT,
    triggered_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
    is_scheduled BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_ief_import_runs_source
    ON invoice_error_finder_import_runs(source_type, started_at DESC);

CREATE TABLE IF NOT EXISTS invoice_error_finder_economic_invoices (
    id SERIAL PRIMARY KEY,
    import_run_id INTEGER NOT NULL REFERENCES invoice_error_finder_import_runs(id) ON DELETE CASCADE,
    source_invoice_number VARCHAR(80),
    source_type VARCHAR(30) NOT NULL DEFAULT 'booked',
    customer_number INTEGER,
    customer_name VARCHAR(255),
    invoice_date DATE,
    due_date DATE,
    currency VARCHAR(10) DEFAULT 'DKK',
    net_amount NUMERIC(14,2),
    vat_amount NUMERIC(14,2),
    total_amount NUMERIC(14,2),
    source_raw JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_ief_economic_invoice_import UNIQUE (import_run_id, source_invoice_number, source_type)
);

CREATE INDEX IF NOT EXISTS idx_ief_economic_invoices_run
    ON invoice_error_finder_economic_invoices(import_run_id);
CREATE INDEX IF NOT EXISTS idx_ief_economic_invoices_customer
    ON invoice_error_finder_economic_invoices(customer_number);
CREATE INDEX IF NOT EXISTS idx_ief_economic_invoices_date
    ON invoice_error_finder_economic_invoices(invoice_date);

CREATE TABLE IF NOT EXISTS invoice_error_finder_economic_invoice_lines (
    id SERIAL PRIMARY KEY,
    invoice_id INTEGER NOT NULL REFERENCES invoice_error_finder_economic_invoices(id) ON DELETE CASCADE,
    line_number INTEGER,
    product_number VARCHAR(100),
    product_name VARCHAR(500),
    description TEXT,
    quantity NUMERIC(14,4) NOT NULL DEFAULT 0,
    unit_price NUMERIC(14,4) NOT NULL DEFAULT 0,
    line_net_amount NUMERIC(14,2) NOT NULL DEFAULT 0,
    discount_percentage NUMERIC(5,2) DEFAULT 0,
    source_raw JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_ief_economic_lines_invoice
    ON invoice_error_finder_economic_invoice_lines(invoice_id);
CREATE INDEX IF NOT EXISTS idx_ief_economic_lines_product
    ON invoice_error_finder_economic_invoice_lines(product_number);

CREATE TABLE IF NOT EXISTS invoice_error_finder_simply_sales_orders (
    id SERIAL PRIMARY KEY,
    import_run_id INTEGER NOT NULL REFERENCES invoice_error_finder_import_runs(id) ON DELETE CASCADE,
    source_record_id VARCHAR(80) NOT NULL,
    salesorder_no VARCHAR(80),
    account_id VARCHAR(80),
    customer_name VARCHAR(255),
    customer_cvr VARCHAR(32),
    subject TEXT,
    status VARCHAR(50),
    product_number VARCHAR(100),
    product_name VARCHAR(500),
    quantity NUMERIC(14,4) NOT NULL DEFAULT 0,
    unit_price NUMERIC(14,4) NOT NULL DEFAULT 0,
    total_amount NUMERIC(14,2) NOT NULL DEFAULT 0,
    start_period DATE,
    end_period DATE,
    source_raw JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_ief_simply_order_import UNIQUE (source_record_id)
);

CREATE INDEX IF NOT EXISTS idx_ief_simply_orders_run
    ON invoice_error_finder_simply_sales_orders(import_run_id);
CREATE INDEX IF NOT EXISTS idx_ief_simply_orders_account
    ON invoice_error_finder_simply_sales_orders(account_id);
CREATE INDEX IF NOT EXISTS idx_ief_simply_orders_status
    ON invoice_error_finder_simply_sales_orders(status);

CREATE TABLE IF NOT EXISTS invoice_error_finder_issues (
    id SERIAL PRIMARY KEY,
    issue_type VARCHAR(50) NOT NULL CHECK (issue_type IN (
        'missing_line',
        'open_order_not_invoiced',
        'quantity_drop',
        'price_change',
        'new_item_never_invoiced'
    )),
    status VARCHAR(30) NOT NULL DEFAULT 'open' CHECK (status IN (
        'open',
        'investigating',
        'approved_change',
        'error_found',
        'ready_to_invoice',
        'invoiced',
        'ignored'
    )),
    customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
    customer_name VARCHAR(255),
    subscription_id INTEGER REFERENCES sag_subscriptions(id) ON DELETE SET NULL,
    simply_order_id INTEGER REFERENCES invoice_error_finder_simply_sales_orders(id) ON DELETE SET NULL,
    simply_source_record_id VARCHAR(80),
    sag_id INTEGER REFERENCES sag_sager(id) ON DELETE SET NULL,
    product_number VARCHAR(100),
    product_name VARCHAR(500),
    reference_period_start DATE,
    reference_period_end DATE,
    expected_quantity NUMERIC(14,4),
    actual_quantity NUMERIC(14,4),
    expected_price NUMERIC(14,4),
    actual_price NUMERIC(14,4),
    last_invoice_number VARCHAR(80),
    last_invoice_date DATE,
    sales_order_number VARCHAR(80),
    amount_impact NUMERIC(14,2),
    currency VARCHAR(10) DEFAULT 'DKK',
    assigned_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
    notes TEXT,
    ignored_until DATE,
    resolved_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_ief_issues_type
    ON invoice_error_finder_issues(issue_type);
CREATE INDEX IF NOT EXISTS idx_ief_issues_status
    ON invoice_error_finder_issues(status);
CREATE INDEX IF NOT EXISTS idx_ief_issues_customer
    ON invoice_error_finder_issues(customer_id);
CREATE INDEX IF NOT EXISTS idx_ief_issues_period
    ON invoice_error_finder_issues(reference_period_start, reference_period_end);
CREATE INDEX IF NOT EXISTS idx_ief_issues_assigned
    ON invoice_error_finder_issues(assigned_user_id)
    WHERE assigned_user_id IS NULL;

CREATE OR REPLACE FUNCTION update_ief_issues_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trigger_ief_issues_updated_at ON invoice_error_finder_issues;
CREATE TRIGGER trigger_ief_issues_updated_at
BEFORE UPDATE ON invoice_error_finder_issues
FOR EACH ROW
EXECUTE FUNCTION update_ief_issues_updated_at();
