-- Configuration tables schema

-- Stock threshold configurations
CREATE TABLE stock_thresholds (
    id INTEGER NOT NULL,
    category_id BIGINT,  -- NULL means default/global threshold
    vendor VARCHAR(100), -- NULL means applies to all vendors
    critical_days INTEGER NOT NULL DEFAULT 7,
    reorder_days INTEGER NOT NULL DEFAULT 14,
    overstock_days INTEGER NOT NULL DEFAULT 90,
    low_stock_threshold INTEGER NOT NULL DEFAULT 5,
    min_reorder_quantity INTEGER NOT NULL DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES categories(cat_id) ON DELETE CASCADE,
    UNIQUE (category_id, vendor)
);

CREATE INDEX idx_st_metrics ON stock_thresholds(category_id, vendor);

-- Lead time threshold configurations
CREATE TABLE lead_time_thresholds (
    id INTEGER NOT NULL,
    category_id BIGINT,  -- NULL means default/global threshold
    vendor VARCHAR(100), -- NULL means applies to all vendors
    target_days INTEGER NOT NULL DEFAULT 14,
    warning_days INTEGER NOT NULL DEFAULT 21,
    critical_days INTEGER NOT NULL DEFAULT 30,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES categories(cat_id) ON DELETE CASCADE,
    UNIQUE (category_id, vendor)
);

-- Sales velocity window configurations
CREATE TABLE sales_velocity_config (
    id INTEGER NOT NULL,
    category_id BIGINT,  -- NULL means default/global threshold
    vendor VARCHAR(100), -- NULL means applies to all vendors
    daily_window_days INTEGER NOT NULL DEFAULT 30,
    weekly_window_days INTEGER NOT NULL DEFAULT 7,
    monthly_window_days INTEGER NOT NULL DEFAULT 90,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES categories(cat_id) ON DELETE CASCADE,
    UNIQUE (category_id, vendor)
);

CREATE INDEX idx_sv_metrics ON sales_velocity_config(category_id, vendor);

-- ABC Classification configurations
CREATE TABLE abc_classification_config (
    id INTEGER NOT NULL PRIMARY KEY,
    a_threshold DECIMAL(5,2) NOT NULL DEFAULT 20.0,
    b_threshold DECIMAL(5,2) NOT NULL DEFAULT 50.0,
    classification_period_days INTEGER NOT NULL DEFAULT 90,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Safety stock configurations
CREATE TABLE safety_stock_config (
    id INTEGER NOT NULL,
    category_id BIGINT,  -- NULL means default/global threshold
    vendor VARCHAR(100), -- NULL means applies to all vendors
    coverage_days INTEGER NOT NULL DEFAULT 14,
    service_level DECIMAL(5,2) NOT NULL DEFAULT 95.0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES categories(cat_id) ON DELETE CASCADE,
    UNIQUE (category_id, vendor)
);

CREATE INDEX idx_ss_metrics ON safety_stock_config(category_id, vendor);

-- Turnover rate configurations
CREATE TABLE turnover_config (
    id INTEGER NOT NULL,
    category_id BIGINT,  -- NULL means default/global threshold
    vendor VARCHAR(100), -- NULL means applies to all vendors
    calculation_period_days INTEGER NOT NULL DEFAULT 30,
    target_rate DECIMAL(10,2) NOT NULL DEFAULT 1.0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (category_id) REFERENCES categories(cat_id) ON DELETE CASCADE,
    UNIQUE (category_id, vendor)
);

-- Create table for sales seasonality factors
CREATE TABLE sales_seasonality (
    month INTEGER NOT NULL,
    seasonality_factor DECIMAL(5,3) DEFAULT 0,
    last_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (month),
    CONSTRAINT month_range CHECK (month BETWEEN 1 AND 12),
    CONSTRAINT seasonality_range CHECK (seasonality_factor BETWEEN -1.0 AND 1.0)
);

-- Insert default global thresholds
INSERT INTO stock_thresholds (id, category_id, vendor, critical_days, reorder_days, overstock_days)
VALUES (1, NULL, NULL, 7, 14, 90)
ON CONFLICT (id) DO UPDATE SET
    critical_days = EXCLUDED.critical_days,
    reorder_days = EXCLUDED.reorder_days,
    overstock_days = EXCLUDED.overstock_days;

INSERT INTO lead_time_thresholds (id, category_id, vendor, target_days, warning_days, critical_days)
VALUES (1, NULL, NULL, 14, 21, 30)
ON CONFLICT (id) DO UPDATE SET
    target_days = EXCLUDED.target_days,
    warning_days = EXCLUDED.warning_days,
    critical_days = EXCLUDED.critical_days;

INSERT INTO sales_velocity_config (id, category_id, vendor, daily_window_days, weekly_window_days, monthly_window_days)
VALUES (1, NULL, NULL, 30, 7, 90)
ON CONFLICT (id) DO UPDATE SET
    daily_window_days = EXCLUDED.daily_window_days,
    weekly_window_days = EXCLUDED.weekly_window_days,
    monthly_window_days = EXCLUDED.monthly_window_days;

INSERT INTO abc_classification_config (id, a_threshold, b_threshold, classification_period_days)
VALUES (1, 20.0, 50.0, 90)
ON CONFLICT (id) DO UPDATE SET
    a_threshold = EXCLUDED.a_threshold,
    b_threshold = EXCLUDED.b_threshold,
    classification_period_days = EXCLUDED.classification_period_days;

INSERT INTO safety_stock_config (id, category_id, vendor, coverage_days, service_level)
VALUES (1, NULL, NULL, 14, 95.0)
ON CONFLICT (id) DO UPDATE SET
    coverage_days = EXCLUDED.coverage_days,
    service_level = EXCLUDED.service_level;

INSERT INTO turnover_config (id, category_id, vendor, calculation_period_days, target_rate)
VALUES (1, NULL, NULL, 30, 1.0)
ON CONFLICT (id) DO UPDATE SET
    calculation_period_days = EXCLUDED.calculation_period_days,
    target_rate = EXCLUDED.target_rate;

-- Insert default seasonality factors (neutral)
INSERT INTO sales_seasonality (month, seasonality_factor)
VALUES 
    (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0),
    (7, 0), (8, 0), (9, 0), (10, 0), (11, 0), (12, 0)
ON CONFLICT (month) DO UPDATE SET
    last_updated = CURRENT_TIMESTAMP;

-- View to show thresholds with category names
CREATE OR REPLACE VIEW stock_thresholds_view AS
SELECT 
    st.*,
    c.name as category_name,
    CASE 
        WHEN st.category_id IS NULL AND st.vendor IS NULL THEN 'Global Default'
        WHEN st.category_id IS NULL THEN 'Vendor: ' || st.vendor
        WHEN st.vendor IS NULL THEN 'Category: ' || c.name
        ELSE 'Category: ' || c.name || ' / Vendor: ' || st.vendor
    END as threshold_scope
FROM 
    stock_thresholds st
LEFT JOIN 
    categories c ON st.category_id = c.cat_id
ORDER BY 
    CASE 
        WHEN st.category_id IS NULL AND st.vendor IS NULL THEN 1
        WHEN st.category_id IS NULL THEN 2
        WHEN st.vendor IS NULL THEN 3
        ELSE 4
    END,
    c.name,
    st.vendor;

-- History and status tables
CREATE TABLE IF NOT EXISTS calculate_history (
    id BIGSERIAL PRIMARY KEY,
    start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    end_time TIMESTAMP NULL,
    duration_seconds INTEGER,
    duration_minutes DECIMAL(10,2) GENERATED ALWAYS AS (duration_seconds::decimal / 60.0) STORED,
    total_products INTEGER DEFAULT 0,
    total_orders INTEGER DEFAULT 0,
    total_purchase_orders INTEGER DEFAULT 0,
    processed_products INTEGER DEFAULT 0,
    processed_orders INTEGER DEFAULT 0,
    processed_purchase_orders INTEGER DEFAULT 0,
    status calculation_status DEFAULT 'running',
    error_message TEXT,
    additional_info JSONB
);

CREATE TABLE IF NOT EXISTS calculate_status (
    module_name module_name PRIMARY KEY,
    last_calculation_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS sync_status (
    table_name VARCHAR(50) PRIMARY KEY,
    last_sync_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    last_sync_id BIGINT
);

CREATE TABLE IF NOT EXISTS import_history (
    id BIGSERIAL PRIMARY KEY,
    table_name VARCHAR(50) NOT NULL,
    start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    end_time TIMESTAMP NULL,
    duration_seconds INTEGER,
    duration_minutes DECIMAL(10,2) GENERATED ALWAYS AS (duration_seconds::decimal / 60.0) STORED,
    records_added INTEGER DEFAULT 0,
    records_updated INTEGER DEFAULT 0,
    is_incremental BOOLEAN DEFAULT FALSE,
    status calculation_status DEFAULT 'running',
    error_message TEXT,
    additional_info JSONB
);

-- Create all indexes after tables are fully created
CREATE INDEX IF NOT EXISTS idx_last_calc ON calculate_status(last_calculation_timestamp);
CREATE INDEX IF NOT EXISTS idx_last_sync ON sync_status(last_sync_timestamp);
CREATE INDEX IF NOT EXISTS idx_table_time ON import_history(table_name, start_time); 